xref: /onnv-gate/usr/src/lib/efcode/engine/forth.c (revision 3956:ea75466401e7)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*3956Sgovinda  * Common Development and Distribution License (the "License").
6*3956Sgovinda  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*3956Sgovinda  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*3956Sgovinda  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <stdio.h>
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <string.h>
310Sstevel@tonic-gate #include <stdarg.h>
320Sstevel@tonic-gate #include <ctype.h>
330Sstevel@tonic-gate 
340Sstevel@tonic-gate #include <fcode/private.h>
350Sstevel@tonic-gate #include <fcode/log.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate void (*semi_ptr)(fcode_env_t *env) = do_semi;
380Sstevel@tonic-gate void (*does_ptr)(fcode_env_t *env) = install_does;
390Sstevel@tonic-gate void (*quote_ptr)(fcode_env_t *env) = do_quote;
400Sstevel@tonic-gate void (*blit_ptr)(fcode_env_t *env) = do_literal;
410Sstevel@tonic-gate void (*tlit_ptr)(fcode_env_t *env) = do_literal;
420Sstevel@tonic-gate void (*do_bdo_ptr)(fcode_env_t *env) = do_bdo;
430Sstevel@tonic-gate void (*do_bqdo_ptr)(fcode_env_t *env) = do_bqdo;
440Sstevel@tonic-gate void (*create_ptr)(fcode_env_t *env) = do_creator;
450Sstevel@tonic-gate void (*do_leave_ptr)(fcode_env_t *env) = do_bleave;
460Sstevel@tonic-gate void (*do_loop_ptr)(fcode_env_t *env) = do_bloop;
470Sstevel@tonic-gate void (*do_ploop_ptr)(fcode_env_t *env) = do_bploop;
480Sstevel@tonic-gate 
490Sstevel@tonic-gate void unaligned_lstore(fcode_env_t *);
500Sstevel@tonic-gate void unaligned_wstore(fcode_env_t *);
510Sstevel@tonic-gate void unaligned_lfetch(fcode_env_t *);
520Sstevel@tonic-gate void unaligned_wfetch(fcode_env_t *);
530Sstevel@tonic-gate 
540Sstevel@tonic-gate /* start with the simple maths functions */
550Sstevel@tonic-gate 
560Sstevel@tonic-gate 
570Sstevel@tonic-gate void
add(fcode_env_t * env)580Sstevel@tonic-gate add(fcode_env_t *env)
590Sstevel@tonic-gate {
600Sstevel@tonic-gate 	fstack_t d;
610Sstevel@tonic-gate 
620Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "+");
630Sstevel@tonic-gate 	d = POP(DS);
640Sstevel@tonic-gate 	TOS += d;
650Sstevel@tonic-gate }
660Sstevel@tonic-gate 
670Sstevel@tonic-gate void
subtract(fcode_env_t * env)680Sstevel@tonic-gate subtract(fcode_env_t *env)
690Sstevel@tonic-gate {
700Sstevel@tonic-gate 	fstack_t d;
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "-");
730Sstevel@tonic-gate 	d = POP(DS);
740Sstevel@tonic-gate 	TOS -= d;
750Sstevel@tonic-gate }
760Sstevel@tonic-gate 
770Sstevel@tonic-gate void
multiply(fcode_env_t * env)780Sstevel@tonic-gate multiply(fcode_env_t *env)
790Sstevel@tonic-gate {
800Sstevel@tonic-gate 	fstack_t d;
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "*");
830Sstevel@tonic-gate 	d = POP(DS);
840Sstevel@tonic-gate 	TOS *= d;
850Sstevel@tonic-gate }
860Sstevel@tonic-gate 
870Sstevel@tonic-gate void
slash_mod(fcode_env_t * env)880Sstevel@tonic-gate slash_mod(fcode_env_t *env)
890Sstevel@tonic-gate {
900Sstevel@tonic-gate 	fstack_t d, o, t, rem;
910Sstevel@tonic-gate 	int sign = 1;
920Sstevel@tonic-gate 
930Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "/mod");
940Sstevel@tonic-gate 	d = POP(DS);
950Sstevel@tonic-gate 	o = t = POP(DS);
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	if (d == 0) {
980Sstevel@tonic-gate 		throw_from_fclib(env, 1, "/mod divide by zero");
990Sstevel@tonic-gate 	}
1000Sstevel@tonic-gate 	sign = ((d ^ t) < 0);
1010Sstevel@tonic-gate 	if (d < 0) {
1020Sstevel@tonic-gate 		d = -d;
1030Sstevel@tonic-gate 		if (sign) {
1040Sstevel@tonic-gate 			t += (d-1);
1050Sstevel@tonic-gate 		}
1060Sstevel@tonic-gate 	}
1070Sstevel@tonic-gate 	if (t < 0) {
1080Sstevel@tonic-gate 		if (sign) {
1090Sstevel@tonic-gate 			t -= (d-1);
1100Sstevel@tonic-gate 		}
1110Sstevel@tonic-gate 		t = -t;
1120Sstevel@tonic-gate 	}
1130Sstevel@tonic-gate 	t = t / d;
1140Sstevel@tonic-gate 	if ((o ^ sign) < 0) {
1150Sstevel@tonic-gate 		rem = (t * d) + o;
1160Sstevel@tonic-gate 	} else {
1170Sstevel@tonic-gate 		rem = o - (t*d);
1180Sstevel@tonic-gate 	}
1190Sstevel@tonic-gate 	if (sign) {
1200Sstevel@tonic-gate 		t = -t;
1210Sstevel@tonic-gate 	}
1220Sstevel@tonic-gate 	PUSH(DS, rem);
1230Sstevel@tonic-gate 	PUSH(DS, t);
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate /*
1270Sstevel@tonic-gate  * 'u/mod' Fcode implementation.
1280Sstevel@tonic-gate  */
1290Sstevel@tonic-gate void
uslash_mod(fcode_env_t * env)1300Sstevel@tonic-gate uslash_mod(fcode_env_t *env)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate 	u_lforth_t u1, u2;
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "u/mod");
1350Sstevel@tonic-gate 	u2 = POP(DS);
1360Sstevel@tonic-gate 	u1 = POP(DS);
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	if (u2 == 0)
1390Sstevel@tonic-gate 		forth_abort(env, "u/mod: divide by zero");
1400Sstevel@tonic-gate 	PUSH(DS, u1 % u2);
1410Sstevel@tonic-gate 	PUSH(DS, u1 / u2);
1420Sstevel@tonic-gate }
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate void
divide(fcode_env_t * env)1450Sstevel@tonic-gate divide(fcode_env_t *env)
1460Sstevel@tonic-gate {
1470Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "/");
1480Sstevel@tonic-gate 	slash_mod(env);
1490Sstevel@tonic-gate 	nip(env);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate void
mod(fcode_env_t * env)1530Sstevel@tonic-gate mod(fcode_env_t *env)
1540Sstevel@tonic-gate {
1550Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "mod");
1560Sstevel@tonic-gate 	slash_mod(env);
1570Sstevel@tonic-gate 	drop(env);
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate void
and(fcode_env_t * env)1610Sstevel@tonic-gate and(fcode_env_t *env)
1620Sstevel@tonic-gate {
1630Sstevel@tonic-gate 	fstack_t d;
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "and");
1660Sstevel@tonic-gate 	d = POP(DS);
1670Sstevel@tonic-gate 	TOS &= d;
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate void
or(fcode_env_t * env)1710Sstevel@tonic-gate or(fcode_env_t *env)
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate 	fstack_t d;
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "or");
1760Sstevel@tonic-gate 	d = POP(DS);
1770Sstevel@tonic-gate 	TOS |= d;
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate void
xor(fcode_env_t * env)1810Sstevel@tonic-gate xor(fcode_env_t *env)
1820Sstevel@tonic-gate {
1830Sstevel@tonic-gate 	fstack_t d;
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "xor");
1860Sstevel@tonic-gate 	d = POP(DS);
1870Sstevel@tonic-gate 	TOS ^= d;
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate void
invert(fcode_env_t * env)1910Sstevel@tonic-gate invert(fcode_env_t *env)
1920Sstevel@tonic-gate {
1930Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "invert");
1940Sstevel@tonic-gate 	TOS = ~TOS;
1950Sstevel@tonic-gate }
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate void
lshift(fcode_env_t * env)1980Sstevel@tonic-gate lshift(fcode_env_t *env)
1990Sstevel@tonic-gate {
2000Sstevel@tonic-gate 	fstack_t d;
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "lshift");
2030Sstevel@tonic-gate 	d = POP(DS);
2040Sstevel@tonic-gate 	TOS = TOS << d;
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate void
rshift(fcode_env_t * env)2080Sstevel@tonic-gate rshift(fcode_env_t *env)
2090Sstevel@tonic-gate {
2100Sstevel@tonic-gate 	fstack_t d;
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "rshift");
2130Sstevel@tonic-gate 	d = POP(DS);
2140Sstevel@tonic-gate 	TOS = ((ufstack_t)TOS) >> d;
2150Sstevel@tonic-gate }
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate void
rshifta(fcode_env_t * env)2180Sstevel@tonic-gate rshifta(fcode_env_t *env)
2190Sstevel@tonic-gate {
2200Sstevel@tonic-gate 	fstack_t d;
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, ">>a");
2230Sstevel@tonic-gate 	d = POP(DS);
2240Sstevel@tonic-gate 	TOS = ((s_lforth_t)TOS) >> d;
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate void
negate(fcode_env_t * env)2280Sstevel@tonic-gate negate(fcode_env_t *env)
2290Sstevel@tonic-gate {
2300Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "negate");
2310Sstevel@tonic-gate 	TOS = -TOS;
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate void
f_abs(fcode_env_t * env)2350Sstevel@tonic-gate f_abs(fcode_env_t *env)
2360Sstevel@tonic-gate {
2370Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "abs");
2380Sstevel@tonic-gate 	if (TOS < 0) TOS = -TOS;
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate void
f_min(fcode_env_t * env)2420Sstevel@tonic-gate f_min(fcode_env_t *env)
2430Sstevel@tonic-gate {
2440Sstevel@tonic-gate 	fstack_t d;
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "min");
2470Sstevel@tonic-gate 	d = POP(DS);
2480Sstevel@tonic-gate 	if (d < TOS)	TOS = d;
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate void
f_max(fcode_env_t * env)2520Sstevel@tonic-gate f_max(fcode_env_t *env)
2530Sstevel@tonic-gate {
2540Sstevel@tonic-gate 	fstack_t d;
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "max");
2570Sstevel@tonic-gate 	d = POP(DS);
2580Sstevel@tonic-gate 	if (d > TOS)	TOS = d;
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate void
to_r(fcode_env_t * env)2620Sstevel@tonic-gate to_r(fcode_env_t *env)
2630Sstevel@tonic-gate {
2640Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, ">r");
2650Sstevel@tonic-gate 	PUSH(RS, POP(DS));
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate void
from_r(fcode_env_t * env)2690Sstevel@tonic-gate from_r(fcode_env_t *env)
2700Sstevel@tonic-gate {
2710Sstevel@tonic-gate 	CHECK_RETURN_DEPTH(env, 1, "r>");
2720Sstevel@tonic-gate 	PUSH(DS, POP(RS));
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate void
rfetch(fcode_env_t * env)2760Sstevel@tonic-gate rfetch(fcode_env_t *env)
2770Sstevel@tonic-gate {
2780Sstevel@tonic-gate 	CHECK_RETURN_DEPTH(env, 1, "r@");
2790Sstevel@tonic-gate 	PUSH(DS, *RS);
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate void
f_exit(fcode_env_t * env)2830Sstevel@tonic-gate f_exit(fcode_env_t *env)
2840Sstevel@tonic-gate {
2850Sstevel@tonic-gate 	CHECK_RETURN_DEPTH(env, 1, "exit");
2860Sstevel@tonic-gate 	IP = (token_t *)POP(RS);
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate #define	COMPARE(cmp, rhs)	((((s_lforth_t)TOS) cmp((s_lforth_t)(rhs))) ? \
2900Sstevel@tonic-gate 				    TRUE : FALSE)
2910Sstevel@tonic-gate #define	UCOMPARE(cmp, rhs) 	((((u_lforth_t)TOS) cmp((u_lforth_t)(rhs))) ? \
2920Sstevel@tonic-gate 				    TRUE : FALSE)
2930Sstevel@tonic-gate #define	EQUALS		==
2940Sstevel@tonic-gate #define	NOTEQUALS	!=
2950Sstevel@tonic-gate #define	LESSTHAN	<
2960Sstevel@tonic-gate #define	LESSEQUALS	<=
2970Sstevel@tonic-gate #define	GREATERTHAN	>
2980Sstevel@tonic-gate #define	GREATEREQUALS	>=
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate void
zero_equals(fcode_env_t * env)3010Sstevel@tonic-gate zero_equals(fcode_env_t *env)
3020Sstevel@tonic-gate {
3030Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "0=");
3040Sstevel@tonic-gate 	TOS = COMPARE(EQUALS, 0);
3050Sstevel@tonic-gate }
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate void
zero_not_equals(fcode_env_t * env)3080Sstevel@tonic-gate zero_not_equals(fcode_env_t *env)
3090Sstevel@tonic-gate {
3100Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "0<>");
3110Sstevel@tonic-gate 	TOS = COMPARE(NOTEQUALS, 0);
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate void
zero_less(fcode_env_t * env)3150Sstevel@tonic-gate zero_less(fcode_env_t *env)
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "0<");
3180Sstevel@tonic-gate 	TOS = COMPARE(LESSTHAN, 0);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate void
zero_less_equals(fcode_env_t * env)3220Sstevel@tonic-gate zero_less_equals(fcode_env_t *env)
3230Sstevel@tonic-gate {
3240Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "0<=");
3250Sstevel@tonic-gate 	TOS = COMPARE(LESSEQUALS, 0);
3260Sstevel@tonic-gate }
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate void
zero_greater(fcode_env_t * env)3290Sstevel@tonic-gate zero_greater(fcode_env_t *env)
3300Sstevel@tonic-gate {
3310Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "0>");
3320Sstevel@tonic-gate 	TOS = COMPARE(GREATERTHAN, 0);
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate void
zero_greater_equals(fcode_env_t * env)3360Sstevel@tonic-gate zero_greater_equals(fcode_env_t *env)
3370Sstevel@tonic-gate {
3380Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "0>=");
3390Sstevel@tonic-gate 	TOS = COMPARE(GREATEREQUALS, 0);
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate void
less(fcode_env_t * env)3430Sstevel@tonic-gate less(fcode_env_t *env)
3440Sstevel@tonic-gate {
3450Sstevel@tonic-gate 	fstack_t d;
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "<");
3480Sstevel@tonic-gate 	d = POP(DS);
3490Sstevel@tonic-gate 	TOS = COMPARE(LESSTHAN, d);
3500Sstevel@tonic-gate }
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate void
greater(fcode_env_t * env)3530Sstevel@tonic-gate greater(fcode_env_t *env)
3540Sstevel@tonic-gate {
3550Sstevel@tonic-gate 	fstack_t d;
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, ">");
3580Sstevel@tonic-gate 	d = POP(DS);
3590Sstevel@tonic-gate 	TOS = COMPARE(GREATERTHAN, d);
3600Sstevel@tonic-gate }
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate void
equals(fcode_env_t * env)3630Sstevel@tonic-gate equals(fcode_env_t *env)
3640Sstevel@tonic-gate {
3650Sstevel@tonic-gate 	fstack_t d;
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "=");
3680Sstevel@tonic-gate 	d = POP(DS);
3690Sstevel@tonic-gate 	TOS = COMPARE(EQUALS, d);
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate void
not_equals(fcode_env_t * env)3730Sstevel@tonic-gate not_equals(fcode_env_t *env)
3740Sstevel@tonic-gate {
3750Sstevel@tonic-gate 	fstack_t d;
3760Sstevel@tonic-gate 
3770Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "<>");
3780Sstevel@tonic-gate 	d = POP(DS);
3790Sstevel@tonic-gate 	TOS = COMPARE(NOTEQUALS, d);
3800Sstevel@tonic-gate }
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate void
unsign_greater(fcode_env_t * env)3840Sstevel@tonic-gate unsign_greater(fcode_env_t *env)
3850Sstevel@tonic-gate {
3860Sstevel@tonic-gate 	ufstack_t d;
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "u>");
3890Sstevel@tonic-gate 	d = POP(DS);
3900Sstevel@tonic-gate 	TOS = UCOMPARE(GREATERTHAN, d);
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate 
3930Sstevel@tonic-gate void
unsign_less_equals(fcode_env_t * env)3940Sstevel@tonic-gate unsign_less_equals(fcode_env_t *env)
3950Sstevel@tonic-gate {
3960Sstevel@tonic-gate 	ufstack_t d;
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "u<=");
3990Sstevel@tonic-gate 	d = POP(DS);
4000Sstevel@tonic-gate 	TOS = UCOMPARE(LESSEQUALS, d);
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate void
unsign_less(fcode_env_t * env)4040Sstevel@tonic-gate unsign_less(fcode_env_t *env)
4050Sstevel@tonic-gate {
4060Sstevel@tonic-gate 	ufstack_t d;
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "u<");
4090Sstevel@tonic-gate 	d = POP(DS);
4100Sstevel@tonic-gate 	TOS = UCOMPARE(LESSTHAN, d);
4110Sstevel@tonic-gate }
4120Sstevel@tonic-gate 
4130Sstevel@tonic-gate void
unsign_greater_equals(fcode_env_t * env)4140Sstevel@tonic-gate unsign_greater_equals(fcode_env_t *env)
4150Sstevel@tonic-gate {
4160Sstevel@tonic-gate 	ufstack_t d;
4170Sstevel@tonic-gate 
4180Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "u>=");
4190Sstevel@tonic-gate 	d = POP(DS);
4200Sstevel@tonic-gate 	TOS = UCOMPARE(GREATEREQUALS, d);
4210Sstevel@tonic-gate }
4220Sstevel@tonic-gate 
4230Sstevel@tonic-gate void
greater_equals(fcode_env_t * env)4240Sstevel@tonic-gate greater_equals(fcode_env_t *env)
4250Sstevel@tonic-gate {
4260Sstevel@tonic-gate 	fstack_t d;
4270Sstevel@tonic-gate 
4280Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, ">=");
4290Sstevel@tonic-gate 	d = POP(DS);
4300Sstevel@tonic-gate 	TOS = COMPARE(GREATEREQUALS, d);
4310Sstevel@tonic-gate }
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate void
less_equals(fcode_env_t * env)4340Sstevel@tonic-gate less_equals(fcode_env_t *env)
4350Sstevel@tonic-gate {
4360Sstevel@tonic-gate 	fstack_t d;
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "<=");
4390Sstevel@tonic-gate 	d = POP(DS);
4400Sstevel@tonic-gate 	TOS = COMPARE(LESSEQUALS, d);
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate void
between(fcode_env_t * env)4440Sstevel@tonic-gate between(fcode_env_t *env)
4450Sstevel@tonic-gate {
446*3956Sgovinda 	u_lforth_t hi, lo;
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "between");
449*3956Sgovinda 	hi = (u_lforth_t)POP(DS);
450*3956Sgovinda 	lo = (u_lforth_t)POP(DS);
451*3956Sgovinda 	TOS = (((u_lforth_t)TOS >= lo) && ((u_lforth_t)TOS <= hi) ? -1 : 0);
4520Sstevel@tonic-gate }
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate void
within(fcode_env_t * env)4550Sstevel@tonic-gate within(fcode_env_t *env)
4560Sstevel@tonic-gate {
457*3956Sgovinda 	u_lforth_t lo, hi;
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "within");
460*3956Sgovinda 	hi = (u_lforth_t)POP(DS);
461*3956Sgovinda 	lo = (u_lforth_t)POP(DS);
462*3956Sgovinda 	TOS = ((((u_lforth_t)TOS >= lo) && ((u_lforth_t)TOS < hi)) ? -1 : 0);
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate void
do_literal(fcode_env_t * env)4660Sstevel@tonic-gate do_literal(fcode_env_t *env)
4670Sstevel@tonic-gate {
4680Sstevel@tonic-gate 	PUSH(DS, *IP);
4690Sstevel@tonic-gate 	IP++;
4700Sstevel@tonic-gate }
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate void
literal(fcode_env_t * env)4730Sstevel@tonic-gate literal(fcode_env_t *env)
4740Sstevel@tonic-gate {
4750Sstevel@tonic-gate 	if (env->state) {
4760Sstevel@tonic-gate 		COMPILE_TOKEN(&blit_ptr);
4770Sstevel@tonic-gate 		compile_comma(env);
4780Sstevel@tonic-gate 	}
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate 
4810Sstevel@tonic-gate void
do_also(fcode_env_t * env)4820Sstevel@tonic-gate do_also(fcode_env_t *env)
4830Sstevel@tonic-gate {
4840Sstevel@tonic-gate 	token_t *d = *ORDER;
4850Sstevel@tonic-gate 
4860Sstevel@tonic-gate 	if (env->order_depth < (MAX_ORDER - 1)) {
4870Sstevel@tonic-gate 		env->order[++env->order_depth] = d;
4880Sstevel@tonic-gate 		debug_msg(DEBUG_CONTEXT, "CONTEXT:also: %d/%p/%p\n",
4890Sstevel@tonic-gate 		    env->order_depth, CONTEXT, env->current);
4900Sstevel@tonic-gate 	} else
4910Sstevel@tonic-gate 		log_message(MSG_WARN, "Vocabulary search order exceeds: %d\n",
4920Sstevel@tonic-gate 		    MAX_ORDER);
4930Sstevel@tonic-gate }
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate void
do_previous(fcode_env_t * env)4960Sstevel@tonic-gate do_previous(fcode_env_t *env)
4970Sstevel@tonic-gate {
4980Sstevel@tonic-gate 	if (env->order_depth) {
4990Sstevel@tonic-gate 		env->order_depth--;
5000Sstevel@tonic-gate 		debug_msg(DEBUG_CONTEXT, "CONTEXT:previous: %d/%p/%p\n",
5010Sstevel@tonic-gate 		    env->order_depth, CONTEXT, env->current);
5020Sstevel@tonic-gate 	}
5030Sstevel@tonic-gate }
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate #ifdef DEBUG
5060Sstevel@tonic-gate void
do_order(fcode_env_t * env)5070Sstevel@tonic-gate do_order(fcode_env_t *env)
5080Sstevel@tonic-gate {
5090Sstevel@tonic-gate 	int i;
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 	log_message(MSG_INFO, "Order: Depth: %ld: ", env->order_depth);
5120Sstevel@tonic-gate 	for (i = env->order_depth; i >= 0 && env->order[i]; i--)
5130Sstevel@tonic-gate 		log_message(MSG_INFO, "%p ", (void *)env->order[i]);
5140Sstevel@tonic-gate 	log_message(MSG_INFO, "\n");
5150Sstevel@tonic-gate }
5160Sstevel@tonic-gate #endif
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate void
noop(fcode_env_t * env)5190Sstevel@tonic-gate noop(fcode_env_t *env)
5200Sstevel@tonic-gate {
5210Sstevel@tonic-gate 	/* what a waste of cycles */
5220Sstevel@tonic-gate }
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate 
5250Sstevel@tonic-gate #define	FW_PER_FL	(sizeof (lforth_t)/sizeof (wforth_t))
5260Sstevel@tonic-gate 
5270Sstevel@tonic-gate void
lwsplit(fcode_env_t * env)5280Sstevel@tonic-gate lwsplit(fcode_env_t *env)
5290Sstevel@tonic-gate {
5300Sstevel@tonic-gate 	union {
5310Sstevel@tonic-gate 		u_wforth_t l_wf[FW_PER_FL];
5320Sstevel@tonic-gate 		u_lforth_t l_lf;
5330Sstevel@tonic-gate 	} d;
5340Sstevel@tonic-gate 	int i;
5350Sstevel@tonic-gate 
5360Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "lwsplit");
5370Sstevel@tonic-gate 	d.l_lf = POP(DS);
5380Sstevel@tonic-gate 	for (i = 0; i < FW_PER_FL; i++)
5390Sstevel@tonic-gate 		PUSH(DS, d.l_wf[(FW_PER_FL - 1) - i]);
5400Sstevel@tonic-gate }
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate void
wljoin(fcode_env_t * env)5430Sstevel@tonic-gate wljoin(fcode_env_t *env)
5440Sstevel@tonic-gate {
5450Sstevel@tonic-gate 	union {
5460Sstevel@tonic-gate 		u_wforth_t l_wf[FW_PER_FL];
5470Sstevel@tonic-gate 		u_lforth_t l_lf;
5480Sstevel@tonic-gate 	} d;
5490Sstevel@tonic-gate 	int i;
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 	CHECK_DEPTH(env, FW_PER_FL, "wljoin");
5520Sstevel@tonic-gate 	for (i = 0; i < FW_PER_FL; i++)
5530Sstevel@tonic-gate 		d.l_wf[i] = POP(DS);
5540Sstevel@tonic-gate 	PUSH(DS, d.l_lf);
5550Sstevel@tonic-gate }
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate void
lwflip(fcode_env_t * env)5580Sstevel@tonic-gate lwflip(fcode_env_t *env)
5590Sstevel@tonic-gate {
5600Sstevel@tonic-gate 	union {
5610Sstevel@tonic-gate 		u_wforth_t l_wf[FW_PER_FL];
5620Sstevel@tonic-gate 		u_lforth_t l_lf;
5630Sstevel@tonic-gate 	} d, c;
5640Sstevel@tonic-gate 	int i;
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "lwflip");
5670Sstevel@tonic-gate 	d.l_lf = POP(DS);
5680Sstevel@tonic-gate 	for (i = 0; i < FW_PER_FL; i++)
5690Sstevel@tonic-gate 		c.l_wf[i] = d.l_wf[(FW_PER_FL - 1) - i];
5700Sstevel@tonic-gate 	PUSH(DS, c.l_lf);
5710Sstevel@tonic-gate }
5720Sstevel@tonic-gate 
5730Sstevel@tonic-gate void
lbsplit(fcode_env_t * env)5740Sstevel@tonic-gate lbsplit(fcode_env_t *env)
5750Sstevel@tonic-gate {
5760Sstevel@tonic-gate 	union {
5770Sstevel@tonic-gate 		uchar_t l_bytes[sizeof (lforth_t)];
5780Sstevel@tonic-gate 		u_lforth_t l_lf;
5790Sstevel@tonic-gate 	} d;
5800Sstevel@tonic-gate 	int i;
5810Sstevel@tonic-gate 
5820Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "lbsplit");
5830Sstevel@tonic-gate 	d.l_lf = POP(DS);
5840Sstevel@tonic-gate 	for (i = 0; i < sizeof (lforth_t); i++)
5850Sstevel@tonic-gate 		PUSH(DS, d.l_bytes[(sizeof (lforth_t) - 1) - i]);
5860Sstevel@tonic-gate }
5870Sstevel@tonic-gate 
5880Sstevel@tonic-gate void
bljoin(fcode_env_t * env)5890Sstevel@tonic-gate bljoin(fcode_env_t *env)
5900Sstevel@tonic-gate {
5910Sstevel@tonic-gate 	union {
5920Sstevel@tonic-gate 		uchar_t l_bytes[sizeof (lforth_t)];
5930Sstevel@tonic-gate 		u_lforth_t l_lf;
5940Sstevel@tonic-gate 	} d;
5950Sstevel@tonic-gate 	int i;
5960Sstevel@tonic-gate 
5970Sstevel@tonic-gate 	CHECK_DEPTH(env, sizeof (lforth_t), "bljoin");
5980Sstevel@tonic-gate 	for (i = 0; i < sizeof (lforth_t); i++)
5990Sstevel@tonic-gate 		d.l_bytes[i] = POP(DS);
6000Sstevel@tonic-gate 	PUSH(DS, (fstack_t)d.l_lf);
6010Sstevel@tonic-gate }
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate void
lbflip(fcode_env_t * env)6040Sstevel@tonic-gate lbflip(fcode_env_t *env)
6050Sstevel@tonic-gate {
6060Sstevel@tonic-gate 	union {
6070Sstevel@tonic-gate 		uchar_t l_bytes[sizeof (lforth_t)];
6080Sstevel@tonic-gate 		u_lforth_t l_lf;
6090Sstevel@tonic-gate 	} d, c;
6100Sstevel@tonic-gate 	int i;
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "lbflip");
6130Sstevel@tonic-gate 	d.l_lf = POP(DS);
6140Sstevel@tonic-gate 	for (i = 0; i < sizeof (lforth_t); i++)
6150Sstevel@tonic-gate 		c.l_bytes[i] = d.l_bytes[(sizeof (lforth_t) - 1) - i];
6160Sstevel@tonic-gate 	PUSH(DS, c.l_lf);
6170Sstevel@tonic-gate }
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate void
wbsplit(fcode_env_t * env)6200Sstevel@tonic-gate wbsplit(fcode_env_t *env)
6210Sstevel@tonic-gate {
6220Sstevel@tonic-gate 	union {
6230Sstevel@tonic-gate 		uchar_t w_bytes[sizeof (wforth_t)];
6240Sstevel@tonic-gate 		u_wforth_t w_wf;
6250Sstevel@tonic-gate 	} d;
6260Sstevel@tonic-gate 	int i;
6270Sstevel@tonic-gate 
6280Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "wbsplit");
6290Sstevel@tonic-gate 	d.w_wf = POP(DS);
6300Sstevel@tonic-gate 	for (i = 0; i < sizeof (wforth_t); i++)
6310Sstevel@tonic-gate 		PUSH(DS, d.w_bytes[(sizeof (wforth_t) - 1) - i]);
6320Sstevel@tonic-gate }
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate void
bwjoin(fcode_env_t * env)6350Sstevel@tonic-gate bwjoin(fcode_env_t *env)
6360Sstevel@tonic-gate {
6370Sstevel@tonic-gate 	union {
6380Sstevel@tonic-gate 		uchar_t w_bytes[sizeof (wforth_t)];
6390Sstevel@tonic-gate 		u_wforth_t w_wf;
6400Sstevel@tonic-gate 	} d;
6410Sstevel@tonic-gate 	int i;
6420Sstevel@tonic-gate 
6430Sstevel@tonic-gate 	CHECK_DEPTH(env, sizeof (wforth_t), "bwjoin");
6440Sstevel@tonic-gate 	for (i = 0; i < sizeof (wforth_t); i++)
6450Sstevel@tonic-gate 		d.w_bytes[i] = POP(DS);
6460Sstevel@tonic-gate 	PUSH(DS, d.w_wf);
6470Sstevel@tonic-gate }
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate void
wbflip(fcode_env_t * env)6500Sstevel@tonic-gate wbflip(fcode_env_t *env)
6510Sstevel@tonic-gate {
6520Sstevel@tonic-gate 	union {
6530Sstevel@tonic-gate 		uchar_t w_bytes[sizeof (wforth_t)];
6540Sstevel@tonic-gate 		u_wforth_t w_wf;
6550Sstevel@tonic-gate 	} c, d;
6560Sstevel@tonic-gate 	int i;
6570Sstevel@tonic-gate 
6580Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "wbflip");
6590Sstevel@tonic-gate 	d.w_wf = POP(DS);
6600Sstevel@tonic-gate 	for (i = 0; i < sizeof (wforth_t); i++)
6610Sstevel@tonic-gate 		c.w_bytes[i] = d.w_bytes[(sizeof (wforth_t) - 1) - i];
6620Sstevel@tonic-gate 	PUSH(DS, c.w_wf);
6630Sstevel@tonic-gate }
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate void
upper_case(fcode_env_t * env)6660Sstevel@tonic-gate upper_case(fcode_env_t *env)
6670Sstevel@tonic-gate {
6680Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "upc");
6690Sstevel@tonic-gate 	TOS = toupper(TOS);
6700Sstevel@tonic-gate }
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate void
lower_case(fcode_env_t * env)6730Sstevel@tonic-gate lower_case(fcode_env_t *env)
6740Sstevel@tonic-gate {
6750Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "lcc");
6760Sstevel@tonic-gate 	TOS = tolower(TOS);
6770Sstevel@tonic-gate }
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate void
pack_str(fcode_env_t * env)6800Sstevel@tonic-gate pack_str(fcode_env_t *env)
6810Sstevel@tonic-gate {
6820Sstevel@tonic-gate 	char *buf;
6830Sstevel@tonic-gate 	size_t len;
6840Sstevel@tonic-gate 	char *str;
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "pack");
6870Sstevel@tonic-gate 	buf = (char *)POP(DS);
6880Sstevel@tonic-gate 	len = (size_t)POP(DS);
6890Sstevel@tonic-gate 	str = (char *)TOS;
6900Sstevel@tonic-gate 	TOS = (fstack_t)buf;
6910Sstevel@tonic-gate 	*buf++ = (uchar_t)len;
6920Sstevel@tonic-gate 	strncpy(buf, str, (len&0xff));
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate void
count_str(fcode_env_t * env)6960Sstevel@tonic-gate count_str(fcode_env_t *env)
6970Sstevel@tonic-gate {
6980Sstevel@tonic-gate 	uchar_t *len;
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "count");
7010Sstevel@tonic-gate 	len = (uchar_t *)TOS;
7020Sstevel@tonic-gate 	TOS += 1;
7030Sstevel@tonic-gate 	PUSH(DS, *len);
7040Sstevel@tonic-gate }
7050Sstevel@tonic-gate 
7060Sstevel@tonic-gate void
to_body(fcode_env_t * env)7070Sstevel@tonic-gate to_body(fcode_env_t *env)
7080Sstevel@tonic-gate {
7090Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, ">body");
7100Sstevel@tonic-gate 	TOS = (fstack_t)(((acf_t)TOS)+1);
7110Sstevel@tonic-gate }
7120Sstevel@tonic-gate 
7130Sstevel@tonic-gate void
to_acf(fcode_env_t * env)7140Sstevel@tonic-gate to_acf(fcode_env_t *env)
7150Sstevel@tonic-gate {
7160Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "body>");
7170Sstevel@tonic-gate 	TOS = (fstack_t)(((acf_t)TOS)-1);
7180Sstevel@tonic-gate }
7190Sstevel@tonic-gate 
7200Sstevel@tonic-gate /*
7210Sstevel@tonic-gate  * 'unloop' Fcode implementation, drop 3 loop ctrl elements off return stack.
7220Sstevel@tonic-gate  */
7230Sstevel@tonic-gate static void
unloop(fcode_env_t * env)7240Sstevel@tonic-gate unloop(fcode_env_t *env)
7250Sstevel@tonic-gate {
7260Sstevel@tonic-gate 	CHECK_RETURN_DEPTH(env, 3, "unloop");
7270Sstevel@tonic-gate 	RS -= 3;
7280Sstevel@tonic-gate }
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate /*
7310Sstevel@tonic-gate  * 'um*' Fcode implementation.
7320Sstevel@tonic-gate  */
7330Sstevel@tonic-gate static void
um_multiply(fcode_env_t * env)7340Sstevel@tonic-gate um_multiply(fcode_env_t *env)
7350Sstevel@tonic-gate {
7360Sstevel@tonic-gate 	ufstack_t u1, u2;
7370Sstevel@tonic-gate 	dforth_t d;
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "um*");
7400Sstevel@tonic-gate 	u1 = POP(DS);
7410Sstevel@tonic-gate 	u2 = POP(DS);
7420Sstevel@tonic-gate 	d = u1 * u2;
7430Sstevel@tonic-gate 	push_double(env, d);
7440Sstevel@tonic-gate }
7450Sstevel@tonic-gate 
7460Sstevel@tonic-gate /*
7470Sstevel@tonic-gate  * um/mod (d.lo d.hi u -- urem uquot)
7480Sstevel@tonic-gate  */
7490Sstevel@tonic-gate static void
um_slash_mod(fcode_env_t * env)7500Sstevel@tonic-gate um_slash_mod(fcode_env_t *env)
7510Sstevel@tonic-gate {
7520Sstevel@tonic-gate 	u_dforth_t d;
7530Sstevel@tonic-gate 	uint32_t u, urem, uquot;
7540Sstevel@tonic-gate 
7550Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "um/mod");
7560Sstevel@tonic-gate 	u = (uint32_t)POP(DS);
7570Sstevel@tonic-gate 	d = pop_double(env);
7580Sstevel@tonic-gate 	urem = d % u;
7590Sstevel@tonic-gate 	uquot = d / u;
7600Sstevel@tonic-gate 	PUSH(DS, urem);
7610Sstevel@tonic-gate 	PUSH(DS, uquot);
7620Sstevel@tonic-gate }
7630Sstevel@tonic-gate 
7640Sstevel@tonic-gate /*
7650Sstevel@tonic-gate  * d+ (d1.lo d1.hi d2.lo d2.hi -- dsum.lo dsum.hi)
7660Sstevel@tonic-gate  */
7670Sstevel@tonic-gate static void
d_plus(fcode_env_t * env)7680Sstevel@tonic-gate d_plus(fcode_env_t *env)
7690Sstevel@tonic-gate {
7700Sstevel@tonic-gate 	dforth_t d1, d2;
7710Sstevel@tonic-gate 
7720Sstevel@tonic-gate 	CHECK_DEPTH(env, 4, "d+");
7730Sstevel@tonic-gate 	d2 = pop_double(env);
7740Sstevel@tonic-gate 	d1 = pop_double(env);
7750Sstevel@tonic-gate 	d1 += d2;
7760Sstevel@tonic-gate 	push_double(env, d1);
7770Sstevel@tonic-gate }
7780Sstevel@tonic-gate 
7790Sstevel@tonic-gate /*
7800Sstevel@tonic-gate  * d- (d1.lo d1.hi d2.lo d2.hi -- ddif.lo ddif.hi)
7810Sstevel@tonic-gate  */
7820Sstevel@tonic-gate static void
d_minus(fcode_env_t * env)7830Sstevel@tonic-gate d_minus(fcode_env_t *env)
7840Sstevel@tonic-gate {
7850Sstevel@tonic-gate 	dforth_t d1, d2;
7860Sstevel@tonic-gate 
7870Sstevel@tonic-gate 	CHECK_DEPTH(env, 4, "d-");
7880Sstevel@tonic-gate 	d2 = pop_double(env);
7890Sstevel@tonic-gate 	d1 = pop_double(env);
7900Sstevel@tonic-gate 	d1 -= d2;
7910Sstevel@tonic-gate 	push_double(env, d1);
7920Sstevel@tonic-gate }
7930Sstevel@tonic-gate 
7940Sstevel@tonic-gate void
set_here(fcode_env_t * env,uchar_t * new_here,char * where)7950Sstevel@tonic-gate set_here(fcode_env_t *env, uchar_t *new_here, char *where)
7960Sstevel@tonic-gate {
7970Sstevel@tonic-gate 	if (new_here < HERE) {
7980Sstevel@tonic-gate 		if (strcmp(where, "temporary_execute")) {
7990Sstevel@tonic-gate 			/*
8000Sstevel@tonic-gate 			 * Other than temporary_execute, no one should set
8010Sstevel@tonic-gate 			 * here backwards.
8020Sstevel@tonic-gate 			 */
8030Sstevel@tonic-gate 			log_message(MSG_WARN, "Warning: set_here(%s) back: old:"
8040Sstevel@tonic-gate 			    " %p new: %p\n", where, HERE, new_here);
8050Sstevel@tonic-gate 		}
8060Sstevel@tonic-gate 	}
8070Sstevel@tonic-gate 	if (new_here >= env->base + dict_size)
8080Sstevel@tonic-gate 		forth_abort(env, "Here (%p) set past dictionary end (%p)",
8090Sstevel@tonic-gate 		    new_here, env->base + dict_size);
8100Sstevel@tonic-gate 	HERE = new_here;
8110Sstevel@tonic-gate }
8120Sstevel@tonic-gate 
8130Sstevel@tonic-gate static void
unaligned_store(fcode_env_t * env)8140Sstevel@tonic-gate unaligned_store(fcode_env_t *env)
8150Sstevel@tonic-gate {
8160Sstevel@tonic-gate 	extern void unaligned_xstore(fcode_env_t *);
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate 	if (sizeof (fstack_t) == sizeof (lforth_t))
8190Sstevel@tonic-gate 		unaligned_lstore(env);
8200Sstevel@tonic-gate 	else
8210Sstevel@tonic-gate 		unaligned_xstore(env);
8220Sstevel@tonic-gate }
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate static void
unaligned_fetch(fcode_env_t * env)8250Sstevel@tonic-gate unaligned_fetch(fcode_env_t *env)
8260Sstevel@tonic-gate {
8270Sstevel@tonic-gate 	extern void unaligned_xfetch(fcode_env_t *);
8280Sstevel@tonic-gate 
8290Sstevel@tonic-gate 	if (sizeof (fstack_t) == sizeof (lforth_t))
8300Sstevel@tonic-gate 		unaligned_lfetch(env);
8310Sstevel@tonic-gate 	else
8320Sstevel@tonic-gate 		unaligned_xfetch(env);
8330Sstevel@tonic-gate }
8340Sstevel@tonic-gate 
8350Sstevel@tonic-gate void
comma(fcode_env_t * env)8360Sstevel@tonic-gate comma(fcode_env_t *env)
8370Sstevel@tonic-gate {
8380Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, ",");
8390Sstevel@tonic-gate 	DEBUGF(COMMA, dump_comma(env, ","));
8400Sstevel@tonic-gate 	PUSH(DS, (fstack_t)HERE);
8410Sstevel@tonic-gate 	unaligned_store(env);
8420Sstevel@tonic-gate 	set_here(env, HERE + sizeof (fstack_t), "comma");
8430Sstevel@tonic-gate }
8440Sstevel@tonic-gate 
8450Sstevel@tonic-gate void
lcomma(fcode_env_t * env)8460Sstevel@tonic-gate lcomma(fcode_env_t *env)
8470Sstevel@tonic-gate {
8480Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "l,");
8490Sstevel@tonic-gate 	DEBUGF(COMMA, dump_comma(env, "l,"));
8500Sstevel@tonic-gate 	PUSH(DS, (fstack_t)HERE);
8510Sstevel@tonic-gate 	unaligned_lstore(env);
8520Sstevel@tonic-gate 	set_here(env, HERE + sizeof (u_lforth_t), "lcomma");
8530Sstevel@tonic-gate }
8540Sstevel@tonic-gate 
8550Sstevel@tonic-gate void
wcomma(fcode_env_t * env)8560Sstevel@tonic-gate wcomma(fcode_env_t *env)
8570Sstevel@tonic-gate {
8580Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "w,");
8590Sstevel@tonic-gate 	DEBUGF(COMMA, dump_comma(env, "w,"));
8600Sstevel@tonic-gate 	PUSH(DS, (fstack_t)HERE);
8610Sstevel@tonic-gate 	unaligned_wstore(env);
8620Sstevel@tonic-gate 	set_here(env, HERE + sizeof (u_wforth_t), "wcomma");
8630Sstevel@tonic-gate }
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate void
ccomma(fcode_env_t * env)8660Sstevel@tonic-gate ccomma(fcode_env_t *env)
8670Sstevel@tonic-gate {
8680Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "c,");
8690Sstevel@tonic-gate 	DEBUGF(COMMA, dump_comma(env, "c,"));
8700Sstevel@tonic-gate 	PUSH(DS, (fstack_t)HERE);
8710Sstevel@tonic-gate 	cstore(env);
8720Sstevel@tonic-gate 	set_here(env, HERE + sizeof (uchar_t), "ccomma");
8730Sstevel@tonic-gate }
8740Sstevel@tonic-gate 
8750Sstevel@tonic-gate void
token_roundup(fcode_env_t * env,char * where)8760Sstevel@tonic-gate token_roundup(fcode_env_t *env, char *where)
8770Sstevel@tonic-gate {
8780Sstevel@tonic-gate 	if ((((token_t)HERE) & (sizeof (token_t) - 1)) != 0) {
8790Sstevel@tonic-gate 		set_here(env, (uchar_t *)TOKEN_ROUNDUP(HERE), where);
8800Sstevel@tonic-gate 	}
8810Sstevel@tonic-gate }
8820Sstevel@tonic-gate 
8830Sstevel@tonic-gate void
compile_comma(fcode_env_t * env)8840Sstevel@tonic-gate compile_comma(fcode_env_t *env)
8850Sstevel@tonic-gate {
8860Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "compile,");
8870Sstevel@tonic-gate 	DEBUGF(COMMA, dump_comma(env, "compile,"));
8880Sstevel@tonic-gate 	token_roundup(env, "compile,");
8890Sstevel@tonic-gate 	PUSH(DS, (fstack_t)HERE);
8900Sstevel@tonic-gate 	unaligned_store(env);
8910Sstevel@tonic-gate 	set_here(env, HERE + sizeof (fstack_t), "compile,");
8920Sstevel@tonic-gate }
8930Sstevel@tonic-gate 
8940Sstevel@tonic-gate void
unaligned_lfetch(fcode_env_t * env)8950Sstevel@tonic-gate unaligned_lfetch(fcode_env_t *env)
8960Sstevel@tonic-gate {
8970Sstevel@tonic-gate 	fstack_t addr;
8980Sstevel@tonic-gate 	int i;
8990Sstevel@tonic-gate 
9000Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "unaligned-l@");
9010Sstevel@tonic-gate 	addr = POP(DS);
9020Sstevel@tonic-gate 	for (i = 0; i < sizeof (lforth_t); i++, addr++) {
9030Sstevel@tonic-gate 		PUSH(DS, addr);
9040Sstevel@tonic-gate 		cfetch(env);
9050Sstevel@tonic-gate 	}
9060Sstevel@tonic-gate 	bljoin(env);
9070Sstevel@tonic-gate 	lbflip(env);
9080Sstevel@tonic-gate }
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate void
unaligned_lstore(fcode_env_t * env)9110Sstevel@tonic-gate unaligned_lstore(fcode_env_t *env)
9120Sstevel@tonic-gate {
9130Sstevel@tonic-gate 	fstack_t addr;
9140Sstevel@tonic-gate 	int i;
9150Sstevel@tonic-gate 
9160Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "unaligned-l!");
9170Sstevel@tonic-gate 	addr = POP(DS);
9180Sstevel@tonic-gate 	lbsplit(env);
9190Sstevel@tonic-gate 	for (i = 0; i < sizeof (lforth_t); i++, addr++) {
9200Sstevel@tonic-gate 		PUSH(DS, addr);
9210Sstevel@tonic-gate 		cstore(env);
9220Sstevel@tonic-gate 	}
9230Sstevel@tonic-gate }
9240Sstevel@tonic-gate 
9250Sstevel@tonic-gate void
unaligned_wfetch(fcode_env_t * env)9260Sstevel@tonic-gate unaligned_wfetch(fcode_env_t *env)
9270Sstevel@tonic-gate {
9280Sstevel@tonic-gate 	fstack_t addr;
9290Sstevel@tonic-gate 	int i;
9300Sstevel@tonic-gate 
9310Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "unaligned-w@");
9320Sstevel@tonic-gate 	addr = POP(DS);
9330Sstevel@tonic-gate 	for (i = 0; i < sizeof (wforth_t); i++, addr++) {
9340Sstevel@tonic-gate 		PUSH(DS, addr);
9350Sstevel@tonic-gate 		cfetch(env);
9360Sstevel@tonic-gate 	}
9370Sstevel@tonic-gate 	bwjoin(env);
9380Sstevel@tonic-gate 	wbflip(env);
9390Sstevel@tonic-gate }
9400Sstevel@tonic-gate 
9410Sstevel@tonic-gate void
unaligned_wstore(fcode_env_t * env)9420Sstevel@tonic-gate unaligned_wstore(fcode_env_t *env)
9430Sstevel@tonic-gate {
9440Sstevel@tonic-gate 	fstack_t addr;
9450Sstevel@tonic-gate 	int i;
9460Sstevel@tonic-gate 
9470Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "unaligned-w!");
9480Sstevel@tonic-gate 	addr = POP(DS);
9490Sstevel@tonic-gate 	wbsplit(env);
9500Sstevel@tonic-gate 	for (i = 0; i < sizeof (wforth_t); i++, addr++) {
9510Sstevel@tonic-gate 		PUSH(DS, addr);
9520Sstevel@tonic-gate 		cstore(env);
9530Sstevel@tonic-gate 	}
9540Sstevel@tonic-gate }
9550Sstevel@tonic-gate 
9560Sstevel@tonic-gate /*
9570Sstevel@tonic-gate  * 'lbflips' Fcode implementation.
9580Sstevel@tonic-gate  */
9590Sstevel@tonic-gate static void
lbflips(fcode_env_t * env)9600Sstevel@tonic-gate lbflips(fcode_env_t *env)
9610Sstevel@tonic-gate {
9620Sstevel@tonic-gate 	fstack_t len, addr;
9630Sstevel@tonic-gate 	int i;
9640Sstevel@tonic-gate 
9650Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "lbflips");
9660Sstevel@tonic-gate 	len = POP(DS);
9670Sstevel@tonic-gate 	addr = POP(DS);
9680Sstevel@tonic-gate 	for (i = 0; i < len; i += sizeof (lforth_t),
9690Sstevel@tonic-gate 	    addr += sizeof (lforth_t)) {
9700Sstevel@tonic-gate 		PUSH(DS, addr);
9710Sstevel@tonic-gate 		unaligned_lfetch(env);
9720Sstevel@tonic-gate 		lbflip(env);
9730Sstevel@tonic-gate 		PUSH(DS, addr);
9740Sstevel@tonic-gate 		unaligned_lstore(env);
9750Sstevel@tonic-gate 	}
9760Sstevel@tonic-gate }
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate /*
9790Sstevel@tonic-gate  * 'wbflips' Fcode implementation.
9800Sstevel@tonic-gate  */
9810Sstevel@tonic-gate static void
wbflips(fcode_env_t * env)9820Sstevel@tonic-gate wbflips(fcode_env_t *env)
9830Sstevel@tonic-gate {
9840Sstevel@tonic-gate 	fstack_t len, addr;
9850Sstevel@tonic-gate 	int i;
9860Sstevel@tonic-gate 
9870Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "wbflips");
9880Sstevel@tonic-gate 	len = POP(DS);
9890Sstevel@tonic-gate 	addr = POP(DS);
9900Sstevel@tonic-gate 	for (i = 0; i < len; i += sizeof (wforth_t),
9910Sstevel@tonic-gate 	    addr += sizeof (wforth_t)) {
9920Sstevel@tonic-gate 		PUSH(DS, addr);
9930Sstevel@tonic-gate 		unaligned_wfetch(env);
9940Sstevel@tonic-gate 		wbflip(env);
9950Sstevel@tonic-gate 		PUSH(DS, addr);
9960Sstevel@tonic-gate 		unaligned_wstore(env);
9970Sstevel@tonic-gate 	}
9980Sstevel@tonic-gate }
9990Sstevel@tonic-gate 
10000Sstevel@tonic-gate /*
10010Sstevel@tonic-gate  * 'lwflips' Fcode implementation.
10020Sstevel@tonic-gate  */
10030Sstevel@tonic-gate static void
lwflips(fcode_env_t * env)10040Sstevel@tonic-gate lwflips(fcode_env_t *env)
10050Sstevel@tonic-gate {
10060Sstevel@tonic-gate 	fstack_t len, addr;
10070Sstevel@tonic-gate 	int i;
10080Sstevel@tonic-gate 
10090Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "lwflips");
10100Sstevel@tonic-gate 	len = POP(DS);
10110Sstevel@tonic-gate 	addr = POP(DS);
10120Sstevel@tonic-gate 	for (i = 0; i < len; i += sizeof (lforth_t),
10130Sstevel@tonic-gate 	    addr += sizeof (lforth_t)) {
10140Sstevel@tonic-gate 		PUSH(DS, addr);
10150Sstevel@tonic-gate 		unaligned_lfetch(env);
10160Sstevel@tonic-gate 		lwflip(env);
10170Sstevel@tonic-gate 		PUSH(DS, addr);
10180Sstevel@tonic-gate 		unaligned_lstore(env);
10190Sstevel@tonic-gate 	}
10200Sstevel@tonic-gate }
10210Sstevel@tonic-gate 
10220Sstevel@tonic-gate void
base(fcode_env_t * env)10230Sstevel@tonic-gate base(fcode_env_t *env)
10240Sstevel@tonic-gate {
10250Sstevel@tonic-gate 	PUSH(DS, (fstack_t)&env->num_base);
10260Sstevel@tonic-gate }
10270Sstevel@tonic-gate 
10280Sstevel@tonic-gate void
dot_s(fcode_env_t * env)10290Sstevel@tonic-gate dot_s(fcode_env_t *env)
10300Sstevel@tonic-gate {
10310Sstevel@tonic-gate 	output_data_stack(env, MSG_INFO);
10320Sstevel@tonic-gate }
10330Sstevel@tonic-gate 
10340Sstevel@tonic-gate void
state(fcode_env_t * env)10350Sstevel@tonic-gate state(fcode_env_t *env)
10360Sstevel@tonic-gate {
10370Sstevel@tonic-gate 	PUSH(DS, (fstack_t)&env->state);
10380Sstevel@tonic-gate }
10390Sstevel@tonic-gate 
10400Sstevel@tonic-gate int
is_digit(char digit,int num_base,fstack_t * dptr)10410Sstevel@tonic-gate is_digit(char digit, int num_base, fstack_t *dptr)
10420Sstevel@tonic-gate {
10430Sstevel@tonic-gate 	int error = 0;
10440Sstevel@tonic-gate 	char base;
10450Sstevel@tonic-gate 
10460Sstevel@tonic-gate 	if (num_base < 10) {
10470Sstevel@tonic-gate 		base = '0' + (num_base-1);
10480Sstevel@tonic-gate 	} else {
10490Sstevel@tonic-gate 		base = 'a' + (num_base - 10);
10500Sstevel@tonic-gate 	}
10510Sstevel@tonic-gate 
10520Sstevel@tonic-gate 	*dptr = 0;
10530Sstevel@tonic-gate 	if (digit > '9') digit |= 0x20;
10540Sstevel@tonic-gate 	if (((digit < '0') || (digit > base)) ||
10550Sstevel@tonic-gate 	    ((digit > '9') && (digit < 'a') && (num_base > 10)))
10560Sstevel@tonic-gate 		error = 1;
10570Sstevel@tonic-gate 	else {
10580Sstevel@tonic-gate 		if (digit <= '9')
10590Sstevel@tonic-gate 			digit -= '0';
10600Sstevel@tonic-gate 		else
10610Sstevel@tonic-gate 			digit = digit - 'a' + 10;
10620Sstevel@tonic-gate 		*dptr = digit;
10630Sstevel@tonic-gate 	}
10640Sstevel@tonic-gate 	return (error);
10650Sstevel@tonic-gate }
10660Sstevel@tonic-gate 
10670Sstevel@tonic-gate void
dollar_number(fcode_env_t * env)10680Sstevel@tonic-gate dollar_number(fcode_env_t *env)
10690Sstevel@tonic-gate {
10700Sstevel@tonic-gate 	char *buf;
10710Sstevel@tonic-gate 	fstack_t value;
10720Sstevel@tonic-gate 	int len, sign = 1, error = 0;
10730Sstevel@tonic-gate 
10740Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "$number");
10750Sstevel@tonic-gate 	buf = pop_a_string(env, &len);
10760Sstevel@tonic-gate 	if (*buf == '-') {
10770Sstevel@tonic-gate 		sign = -1;
10780Sstevel@tonic-gate 		buf++;
10790Sstevel@tonic-gate 		len--;
10800Sstevel@tonic-gate 	}
10810Sstevel@tonic-gate 	value = 0;
10820Sstevel@tonic-gate 	while (len-- && !error) {
10830Sstevel@tonic-gate 		fstack_t digit;
10840Sstevel@tonic-gate 
10850Sstevel@tonic-gate 		if (*buf == '.') {
10860Sstevel@tonic-gate 			buf++;
10870Sstevel@tonic-gate 			continue;
10880Sstevel@tonic-gate 		}
10890Sstevel@tonic-gate 		value *= env->num_base;
10900Sstevel@tonic-gate 		error = is_digit(*buf++, env->num_base, &digit);
10910Sstevel@tonic-gate 		value += digit;
10920Sstevel@tonic-gate 	}
10930Sstevel@tonic-gate 	if (error) {
10940Sstevel@tonic-gate 		PUSH(DS, -1);
10950Sstevel@tonic-gate 	} else {
10960Sstevel@tonic-gate 		value *= sign;
10970Sstevel@tonic-gate 		PUSH(DS, value);
10980Sstevel@tonic-gate 		PUSH(DS, 0);
10990Sstevel@tonic-gate 	}
11000Sstevel@tonic-gate }
11010Sstevel@tonic-gate 
11020Sstevel@tonic-gate void
digit(fcode_env_t * env)11030Sstevel@tonic-gate digit(fcode_env_t *env)
11040Sstevel@tonic-gate {
11050Sstevel@tonic-gate 	fstack_t base;
11060Sstevel@tonic-gate 	fstack_t value;
11070Sstevel@tonic-gate 
11080Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "digit");
11090Sstevel@tonic-gate 	base = POP(DS);
11100Sstevel@tonic-gate 	if (is_digit(TOS, base, &value))
11110Sstevel@tonic-gate 		PUSH(DS, 0);
11120Sstevel@tonic-gate 	else {
11130Sstevel@tonic-gate 		TOS = value;
11140Sstevel@tonic-gate 		PUSH(DS, -1);
11150Sstevel@tonic-gate 	}
11160Sstevel@tonic-gate }
11170Sstevel@tonic-gate 
11180Sstevel@tonic-gate void
space(fcode_env_t * env)11190Sstevel@tonic-gate space(fcode_env_t *env)
11200Sstevel@tonic-gate {
11210Sstevel@tonic-gate 	PUSH(DS, ' ');
11220Sstevel@tonic-gate }
11230Sstevel@tonic-gate 
11240Sstevel@tonic-gate void
backspace(fcode_env_t * env)11250Sstevel@tonic-gate backspace(fcode_env_t *env)
11260Sstevel@tonic-gate {
11270Sstevel@tonic-gate 	PUSH(DS, '\b');
11280Sstevel@tonic-gate }
11290Sstevel@tonic-gate 
11300Sstevel@tonic-gate void
bell(fcode_env_t * env)11310Sstevel@tonic-gate bell(fcode_env_t *env)
11320Sstevel@tonic-gate {
11330Sstevel@tonic-gate 	PUSH(DS, '\a');
11340Sstevel@tonic-gate }
11350Sstevel@tonic-gate 
11360Sstevel@tonic-gate void
fc_bounds(fcode_env_t * env)11370Sstevel@tonic-gate fc_bounds(fcode_env_t *env)
11380Sstevel@tonic-gate {
11390Sstevel@tonic-gate 	fstack_t lo, hi;
11400Sstevel@tonic-gate 
11410Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "bounds");
11420Sstevel@tonic-gate 	lo = DS[-1];
11430Sstevel@tonic-gate 	hi = TOS;
11440Sstevel@tonic-gate 	DS[-1] = lo+hi;
11450Sstevel@tonic-gate 	TOS = lo;
11460Sstevel@tonic-gate }
11470Sstevel@tonic-gate 
11480Sstevel@tonic-gate void
here(fcode_env_t * env)11490Sstevel@tonic-gate here(fcode_env_t *env)
11500Sstevel@tonic-gate {
11510Sstevel@tonic-gate 	PUSH(DS, (fstack_t)HERE);
11520Sstevel@tonic-gate }
11530Sstevel@tonic-gate 
11540Sstevel@tonic-gate void
aligned(fcode_env_t * env)11550Sstevel@tonic-gate aligned(fcode_env_t *env)
11560Sstevel@tonic-gate {
11570Sstevel@tonic-gate 	ufstack_t a;
11580Sstevel@tonic-gate 
11590Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "aligned");
11600Sstevel@tonic-gate 	a = (TOS & (sizeof (lforth_t) - 1));
11610Sstevel@tonic-gate 	if (a)
11620Sstevel@tonic-gate 		TOS += (sizeof (lforth_t) - a);
11630Sstevel@tonic-gate }
11640Sstevel@tonic-gate 
11650Sstevel@tonic-gate void
instance(fcode_env_t * env)11660Sstevel@tonic-gate instance(fcode_env_t *env)
11670Sstevel@tonic-gate {
11680Sstevel@tonic-gate 	env->instance_mode |= 1;
11690Sstevel@tonic-gate }
11700Sstevel@tonic-gate 
11710Sstevel@tonic-gate void
semi(fcode_env_t * env)11720Sstevel@tonic-gate semi(fcode_env_t *env)
11730Sstevel@tonic-gate {
11740Sstevel@tonic-gate 
11750Sstevel@tonic-gate 	env->state &= ~1;
11760Sstevel@tonic-gate 	COMPILE_TOKEN(&semi_ptr);
11770Sstevel@tonic-gate 
11780Sstevel@tonic-gate 	/*
11790Sstevel@tonic-gate 	 * check if we need to supress expose action;
11800Sstevel@tonic-gate 	 * If so this is an internal word and has no link field
11810Sstevel@tonic-gate 	 * or it is a temporary compile
11820Sstevel@tonic-gate 	 */
11830Sstevel@tonic-gate 
11840Sstevel@tonic-gate 	if (env->state == 0) {
11850Sstevel@tonic-gate 		expose_acf(env, "<semi>");
11860Sstevel@tonic-gate 	}
11870Sstevel@tonic-gate 	if (env->state & 8) {
11880Sstevel@tonic-gate 		env->state ^= 8;
11890Sstevel@tonic-gate 	}
11900Sstevel@tonic-gate }
11910Sstevel@tonic-gate 
11920Sstevel@tonic-gate void
do_create(fcode_env_t * env)11930Sstevel@tonic-gate do_create(fcode_env_t *env)
11940Sstevel@tonic-gate {
11950Sstevel@tonic-gate 	PUSH(DS, (fstack_t)WA);
11960Sstevel@tonic-gate }
11970Sstevel@tonic-gate 
11980Sstevel@tonic-gate void
drop(fcode_env_t * env)11990Sstevel@tonic-gate drop(fcode_env_t *env)
12000Sstevel@tonic-gate {
12010Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "drop");
12020Sstevel@tonic-gate 	(void) POP(DS);
12030Sstevel@tonic-gate }
12040Sstevel@tonic-gate 
12050Sstevel@tonic-gate void
f_dup(fcode_env_t * env)12060Sstevel@tonic-gate f_dup(fcode_env_t *env)
12070Sstevel@tonic-gate {
12080Sstevel@tonic-gate 	fstack_t d;
12090Sstevel@tonic-gate 
12100Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "dup");
12110Sstevel@tonic-gate 	d = TOS;
12120Sstevel@tonic-gate 	PUSH(DS, d);
12130Sstevel@tonic-gate }
12140Sstevel@tonic-gate 
12150Sstevel@tonic-gate void
over(fcode_env_t * env)12160Sstevel@tonic-gate over(fcode_env_t *env)
12170Sstevel@tonic-gate {
12180Sstevel@tonic-gate 	fstack_t d;
12190Sstevel@tonic-gate 
12200Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "over");
12210Sstevel@tonic-gate 	d = DS[-1];
12220Sstevel@tonic-gate 	PUSH(DS, d);
12230Sstevel@tonic-gate }
12240Sstevel@tonic-gate 
12250Sstevel@tonic-gate void
swap(fcode_env_t * env)12260Sstevel@tonic-gate swap(fcode_env_t *env)
12270Sstevel@tonic-gate {
12280Sstevel@tonic-gate 	fstack_t d;
12290Sstevel@tonic-gate 
12300Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "swap");
12310Sstevel@tonic-gate 	d = DS[-1];
12320Sstevel@tonic-gate 	DS[-1] = DS[0];
12330Sstevel@tonic-gate 	DS[0]  = d;
12340Sstevel@tonic-gate }
12350Sstevel@tonic-gate 
12360Sstevel@tonic-gate 
12370Sstevel@tonic-gate void
rot(fcode_env_t * env)12380Sstevel@tonic-gate rot(fcode_env_t *env)
12390Sstevel@tonic-gate {
12400Sstevel@tonic-gate 	fstack_t d;
12410Sstevel@tonic-gate 
12420Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "rot");
12430Sstevel@tonic-gate 	d = DS[-2];
12440Sstevel@tonic-gate 	DS[-2] = DS[-1];
12450Sstevel@tonic-gate 	DS[-1] = TOS;
12460Sstevel@tonic-gate 	TOS    = d;
12470Sstevel@tonic-gate }
12480Sstevel@tonic-gate 
12490Sstevel@tonic-gate void
minus_rot(fcode_env_t * env)12500Sstevel@tonic-gate minus_rot(fcode_env_t *env)
12510Sstevel@tonic-gate {
12520Sstevel@tonic-gate 	fstack_t d;
12530Sstevel@tonic-gate 
12540Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "-rot");
12550Sstevel@tonic-gate 	d = TOS;
12560Sstevel@tonic-gate 	TOS    = DS[-1];
12570Sstevel@tonic-gate 	DS[-1] = DS[-2];
12580Sstevel@tonic-gate 	DS[-2] = d;
12590Sstevel@tonic-gate }
12600Sstevel@tonic-gate 
12610Sstevel@tonic-gate void
tuck(fcode_env_t * env)12620Sstevel@tonic-gate tuck(fcode_env_t *env)
12630Sstevel@tonic-gate {
12640Sstevel@tonic-gate 	fstack_t d;
12650Sstevel@tonic-gate 
12660Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "tuck");
12670Sstevel@tonic-gate 	d = TOS;
12680Sstevel@tonic-gate 	swap(env);
12690Sstevel@tonic-gate 	PUSH(DS, d);
12700Sstevel@tonic-gate }
12710Sstevel@tonic-gate 
12720Sstevel@tonic-gate void
nip(fcode_env_t * env)12730Sstevel@tonic-gate nip(fcode_env_t *env)
12740Sstevel@tonic-gate {
12750Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "nip");
12760Sstevel@tonic-gate 	swap(env);
12770Sstevel@tonic-gate 	drop(env);
12780Sstevel@tonic-gate }
12790Sstevel@tonic-gate 
12800Sstevel@tonic-gate void
qdup(fcode_env_t * env)12810Sstevel@tonic-gate qdup(fcode_env_t *env)
12820Sstevel@tonic-gate {
12830Sstevel@tonic-gate 	fstack_t d;
12840Sstevel@tonic-gate 
12850Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "?dup");
12860Sstevel@tonic-gate 	d = TOS;
12870Sstevel@tonic-gate 	if (d)
12880Sstevel@tonic-gate 		PUSH(DS, d);
12890Sstevel@tonic-gate }
12900Sstevel@tonic-gate 
12910Sstevel@tonic-gate void
depth(fcode_env_t * env)12920Sstevel@tonic-gate depth(fcode_env_t *env)
12930Sstevel@tonic-gate {
12940Sstevel@tonic-gate 	fstack_t d;
12950Sstevel@tonic-gate 
12960Sstevel@tonic-gate 	d =  DS - env->ds0;
12970Sstevel@tonic-gate 	PUSH(DS, d);
12980Sstevel@tonic-gate }
12990Sstevel@tonic-gate 
13000Sstevel@tonic-gate void
pick(fcode_env_t * env)13010Sstevel@tonic-gate pick(fcode_env_t *env)
13020Sstevel@tonic-gate {
13030Sstevel@tonic-gate 	fstack_t p;
13040Sstevel@tonic-gate 
13050Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "pick");
13060Sstevel@tonic-gate 	p = POP(DS);
13070Sstevel@tonic-gate 	if (p < 0 || p >= (env->ds - env->ds0))
13080Sstevel@tonic-gate 		forth_abort(env, "pick: invalid pick value: %d\n", (int)p);
13090Sstevel@tonic-gate 	p = DS[-p];
13100Sstevel@tonic-gate 	PUSH(DS, p);
13110Sstevel@tonic-gate }
13120Sstevel@tonic-gate 
13130Sstevel@tonic-gate void
roll(fcode_env_t * env)13140Sstevel@tonic-gate roll(fcode_env_t *env)
13150Sstevel@tonic-gate {
13160Sstevel@tonic-gate 	fstack_t d, r;
13170Sstevel@tonic-gate 
13180Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "roll");
13190Sstevel@tonic-gate 	r = POP(DS);
13200Sstevel@tonic-gate 	if (r <= 0 || r >= (env->ds - env->ds0))
13210Sstevel@tonic-gate 		forth_abort(env, "roll: invalid roll value: %d\n", (int)r);
13220Sstevel@tonic-gate 
13230Sstevel@tonic-gate 	d = DS[-r];
13240Sstevel@tonic-gate 	while (r) {
13250Sstevel@tonic-gate 		DS[-r] = DS[ -(r-1) ];
13260Sstevel@tonic-gate 		r--;
13270Sstevel@tonic-gate 	}
13280Sstevel@tonic-gate 	TOS = d;
13290Sstevel@tonic-gate }
13300Sstevel@tonic-gate 
13310Sstevel@tonic-gate void
two_drop(fcode_env_t * env)13320Sstevel@tonic-gate two_drop(fcode_env_t *env)
13330Sstevel@tonic-gate {
13340Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "2drop");
13350Sstevel@tonic-gate 	DS -= 2;
13360Sstevel@tonic-gate }
13370Sstevel@tonic-gate 
13380Sstevel@tonic-gate void
two_dup(fcode_env_t * env)13390Sstevel@tonic-gate two_dup(fcode_env_t *env)
13400Sstevel@tonic-gate {
13410Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "2dup");
13420Sstevel@tonic-gate 	DS[1] = DS[-1];
13430Sstevel@tonic-gate 	DS[2] = TOS;
13440Sstevel@tonic-gate 	DS += 2;
13450Sstevel@tonic-gate }
13460Sstevel@tonic-gate 
13470Sstevel@tonic-gate void
two_over(fcode_env_t * env)13480Sstevel@tonic-gate two_over(fcode_env_t *env)
13490Sstevel@tonic-gate {
13500Sstevel@tonic-gate 	fstack_t a, b;
13510Sstevel@tonic-gate 
13520Sstevel@tonic-gate 	CHECK_DEPTH(env, 4, "2over");
13530Sstevel@tonic-gate 	a = DS[-3];
13540Sstevel@tonic-gate 	b = DS[-2];
13550Sstevel@tonic-gate 	PUSH(DS, a);
13560Sstevel@tonic-gate 	PUSH(DS, b);
13570Sstevel@tonic-gate }
13580Sstevel@tonic-gate 
13590Sstevel@tonic-gate void
two_swap(fcode_env_t * env)13600Sstevel@tonic-gate two_swap(fcode_env_t *env)
13610Sstevel@tonic-gate {
13620Sstevel@tonic-gate 	fstack_t a, b;
13630Sstevel@tonic-gate 
13640Sstevel@tonic-gate 	CHECK_DEPTH(env, 4, "2swap");
13650Sstevel@tonic-gate 	a = DS[-3];
13660Sstevel@tonic-gate 	b = DS[-2];
13670Sstevel@tonic-gate 	DS[-3] = DS[-1];
13680Sstevel@tonic-gate 	DS[-2] = TOS;
13690Sstevel@tonic-gate 	DS[-1] = a;
13700Sstevel@tonic-gate 	TOS    = b;
13710Sstevel@tonic-gate }
13720Sstevel@tonic-gate 
13730Sstevel@tonic-gate void
two_rot(fcode_env_t * env)13740Sstevel@tonic-gate two_rot(fcode_env_t *env)
13750Sstevel@tonic-gate {
13760Sstevel@tonic-gate 	fstack_t a, b;
13770Sstevel@tonic-gate 
13780Sstevel@tonic-gate 	CHECK_DEPTH(env, 6, "2rot");
13790Sstevel@tonic-gate 	a = DS[-5];
13800Sstevel@tonic-gate 	b = DS[-4];
13810Sstevel@tonic-gate 	DS[-5] = DS[-3];
13820Sstevel@tonic-gate 	DS[-4] = DS[-2];
13830Sstevel@tonic-gate 	DS[-3] = DS[-1];
13840Sstevel@tonic-gate 	DS[-2] = TOS;
13850Sstevel@tonic-gate 	DS[-1] = a;
13860Sstevel@tonic-gate 	TOS    = b;
13870Sstevel@tonic-gate }
13880Sstevel@tonic-gate 
13890Sstevel@tonic-gate void
two_slash(fcode_env_t * env)13900Sstevel@tonic-gate two_slash(fcode_env_t *env)
13910Sstevel@tonic-gate {
13920Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "2/");
13930Sstevel@tonic-gate 	TOS = TOS >> 1;
13940Sstevel@tonic-gate }
13950Sstevel@tonic-gate 
13960Sstevel@tonic-gate void
utwo_slash(fcode_env_t * env)13970Sstevel@tonic-gate utwo_slash(fcode_env_t *env)
13980Sstevel@tonic-gate {
13990Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "u2/");
14000Sstevel@tonic-gate 	TOS = (ufstack_t)((ufstack_t)TOS) >> 1;
14010Sstevel@tonic-gate }
14020Sstevel@tonic-gate 
14030Sstevel@tonic-gate void
two_times(fcode_env_t * env)14040Sstevel@tonic-gate two_times(fcode_env_t *env)
14050Sstevel@tonic-gate {
14060Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "2*");
14070Sstevel@tonic-gate 	TOS = (ufstack_t)((ufstack_t)TOS) << 1;
14080Sstevel@tonic-gate }
14090Sstevel@tonic-gate 
14100Sstevel@tonic-gate void
slash_c(fcode_env_t * env)14110Sstevel@tonic-gate slash_c(fcode_env_t *env)
14120Sstevel@tonic-gate {
14130Sstevel@tonic-gate 	PUSH(DS, sizeof (char));
14140Sstevel@tonic-gate }
14150Sstevel@tonic-gate 
14160Sstevel@tonic-gate void
slash_w(fcode_env_t * env)14170Sstevel@tonic-gate slash_w(fcode_env_t *env)
14180Sstevel@tonic-gate {
14190Sstevel@tonic-gate 	PUSH(DS, sizeof (wforth_t));
14200Sstevel@tonic-gate }
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate void
slash_l(fcode_env_t * env)14230Sstevel@tonic-gate slash_l(fcode_env_t *env)
14240Sstevel@tonic-gate {
14250Sstevel@tonic-gate 	PUSH(DS, sizeof (lforth_t));
14260Sstevel@tonic-gate }
14270Sstevel@tonic-gate 
14280Sstevel@tonic-gate void
slash_n(fcode_env_t * env)14290Sstevel@tonic-gate slash_n(fcode_env_t *env)
14300Sstevel@tonic-gate {
14310Sstevel@tonic-gate 	PUSH(DS, sizeof (fstack_t));
14320Sstevel@tonic-gate }
14330Sstevel@tonic-gate 
14340Sstevel@tonic-gate void
ca_plus(fcode_env_t * env)14350Sstevel@tonic-gate ca_plus(fcode_env_t *env)
14360Sstevel@tonic-gate {
14370Sstevel@tonic-gate 	fstack_t d;
14380Sstevel@tonic-gate 
14390Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "ca+");
14400Sstevel@tonic-gate 	d = POP(DS);
14410Sstevel@tonic-gate 	TOS += d * sizeof (char);
14420Sstevel@tonic-gate }
14430Sstevel@tonic-gate 
14440Sstevel@tonic-gate void
wa_plus(fcode_env_t * env)14450Sstevel@tonic-gate wa_plus(fcode_env_t *env)
14460Sstevel@tonic-gate {
14470Sstevel@tonic-gate 	fstack_t d;
14480Sstevel@tonic-gate 
14490Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "wa+");
14500Sstevel@tonic-gate 	d = POP(DS);
14510Sstevel@tonic-gate 	TOS += d * sizeof (wforth_t);
14520Sstevel@tonic-gate }
14530Sstevel@tonic-gate 
14540Sstevel@tonic-gate void
la_plus(fcode_env_t * env)14550Sstevel@tonic-gate la_plus(fcode_env_t *env)
14560Sstevel@tonic-gate {
14570Sstevel@tonic-gate 	fstack_t d;
14580Sstevel@tonic-gate 
14590Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "la+");
14600Sstevel@tonic-gate 	d = POP(DS);
14610Sstevel@tonic-gate 	TOS += d * sizeof (lforth_t);
14620Sstevel@tonic-gate }
14630Sstevel@tonic-gate 
14640Sstevel@tonic-gate void
na_plus(fcode_env_t * env)14650Sstevel@tonic-gate na_plus(fcode_env_t *env)
14660Sstevel@tonic-gate {
14670Sstevel@tonic-gate 	fstack_t d;
14680Sstevel@tonic-gate 
14690Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "na+");
14700Sstevel@tonic-gate 	d = POP(DS);
14710Sstevel@tonic-gate 	TOS += d * sizeof (fstack_t);
14720Sstevel@tonic-gate }
14730Sstevel@tonic-gate 
14740Sstevel@tonic-gate void
char_plus(fcode_env_t * env)14750Sstevel@tonic-gate char_plus(fcode_env_t *env)
14760Sstevel@tonic-gate {
14770Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "char+");
14780Sstevel@tonic-gate 	TOS += sizeof (char);
14790Sstevel@tonic-gate }
14800Sstevel@tonic-gate 
14810Sstevel@tonic-gate void
wa1_plus(fcode_env_t * env)14820Sstevel@tonic-gate wa1_plus(fcode_env_t *env)
14830Sstevel@tonic-gate {
14840Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "wa1+");
14850Sstevel@tonic-gate 	TOS += sizeof (wforth_t);
14860Sstevel@tonic-gate }
14870Sstevel@tonic-gate 
14880Sstevel@tonic-gate void
la1_plus(fcode_env_t * env)14890Sstevel@tonic-gate la1_plus(fcode_env_t *env)
14900Sstevel@tonic-gate {
14910Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "la1+");
14920Sstevel@tonic-gate 	TOS += sizeof (lforth_t);
14930Sstevel@tonic-gate }
14940Sstevel@tonic-gate 
14950Sstevel@tonic-gate void
cell_plus(fcode_env_t * env)14960Sstevel@tonic-gate cell_plus(fcode_env_t *env)
14970Sstevel@tonic-gate {
14980Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "cell+");
14990Sstevel@tonic-gate 	TOS += sizeof (fstack_t);
15000Sstevel@tonic-gate }
15010Sstevel@tonic-gate 
15020Sstevel@tonic-gate void
do_chars(fcode_env_t * env)15030Sstevel@tonic-gate do_chars(fcode_env_t *env)
15040Sstevel@tonic-gate {
15050Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "chars");
15060Sstevel@tonic-gate }
15070Sstevel@tonic-gate 
15080Sstevel@tonic-gate void
slash_w_times(fcode_env_t * env)15090Sstevel@tonic-gate slash_w_times(fcode_env_t *env)
15100Sstevel@tonic-gate {
15110Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "/w*");
15120Sstevel@tonic-gate 	TOS *= sizeof (wforth_t);
15130Sstevel@tonic-gate }
15140Sstevel@tonic-gate 
15150Sstevel@tonic-gate void
slash_l_times(fcode_env_t * env)15160Sstevel@tonic-gate slash_l_times(fcode_env_t *env)
15170Sstevel@tonic-gate {
15180Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "/l*");
15190Sstevel@tonic-gate 	TOS *= sizeof (lforth_t);
15200Sstevel@tonic-gate }
15210Sstevel@tonic-gate 
15220Sstevel@tonic-gate void
cells(fcode_env_t * env)15230Sstevel@tonic-gate cells(fcode_env_t *env)
15240Sstevel@tonic-gate {
15250Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "cells");
15260Sstevel@tonic-gate 	TOS *= sizeof (fstack_t);
15270Sstevel@tonic-gate }
15280Sstevel@tonic-gate 
15290Sstevel@tonic-gate void
do_on(fcode_env_t * env)15300Sstevel@tonic-gate do_on(fcode_env_t *env)
15310Sstevel@tonic-gate {
15320Sstevel@tonic-gate 	variable_t *d;
15330Sstevel@tonic-gate 
15340Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "on");
15350Sstevel@tonic-gate 	d = (variable_t *)POP(DS);
15360Sstevel@tonic-gate 	*d = -1;
15370Sstevel@tonic-gate }
15380Sstevel@tonic-gate 
15390Sstevel@tonic-gate void
do_off(fcode_env_t * env)15400Sstevel@tonic-gate do_off(fcode_env_t *env)
15410Sstevel@tonic-gate {
15420Sstevel@tonic-gate 	variable_t *d;
15430Sstevel@tonic-gate 
15440Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "off");
15450Sstevel@tonic-gate 	d = (variable_t *)POP(DS);
15460Sstevel@tonic-gate 	*d = 0;
15470Sstevel@tonic-gate }
15480Sstevel@tonic-gate 
15490Sstevel@tonic-gate void
fetch(fcode_env_t * env)15500Sstevel@tonic-gate fetch(fcode_env_t *env)
15510Sstevel@tonic-gate {
15520Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "@");
15530Sstevel@tonic-gate 	TOS = *((variable_t *)TOS);
15540Sstevel@tonic-gate }
15550Sstevel@tonic-gate 
15560Sstevel@tonic-gate void
lfetch(fcode_env_t * env)15570Sstevel@tonic-gate lfetch(fcode_env_t *env)
15580Sstevel@tonic-gate {
15590Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "l@");
15600Sstevel@tonic-gate 	TOS = *((lforth_t *)TOS);
15610Sstevel@tonic-gate }
15620Sstevel@tonic-gate 
15630Sstevel@tonic-gate void
wfetch(fcode_env_t * env)15640Sstevel@tonic-gate wfetch(fcode_env_t *env)
15650Sstevel@tonic-gate {
15660Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "w@");
15670Sstevel@tonic-gate 	TOS = *((wforth_t *)TOS);
15680Sstevel@tonic-gate }
15690Sstevel@tonic-gate 
15700Sstevel@tonic-gate void
swfetch(fcode_env_t * env)15710Sstevel@tonic-gate swfetch(fcode_env_t *env)
15720Sstevel@tonic-gate {
15730Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "<w@");
15740Sstevel@tonic-gate 	TOS = *((s_wforth_t *)TOS);
15750Sstevel@tonic-gate }
15760Sstevel@tonic-gate 
15770Sstevel@tonic-gate void
cfetch(fcode_env_t * env)15780Sstevel@tonic-gate cfetch(fcode_env_t *env)
15790Sstevel@tonic-gate {
15800Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "c@");
15810Sstevel@tonic-gate 	TOS = *((uchar_t *)TOS);
15820Sstevel@tonic-gate }
15830Sstevel@tonic-gate 
15840Sstevel@tonic-gate void
store(fcode_env_t * env)15850Sstevel@tonic-gate store(fcode_env_t *env)
15860Sstevel@tonic-gate {
15870Sstevel@tonic-gate 	variable_t *dptr;
15880Sstevel@tonic-gate 
15890Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "!");
15900Sstevel@tonic-gate 	dptr = (variable_t *)POP(DS);
15910Sstevel@tonic-gate 	*dptr = POP(DS);
15920Sstevel@tonic-gate }
15930Sstevel@tonic-gate 
15940Sstevel@tonic-gate void
addstore(fcode_env_t * env)15950Sstevel@tonic-gate addstore(fcode_env_t *env)
15960Sstevel@tonic-gate {
15970Sstevel@tonic-gate 	variable_t *dptr;
15980Sstevel@tonic-gate 
15990Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "+!");
16000Sstevel@tonic-gate 	dptr = (variable_t *)POP(DS);
16010Sstevel@tonic-gate 	*dptr = POP(DS) + *dptr;
16020Sstevel@tonic-gate }
16030Sstevel@tonic-gate 
16040Sstevel@tonic-gate void
lstore(fcode_env_t * env)16050Sstevel@tonic-gate lstore(fcode_env_t *env)
16060Sstevel@tonic-gate {
16070Sstevel@tonic-gate 	lforth_t *dptr;
16080Sstevel@tonic-gate 
16090Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "l!");
16100Sstevel@tonic-gate 	dptr = (lforth_t *)POP(DS);
16110Sstevel@tonic-gate 	*dptr = (lforth_t)POP(DS);
16120Sstevel@tonic-gate }
16130Sstevel@tonic-gate 
16140Sstevel@tonic-gate void
wstore(fcode_env_t * env)16150Sstevel@tonic-gate wstore(fcode_env_t *env)
16160Sstevel@tonic-gate {
16170Sstevel@tonic-gate 	wforth_t *dptr;
16180Sstevel@tonic-gate 
16190Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "w!");
16200Sstevel@tonic-gate 	dptr = (wforth_t *)POP(DS);
16210Sstevel@tonic-gate 	*dptr = (wforth_t)POP(DS);
16220Sstevel@tonic-gate }
16230Sstevel@tonic-gate 
16240Sstevel@tonic-gate void
cstore(fcode_env_t * env)16250Sstevel@tonic-gate cstore(fcode_env_t *env)
16260Sstevel@tonic-gate {
16270Sstevel@tonic-gate 	uchar_t *dptr;
16280Sstevel@tonic-gate 
16290Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "c!");
16300Sstevel@tonic-gate 	dptr = (uchar_t *)POP(DS);
16310Sstevel@tonic-gate 	*dptr = (uchar_t)POP(DS);
16320Sstevel@tonic-gate }
16330Sstevel@tonic-gate 
16340Sstevel@tonic-gate void
two_fetch(fcode_env_t * env)16350Sstevel@tonic-gate two_fetch(fcode_env_t *env)
16360Sstevel@tonic-gate {
16370Sstevel@tonic-gate 	variable_t *d;
16380Sstevel@tonic-gate 
16390Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "2@");
16400Sstevel@tonic-gate 	d = (variable_t *)POP(DS);
16410Sstevel@tonic-gate 	PUSH(DS, (fstack_t)(d + 1));
16420Sstevel@tonic-gate 	unaligned_fetch(env);
16430Sstevel@tonic-gate 	PUSH(DS, (fstack_t)d);
16440Sstevel@tonic-gate 	unaligned_fetch(env);
16450Sstevel@tonic-gate }
16460Sstevel@tonic-gate 
16470Sstevel@tonic-gate void
two_store(fcode_env_t * env)16480Sstevel@tonic-gate two_store(fcode_env_t *env)
16490Sstevel@tonic-gate {
16500Sstevel@tonic-gate 	variable_t *d;
16510Sstevel@tonic-gate 
16520Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "2!");
16530Sstevel@tonic-gate 	d = (variable_t *)POP(DS);
16540Sstevel@tonic-gate 	PUSH(DS, (fstack_t)d);
16550Sstevel@tonic-gate 	unaligned_store(env);
16560Sstevel@tonic-gate 	PUSH(DS, (fstack_t)(d + 1));
16570Sstevel@tonic-gate 	unaligned_store(env);
16580Sstevel@tonic-gate }
16590Sstevel@tonic-gate 
16600Sstevel@tonic-gate /*
16610Sstevel@tonic-gate  * 'move' Fcode reimplemented in fcdriver to check for mapped addresses.
16620Sstevel@tonic-gate  */
16630Sstevel@tonic-gate void
fc_move(fcode_env_t * env)16640Sstevel@tonic-gate fc_move(fcode_env_t *env)
16650Sstevel@tonic-gate {
16660Sstevel@tonic-gate 	void *dest, *src;
16670Sstevel@tonic-gate 	size_t len;
16680Sstevel@tonic-gate 
16690Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "move");
16700Sstevel@tonic-gate 	len  = (size_t)POP(DS);
16710Sstevel@tonic-gate 	dest = (void *)POP(DS);
16720Sstevel@tonic-gate 	src  = (void *)POP(DS);
16730Sstevel@tonic-gate 
16740Sstevel@tonic-gate 	memmove(dest, src, len);
16750Sstevel@tonic-gate }
16760Sstevel@tonic-gate 
16770Sstevel@tonic-gate void
fc_fill(fcode_env_t * env)16780Sstevel@tonic-gate fc_fill(fcode_env_t *env)
16790Sstevel@tonic-gate {
16800Sstevel@tonic-gate 	void *dest;
16810Sstevel@tonic-gate 	uchar_t val;
16820Sstevel@tonic-gate 	size_t len;
16830Sstevel@tonic-gate 
16840Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "fill");
16850Sstevel@tonic-gate 	val  = (uchar_t)POP(DS);
16860Sstevel@tonic-gate 	len  = (size_t)POP(DS);
16870Sstevel@tonic-gate 	dest = (void *)POP(DS);
16880Sstevel@tonic-gate 	memset(dest, val, len);
16890Sstevel@tonic-gate }
16900Sstevel@tonic-gate 
16910Sstevel@tonic-gate void
fc_comp(fcode_env_t * env)16920Sstevel@tonic-gate fc_comp(fcode_env_t *env)
16930Sstevel@tonic-gate {
16940Sstevel@tonic-gate 	char *str1, *str2;
16950Sstevel@tonic-gate 	size_t len;
16960Sstevel@tonic-gate 	int res;
16970Sstevel@tonic-gate 
16980Sstevel@tonic-gate 	CHECK_DEPTH(env, 3, "comp");
16990Sstevel@tonic-gate 	len  = (size_t)POP(DS);
17000Sstevel@tonic-gate 	str1 = (char *)POP(DS);
17010Sstevel@tonic-gate 	str2 = (char *)POP(DS);
17020Sstevel@tonic-gate 	res  = memcmp(str2, str1, len);
17030Sstevel@tonic-gate 	if (res > 0)
17040Sstevel@tonic-gate 		res = 1;
17050Sstevel@tonic-gate 	else if (res < 0)
17060Sstevel@tonic-gate 		res = -1;
17070Sstevel@tonic-gate 	PUSH(DS, res);
17080Sstevel@tonic-gate }
17090Sstevel@tonic-gate 
17100Sstevel@tonic-gate void
set_temporary_compile(fcode_env_t * env)17110Sstevel@tonic-gate set_temporary_compile(fcode_env_t *env)
17120Sstevel@tonic-gate {
17130Sstevel@tonic-gate 	if (!env->state) {
17140Sstevel@tonic-gate 		token_roundup(env, "set_temporary_compile");
17150Sstevel@tonic-gate 		PUSH(RS, (fstack_t)HERE);
17160Sstevel@tonic-gate 		env->state = 3;
17170Sstevel@tonic-gate 		COMPILE_TOKEN(&do_colon);
17180Sstevel@tonic-gate 	}
17190Sstevel@tonic-gate }
17200Sstevel@tonic-gate 
17210Sstevel@tonic-gate void
bmark(fcode_env_t * env)17220Sstevel@tonic-gate bmark(fcode_env_t *env)
17230Sstevel@tonic-gate {
17240Sstevel@tonic-gate 	set_temporary_compile(env);
17250Sstevel@tonic-gate 	env->level++;
17260Sstevel@tonic-gate 	PUSH(DS, (fstack_t)HERE);
17270Sstevel@tonic-gate }
17280Sstevel@tonic-gate 
17290Sstevel@tonic-gate void
temporary_execute(fcode_env_t * env)17300Sstevel@tonic-gate temporary_execute(fcode_env_t *env)
17310Sstevel@tonic-gate {
17320Sstevel@tonic-gate 	uchar_t *saved_here;
17330Sstevel@tonic-gate 
17340Sstevel@tonic-gate 	if ((env->level == 0) && (env->state & 2)) {
17350Sstevel@tonic-gate 		fstack_t d = POP(RS);
17360Sstevel@tonic-gate 
17370Sstevel@tonic-gate 		semi(env);
17380Sstevel@tonic-gate 
17390Sstevel@tonic-gate 		saved_here = HERE;
17400Sstevel@tonic-gate 		/* execute the temporary definition */
17410Sstevel@tonic-gate 		env->state &= ~2;
17420Sstevel@tonic-gate 		PUSH(DS, d);
17430Sstevel@tonic-gate 		execute(env);
17440Sstevel@tonic-gate 
17450Sstevel@tonic-gate 		/* now wind the dictionary back! */
17460Sstevel@tonic-gate 		if (saved_here != HERE) {
17470Sstevel@tonic-gate 			debug_msg(DEBUG_COMMA, "Ignoring set_here in"
17480Sstevel@tonic-gate 			    " temporary_execute\n");
17490Sstevel@tonic-gate 		} else
17500Sstevel@tonic-gate 			set_here(env, (uchar_t *)d, "temporary_execute");
17510Sstevel@tonic-gate 	}
17520Sstevel@tonic-gate }
17530Sstevel@tonic-gate 
17540Sstevel@tonic-gate void
bresolve(fcode_env_t * env)17550Sstevel@tonic-gate bresolve(fcode_env_t *env)
17560Sstevel@tonic-gate {
17570Sstevel@tonic-gate 	token_t *prev = (token_t *)POP(DS);
17580Sstevel@tonic-gate 
17590Sstevel@tonic-gate 	env->level--;
17600Sstevel@tonic-gate 	*prev = (token_t)HERE;
17610Sstevel@tonic-gate 	temporary_execute(env);
17620Sstevel@tonic-gate }
17630Sstevel@tonic-gate 
17640Sstevel@tonic-gate #define	BRANCH_IP(ipp)	((token_t *)(*((token_t *)(ipp))))
17650Sstevel@tonic-gate 
17660Sstevel@tonic-gate void
do_bbranch(fcode_env_t * env)17670Sstevel@tonic-gate do_bbranch(fcode_env_t *env)
17680Sstevel@tonic-gate {
17690Sstevel@tonic-gate 	IP = BRANCH_IP(IP);
17700Sstevel@tonic-gate }
17710Sstevel@tonic-gate 
17720Sstevel@tonic-gate void
do_bqbranch(fcode_env_t * env)17730Sstevel@tonic-gate do_bqbranch(fcode_env_t *env)
17740Sstevel@tonic-gate {
17750Sstevel@tonic-gate 	fstack_t flag;
17760Sstevel@tonic-gate 
17770Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "b?branch");
17780Sstevel@tonic-gate 	flag = POP(DS);
17790Sstevel@tonic-gate 	if (flag) {
17800Sstevel@tonic-gate 		IP++;
17810Sstevel@tonic-gate 	} else {
17820Sstevel@tonic-gate 		IP = BRANCH_IP(IP);
17830Sstevel@tonic-gate 	}
17840Sstevel@tonic-gate }
17850Sstevel@tonic-gate 
17860Sstevel@tonic-gate void
do_bofbranch(fcode_env_t * env)17870Sstevel@tonic-gate do_bofbranch(fcode_env_t *env)
17880Sstevel@tonic-gate {
17890Sstevel@tonic-gate 	fstack_t d;
17900Sstevel@tonic-gate 
17910Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "bofbranch");
17920Sstevel@tonic-gate 	d = POP(DS);
17930Sstevel@tonic-gate 	if (d == TOS) {
17940Sstevel@tonic-gate 		(void) POP(DS);
17950Sstevel@tonic-gate 		IP++;
17960Sstevel@tonic-gate 	} else {
17970Sstevel@tonic-gate 		IP = BRANCH_IP(IP);
17980Sstevel@tonic-gate 	}
17990Sstevel@tonic-gate }
18000Sstevel@tonic-gate 
18010Sstevel@tonic-gate void
do_bleave(fcode_env_t * env)18020Sstevel@tonic-gate do_bleave(fcode_env_t *env)
18030Sstevel@tonic-gate {
18040Sstevel@tonic-gate 	CHECK_RETURN_DEPTH(env, 3, "do_bleave");
18050Sstevel@tonic-gate 	(void) POP(RS);
18060Sstevel@tonic-gate 	(void) POP(RS);
18070Sstevel@tonic-gate 	IP = (token_t *)POP(RS);
18080Sstevel@tonic-gate }
18090Sstevel@tonic-gate 
18100Sstevel@tonic-gate void
loop_inc(fcode_env_t * env,fstack_t inc)18110Sstevel@tonic-gate loop_inc(fcode_env_t *env, fstack_t inc)
18120Sstevel@tonic-gate {
18130Sstevel@tonic-gate 	ufstack_t a;
18140Sstevel@tonic-gate 
18150Sstevel@tonic-gate 	CHECK_RETURN_DEPTH(env, 2, "loop_inc");
18160Sstevel@tonic-gate 
18170Sstevel@tonic-gate 	/*
18180Sstevel@tonic-gate 	 * Note: end condition is when the sign bit of R[0] changes.
18190Sstevel@tonic-gate 	 */
18200Sstevel@tonic-gate 	a = RS[0];
18210Sstevel@tonic-gate 	RS[0] += inc;
18220Sstevel@tonic-gate 	if (((a ^ RS[0]) & SIGN_BIT) == 0) {
18230Sstevel@tonic-gate 		IP = BRANCH_IP(IP);
18240Sstevel@tonic-gate 	} else {
18250Sstevel@tonic-gate 		do_bleave(env);
18260Sstevel@tonic-gate 	}
18270Sstevel@tonic-gate }
18280Sstevel@tonic-gate 
18290Sstevel@tonic-gate void
do_bloop(fcode_env_t * env)18300Sstevel@tonic-gate do_bloop(fcode_env_t *env)
18310Sstevel@tonic-gate {
18320Sstevel@tonic-gate 	loop_inc(env, 1);
18330Sstevel@tonic-gate }
18340Sstevel@tonic-gate 
18350Sstevel@tonic-gate void
do_bploop(fcode_env_t * env)18360Sstevel@tonic-gate do_bploop(fcode_env_t *env)
18370Sstevel@tonic-gate {
18380Sstevel@tonic-gate 	fstack_t d;
18390Sstevel@tonic-gate 
18400Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "+loop");
18410Sstevel@tonic-gate 	d = POP(DS);
18420Sstevel@tonic-gate 	loop_inc(env, d);
18430Sstevel@tonic-gate }
18440Sstevel@tonic-gate 
18450Sstevel@tonic-gate void
loop_common(fcode_env_t * env,fstack_t ptr)18460Sstevel@tonic-gate loop_common(fcode_env_t *env, fstack_t ptr)
18470Sstevel@tonic-gate {
18480Sstevel@tonic-gate 	short offset = get_short(env);
18490Sstevel@tonic-gate 
18500Sstevel@tonic-gate 	COMPILE_TOKEN(ptr);
18510Sstevel@tonic-gate 	env->level--;
18520Sstevel@tonic-gate 	compile_comma(env);
18530Sstevel@tonic-gate 	bresolve(env);
18540Sstevel@tonic-gate }
18550Sstevel@tonic-gate 
18560Sstevel@tonic-gate void
bloop(fcode_env_t * env)18570Sstevel@tonic-gate bloop(fcode_env_t *env)
18580Sstevel@tonic-gate {
18590Sstevel@tonic-gate 	loop_common(env, (fstack_t)&do_loop_ptr);
18600Sstevel@tonic-gate }
18610Sstevel@tonic-gate 
18620Sstevel@tonic-gate void
bplusloop(fcode_env_t * env)18630Sstevel@tonic-gate bplusloop(fcode_env_t *env)
18640Sstevel@tonic-gate {
18650Sstevel@tonic-gate 	loop_common(env, (fstack_t)&do_ploop_ptr);
18660Sstevel@tonic-gate }
18670Sstevel@tonic-gate 
18680Sstevel@tonic-gate void
common_do(fcode_env_t * env,fstack_t endpt,fstack_t start,fstack_t limit)18690Sstevel@tonic-gate common_do(fcode_env_t *env, fstack_t endpt, fstack_t start, fstack_t limit)
18700Sstevel@tonic-gate {
18710Sstevel@tonic-gate 	ufstack_t i, l;
18720Sstevel@tonic-gate 
18730Sstevel@tonic-gate 	/*
18740Sstevel@tonic-gate 	 * Same computation as OBP, sets up so that loop_inc will terminate
18750Sstevel@tonic-gate 	 * when the sign bit of RS[0] changes.
18760Sstevel@tonic-gate 	 */
18770Sstevel@tonic-gate 	i = (start - limit) - SIGN_BIT;
18780Sstevel@tonic-gate 	l  = limit + SIGN_BIT;
18790Sstevel@tonic-gate 	PUSH(RS, endpt);
18800Sstevel@tonic-gate 	PUSH(RS, l);
18810Sstevel@tonic-gate 	PUSH(RS, i);
18820Sstevel@tonic-gate }
18830Sstevel@tonic-gate 
18840Sstevel@tonic-gate void
do_bdo(fcode_env_t * env)18850Sstevel@tonic-gate do_bdo(fcode_env_t *env)
18860Sstevel@tonic-gate {
18870Sstevel@tonic-gate 	fstack_t lo, hi;
18880Sstevel@tonic-gate 	fstack_t endpt;
18890Sstevel@tonic-gate 
18900Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "bdo");
18910Sstevel@tonic-gate 	endpt = (fstack_t)BRANCH_IP(IP);
18920Sstevel@tonic-gate 	IP++;
18930Sstevel@tonic-gate 	lo = POP(DS);
18940Sstevel@tonic-gate 	hi = POP(DS);
18950Sstevel@tonic-gate 	common_do(env, endpt, lo, hi);
18960Sstevel@tonic-gate }
18970Sstevel@tonic-gate 
18980Sstevel@tonic-gate void
do_bqdo(fcode_env_t * env)18990Sstevel@tonic-gate do_bqdo(fcode_env_t *env)
19000Sstevel@tonic-gate {
19010Sstevel@tonic-gate 	fstack_t lo, hi;
19020Sstevel@tonic-gate 	fstack_t endpt;
19030Sstevel@tonic-gate 
19040Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "b?do");
19050Sstevel@tonic-gate 	endpt = (fstack_t)BRANCH_IP(IP);
19060Sstevel@tonic-gate 	IP++;
19070Sstevel@tonic-gate 	lo = POP(DS);
19080Sstevel@tonic-gate 	hi = POP(DS);
19090Sstevel@tonic-gate 	if (lo == hi) {
19100Sstevel@tonic-gate 		IP = (token_t *)endpt;
19110Sstevel@tonic-gate 	} else {
19120Sstevel@tonic-gate 		common_do(env, endpt, lo, hi);
19130Sstevel@tonic-gate 	}
19140Sstevel@tonic-gate }
19150Sstevel@tonic-gate 
19160Sstevel@tonic-gate void
compile_do_common(fcode_env_t * env,fstack_t ptr)19170Sstevel@tonic-gate compile_do_common(fcode_env_t *env, fstack_t ptr)
19180Sstevel@tonic-gate {
19190Sstevel@tonic-gate 	set_temporary_compile(env);
19200Sstevel@tonic-gate 	COMPILE_TOKEN(ptr);
19210Sstevel@tonic-gate 	bmark(env);
19220Sstevel@tonic-gate 	COMPILE_TOKEN(0);
19230Sstevel@tonic-gate 	bmark(env);
19240Sstevel@tonic-gate }
19250Sstevel@tonic-gate 
19260Sstevel@tonic-gate void
bdo(fcode_env_t * env)19270Sstevel@tonic-gate bdo(fcode_env_t *env)
19280Sstevel@tonic-gate {
19290Sstevel@tonic-gate 	short offset = (short)get_short(env);
19300Sstevel@tonic-gate 	compile_do_common(env, (fstack_t)&do_bdo_ptr);
19310Sstevel@tonic-gate }
19320Sstevel@tonic-gate 
19330Sstevel@tonic-gate void
bqdo(fcode_env_t * env)19340Sstevel@tonic-gate bqdo(fcode_env_t *env)
19350Sstevel@tonic-gate {
19360Sstevel@tonic-gate 	short offset = (short)get_short(env);
19370Sstevel@tonic-gate 	compile_do_common(env, (fstack_t)&do_bqdo_ptr);
19380Sstevel@tonic-gate }
19390Sstevel@tonic-gate 
19400Sstevel@tonic-gate void
loop_i(fcode_env_t * env)19410Sstevel@tonic-gate loop_i(fcode_env_t *env)
19420Sstevel@tonic-gate {
19430Sstevel@tonic-gate 	fstack_t i;
19440Sstevel@tonic-gate 
19450Sstevel@tonic-gate 	CHECK_RETURN_DEPTH(env, 2, "i");
19460Sstevel@tonic-gate 	i = RS[0] + RS[-1];
19470Sstevel@tonic-gate 	PUSH(DS, i);
19480Sstevel@tonic-gate }
19490Sstevel@tonic-gate 
19500Sstevel@tonic-gate void
loop_j(fcode_env_t * env)19510Sstevel@tonic-gate loop_j(fcode_env_t *env)
19520Sstevel@tonic-gate {
19530Sstevel@tonic-gate 	fstack_t j;
19540Sstevel@tonic-gate 
19550Sstevel@tonic-gate 	CHECK_RETURN_DEPTH(env, 5, "j");
19560Sstevel@tonic-gate 	j = RS[-3] + RS[-4];
19570Sstevel@tonic-gate 	PUSH(DS, j);
19580Sstevel@tonic-gate }
19590Sstevel@tonic-gate 
19600Sstevel@tonic-gate void
bleave(fcode_env_t * env)19610Sstevel@tonic-gate bleave(fcode_env_t *env)
19620Sstevel@tonic-gate {
19630Sstevel@tonic-gate 
19640Sstevel@tonic-gate 	if (env->state) {
19650Sstevel@tonic-gate 		COMPILE_TOKEN(&do_leave_ptr);
19660Sstevel@tonic-gate 	}
19670Sstevel@tonic-gate }
19680Sstevel@tonic-gate 
19690Sstevel@tonic-gate void
push_string(fcode_env_t * env,char * str,int len)19700Sstevel@tonic-gate push_string(fcode_env_t *env, char *str, int len)
19710Sstevel@tonic-gate {
19720Sstevel@tonic-gate #define	NSTRINGS	16
19730Sstevel@tonic-gate 	static int string_count = 0;
19740Sstevel@tonic-gate 	static int  buflen[NSTRINGS];
19750Sstevel@tonic-gate 	static char *buffer[NSTRINGS];
19760Sstevel@tonic-gate 	char *dest;
19770Sstevel@tonic-gate 
19780Sstevel@tonic-gate 	if (!len) {
19790Sstevel@tonic-gate 		PUSH(DS, 0);
19800Sstevel@tonic-gate 		PUSH(DS, 0);
19810Sstevel@tonic-gate 		return;
19820Sstevel@tonic-gate 	}
19830Sstevel@tonic-gate 	if (len != buflen[string_count]) {
19840Sstevel@tonic-gate 		if (buffer[string_count]) FREE(buffer[string_count]);
19850Sstevel@tonic-gate 		buffer[ string_count ] = (char *)MALLOC(len+1);
19860Sstevel@tonic-gate 		buflen[ string_count ] = len;
19870Sstevel@tonic-gate 	}
19880Sstevel@tonic-gate 	dest = buffer[ string_count++ ];
19890Sstevel@tonic-gate 	string_count = string_count%NSTRINGS;
19900Sstevel@tonic-gate 	memcpy(dest, str, len);
19910Sstevel@tonic-gate 	*(dest+len) = 0;
19920Sstevel@tonic-gate 	PUSH(DS, (fstack_t)dest);
19930Sstevel@tonic-gate 	PUSH(DS, len);
19940Sstevel@tonic-gate #undef NSTRINGS
19950Sstevel@tonic-gate }
19960Sstevel@tonic-gate 
19970Sstevel@tonic-gate void
parse_word(fcode_env_t * env)19980Sstevel@tonic-gate parse_word(fcode_env_t *env)
19990Sstevel@tonic-gate {
20000Sstevel@tonic-gate 	int len = 0;
20010Sstevel@tonic-gate 	char *next, *dest, *here = "";
20020Sstevel@tonic-gate 
20030Sstevel@tonic-gate 	if (env->input) {
20040Sstevel@tonic-gate 		here = env->input->scanptr;
20050Sstevel@tonic-gate 		while (*here == env->input->separator) here++;
20060Sstevel@tonic-gate 		next = strchr(here, env->input->separator);
20070Sstevel@tonic-gate 		if (next) {
20080Sstevel@tonic-gate 			len = next - here;
20090Sstevel@tonic-gate 			while (*next == env->input->separator) next++;
20100Sstevel@tonic-gate 		} else {
20110Sstevel@tonic-gate 			len = strlen(here);
20120Sstevel@tonic-gate 			next = here + len;
20130Sstevel@tonic-gate 		}
20140Sstevel@tonic-gate 		env->input->scanptr = next;
20150Sstevel@tonic-gate 	}
20160Sstevel@tonic-gate 	push_string(env, here, len);
20170Sstevel@tonic-gate }
20180Sstevel@tonic-gate 
20190Sstevel@tonic-gate void
install_does(fcode_env_t * env)20200Sstevel@tonic-gate install_does(fcode_env_t *env)
20210Sstevel@tonic-gate {
20220Sstevel@tonic-gate 	token_t *dptr;
20230Sstevel@tonic-gate 
20240Sstevel@tonic-gate 	dptr  = (token_t *)LINK_TO_ACF(env->lastlink);
20250Sstevel@tonic-gate 
20260Sstevel@tonic-gate 	log_message(MSG_WARN, "install_does: Last acf at: %p\n", (void *)dptr);
20270Sstevel@tonic-gate 
20280Sstevel@tonic-gate 	*dptr = ((token_t)(IP+1)) | 1;
20290Sstevel@tonic-gate }
20300Sstevel@tonic-gate 
20310Sstevel@tonic-gate void
does(fcode_env_t * env)20320Sstevel@tonic-gate does(fcode_env_t *env)
20330Sstevel@tonic-gate {
20340Sstevel@tonic-gate 	token_t *dptr;
20350Sstevel@tonic-gate 
20360Sstevel@tonic-gate 	token_roundup(env, "does");
20370Sstevel@tonic-gate 
20380Sstevel@tonic-gate 	if (env->state) {
20390Sstevel@tonic-gate 		COMPILE_TOKEN(&does_ptr);
20400Sstevel@tonic-gate 		COMPILE_TOKEN(&semi_ptr);
20410Sstevel@tonic-gate 	} else {
20420Sstevel@tonic-gate 		dptr  = (token_t *)LINK_TO_ACF(env->lastlink);
20430Sstevel@tonic-gate 		log_message(MSG_WARN, "does: Last acf at: %p\n", (void *)dptr);
20440Sstevel@tonic-gate 		*dptr = ((token_t)(HERE)) | 1;
20450Sstevel@tonic-gate 		env->state |= 1;
20460Sstevel@tonic-gate 	}
20470Sstevel@tonic-gate 	COMPILE_TOKEN(&do_colon);
20480Sstevel@tonic-gate }
20490Sstevel@tonic-gate 
20500Sstevel@tonic-gate void
do_current(fcode_env_t * env)20510Sstevel@tonic-gate do_current(fcode_env_t *env)
20520Sstevel@tonic-gate {
20530Sstevel@tonic-gate 	debug_msg(DEBUG_CONTEXT, "CONTEXT:pushing &CURRENT\n");
20540Sstevel@tonic-gate 	PUSH(DS, (fstack_t)&env->current);
20550Sstevel@tonic-gate }
20560Sstevel@tonic-gate 
20570Sstevel@tonic-gate void
do_context(fcode_env_t * env)20580Sstevel@tonic-gate do_context(fcode_env_t *env)
20590Sstevel@tonic-gate {
20600Sstevel@tonic-gate 	debug_msg(DEBUG_CONTEXT, "CONTEXT:pushing &CONTEXT\n");
20610Sstevel@tonic-gate 	PUSH(DS, (fstack_t)&CONTEXT);
20620Sstevel@tonic-gate }
20630Sstevel@tonic-gate 
20640Sstevel@tonic-gate void
do_definitions(fcode_env_t * env)20650Sstevel@tonic-gate do_definitions(fcode_env_t *env)
20660Sstevel@tonic-gate {
20670Sstevel@tonic-gate 	env->current = CONTEXT;
20680Sstevel@tonic-gate 	debug_msg(DEBUG_CONTEXT, "CONTEXT:definitions: %d/%p/%p\n",
20690Sstevel@tonic-gate 	    env->order_depth, CONTEXT, env->current);
20700Sstevel@tonic-gate }
20710Sstevel@tonic-gate 
20720Sstevel@tonic-gate void
make_header(fcode_env_t * env,int flags)20730Sstevel@tonic-gate make_header(fcode_env_t *env, int flags)
20740Sstevel@tonic-gate {
20750Sstevel@tonic-gate 	int len;
20760Sstevel@tonic-gate 	char *name;
20770Sstevel@tonic-gate 
20780Sstevel@tonic-gate 	name = parse_a_string(env, &len);
20790Sstevel@tonic-gate 	header(env, name, len, flags);
20800Sstevel@tonic-gate }
20810Sstevel@tonic-gate 
20820Sstevel@tonic-gate void
do_creator(fcode_env_t * env)20830Sstevel@tonic-gate do_creator(fcode_env_t *env)
20840Sstevel@tonic-gate {
20850Sstevel@tonic-gate 	make_header(env, 0);
20860Sstevel@tonic-gate 	COMPILE_TOKEN(&do_create);
20870Sstevel@tonic-gate 	expose_acf(env, "<create>");
20880Sstevel@tonic-gate }
20890Sstevel@tonic-gate 
20900Sstevel@tonic-gate void
create(fcode_env_t * env)20910Sstevel@tonic-gate create(fcode_env_t *env)
20920Sstevel@tonic-gate {
20930Sstevel@tonic-gate 	if (env->state) {
20940Sstevel@tonic-gate 		COMPILE_TOKEN(&create_ptr);
20950Sstevel@tonic-gate 	} else
20960Sstevel@tonic-gate 		do_creator(env);
20970Sstevel@tonic-gate }
20980Sstevel@tonic-gate 
20990Sstevel@tonic-gate void
colon(fcode_env_t * env)21000Sstevel@tonic-gate colon(fcode_env_t *env)
21010Sstevel@tonic-gate {
21020Sstevel@tonic-gate 	make_header(env, 0);
21030Sstevel@tonic-gate 	env->state |= 1;
21040Sstevel@tonic-gate 	COMPILE_TOKEN(&do_colon);
21050Sstevel@tonic-gate }
21060Sstevel@tonic-gate 
21070Sstevel@tonic-gate void
recursive(fcode_env_t * env)21080Sstevel@tonic-gate recursive(fcode_env_t *env)
21090Sstevel@tonic-gate {
21100Sstevel@tonic-gate 	expose_acf(env, "<recursive>");
21110Sstevel@tonic-gate }
21120Sstevel@tonic-gate 
21130Sstevel@tonic-gate void
compile_string(fcode_env_t * env)21140Sstevel@tonic-gate compile_string(fcode_env_t *env)
21150Sstevel@tonic-gate {
21160Sstevel@tonic-gate 	int len;
21170Sstevel@tonic-gate 	uchar_t *str, *tostr;
21180Sstevel@tonic-gate 
21190Sstevel@tonic-gate 	COMPILE_TOKEN(&quote_ptr);
21200Sstevel@tonic-gate 	len = POP(DS);
21210Sstevel@tonic-gate 	str = (uchar_t *)POP(DS);
21220Sstevel@tonic-gate 	tostr = HERE;
21230Sstevel@tonic-gate 	*tostr++ = len;
21240Sstevel@tonic-gate 	while (len--)
21250Sstevel@tonic-gate 		*tostr++ = *str++;
21260Sstevel@tonic-gate 	*tostr++ = '\0';
21270Sstevel@tonic-gate 	set_here(env, tostr, "compile_string");
21280Sstevel@tonic-gate 	token_roundup(env, "compile_string");
21290Sstevel@tonic-gate }
21300Sstevel@tonic-gate 
21310Sstevel@tonic-gate void
run_quote(fcode_env_t * env)21320Sstevel@tonic-gate run_quote(fcode_env_t *env)
21330Sstevel@tonic-gate {
21340Sstevel@tonic-gate 	char osep;
21350Sstevel@tonic-gate 
21360Sstevel@tonic-gate 	osep = env->input->separator;
21370Sstevel@tonic-gate 	env->input->separator = '"';
21380Sstevel@tonic-gate 	parse_word(env);
21390Sstevel@tonic-gate 	env->input->separator = osep;
21400Sstevel@tonic-gate 
21410Sstevel@tonic-gate 	if (env->state) {
21420Sstevel@tonic-gate 		compile_string(env);
21430Sstevel@tonic-gate 	}
21440Sstevel@tonic-gate }
21450Sstevel@tonic-gate 
21460Sstevel@tonic-gate void
does_vocabulary(fcode_env_t * env)21470Sstevel@tonic-gate does_vocabulary(fcode_env_t *env)
21480Sstevel@tonic-gate {
21490Sstevel@tonic-gate 	CONTEXT = WA;
21500Sstevel@tonic-gate 	debug_msg(DEBUG_CONTEXT, "CONTEXT:vocabulary: %d/%p/%p\n",
21510Sstevel@tonic-gate 	    env->order_depth, CONTEXT, env->current);
21520Sstevel@tonic-gate }
21530Sstevel@tonic-gate 
21540Sstevel@tonic-gate void
do_vocab(fcode_env_t * env)21550Sstevel@tonic-gate do_vocab(fcode_env_t *env)
21560Sstevel@tonic-gate {
21570Sstevel@tonic-gate 	make_header(env, 0);
21580Sstevel@tonic-gate 	COMPILE_TOKEN(does_vocabulary);
21590Sstevel@tonic-gate 	PUSH(DS, 0);
21600Sstevel@tonic-gate 	compile_comma(env);
21610Sstevel@tonic-gate 	expose_acf(env, "<vocabulary>");
21620Sstevel@tonic-gate }
21630Sstevel@tonic-gate 
21640Sstevel@tonic-gate void
do_forth(fcode_env_t * env)21650Sstevel@tonic-gate do_forth(fcode_env_t *env)
21660Sstevel@tonic-gate {
21670Sstevel@tonic-gate 	CONTEXT = (token_t *)(&env->forth_voc_link);
21680Sstevel@tonic-gate 	debug_msg(DEBUG_CONTEXT, "CONTEXT:forth: %d/%p/%p\n",
21690Sstevel@tonic-gate 	    env->order_depth, CONTEXT, env->current);
21700Sstevel@tonic-gate }
21710Sstevel@tonic-gate 
21720Sstevel@tonic-gate acf_t
voc_find(fcode_env_t * env)21730Sstevel@tonic-gate voc_find(fcode_env_t *env)
21740Sstevel@tonic-gate {
21750Sstevel@tonic-gate 	token_t *voc;
21760Sstevel@tonic-gate 	token_t *dptr;
21770Sstevel@tonic-gate 	char *find_name, *name;
21780Sstevel@tonic-gate 
21790Sstevel@tonic-gate 	voc = (token_t *)POP(DS);
21800Sstevel@tonic-gate 	find_name = pop_a_string(env, NULL);
21810Sstevel@tonic-gate 
21820Sstevel@tonic-gate 	for (dptr = (token_t *)(*voc); dptr; dptr = (token_t *)(*dptr)) {
21830Sstevel@tonic-gate 		if ((name = get_name(dptr)) == NULL)
21840Sstevel@tonic-gate 			continue;
21850Sstevel@tonic-gate 		if (strcmp(find_name, name) == 0) {
21860Sstevel@tonic-gate 			debug_msg(DEBUG_VOC_FIND, "%s -> %p\n", find_name,
21870Sstevel@tonic-gate 			    LINK_TO_ACF(dptr));
21880Sstevel@tonic-gate 			return (LINK_TO_ACF(dptr));
21890Sstevel@tonic-gate 		}
21900Sstevel@tonic-gate 	}
21910Sstevel@tonic-gate 	debug_msg(DEBUG_VOC_FIND, "%s not found\n", find_name);
21920Sstevel@tonic-gate 	return (NULL);
21930Sstevel@tonic-gate }
21940Sstevel@tonic-gate 
21950Sstevel@tonic-gate void
dollar_find(fcode_env_t * env)21960Sstevel@tonic-gate dollar_find(fcode_env_t *env)
21970Sstevel@tonic-gate {
21980Sstevel@tonic-gate 	acf_t acf = NULL;
21990Sstevel@tonic-gate 	int i;
22000Sstevel@tonic-gate 
22010Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "$find");
22020Sstevel@tonic-gate 	for (i = env->order_depth; i >= 0 && env->order[i] && !acf; i--) {
22030Sstevel@tonic-gate 		two_dup(env);
22040Sstevel@tonic-gate 		PUSH(DS, (fstack_t)env->order[i]);
22050Sstevel@tonic-gate 		acf = voc_find(env);
22060Sstevel@tonic-gate 	}
22070Sstevel@tonic-gate 	if (acf) {
22080Sstevel@tonic-gate 		two_drop(env);
22090Sstevel@tonic-gate 		PUSH(DS, (fstack_t)acf);
22100Sstevel@tonic-gate 		PUSH(DS, TRUE);
22110Sstevel@tonic-gate 	} else
22120Sstevel@tonic-gate 		PUSH(DS, FALSE);
22130Sstevel@tonic-gate }
22140Sstevel@tonic-gate 
22150Sstevel@tonic-gate void
interpret(fcode_env_t * env)22160Sstevel@tonic-gate interpret(fcode_env_t *env)
22170Sstevel@tonic-gate {
22180Sstevel@tonic-gate 	char *name;
22190Sstevel@tonic-gate 
22200Sstevel@tonic-gate 	parse_word(env);
22210Sstevel@tonic-gate 	while (TOS) {
22220Sstevel@tonic-gate 		two_dup(env);
22230Sstevel@tonic-gate 		dollar_find(env);
22240Sstevel@tonic-gate 		if (TOS) {
22250Sstevel@tonic-gate 			flag_t *flags;
22260Sstevel@tonic-gate 
22270Sstevel@tonic-gate 			drop(env);
22280Sstevel@tonic-gate 			nip(env);
22290Sstevel@tonic-gate 			nip(env);
22300Sstevel@tonic-gate 			flags = LINK_TO_FLAGS(ACF_TO_LINK(TOS));
22310Sstevel@tonic-gate 
22320Sstevel@tonic-gate 			if ((env->state) &&
22330Sstevel@tonic-gate 			    ((*flags & IMMEDIATE) == 0)) {
22340Sstevel@tonic-gate 				/* Compile in references */
22350Sstevel@tonic-gate 				compile_comma(env);
22360Sstevel@tonic-gate 			} else {
22370Sstevel@tonic-gate 				execute(env);
22380Sstevel@tonic-gate 			}
22390Sstevel@tonic-gate 		} else {
22400Sstevel@tonic-gate 			int bad;
22410Sstevel@tonic-gate 			drop(env);
22420Sstevel@tonic-gate 			dollar_number(env);
22430Sstevel@tonic-gate 			bad = POP(DS);
22440Sstevel@tonic-gate 			if (bad) {
22450Sstevel@tonic-gate 				two_dup(env);
22460Sstevel@tonic-gate 				name = pop_a_string(env, NULL);
22470Sstevel@tonic-gate 				log_message(MSG_INFO, "%s?\n", name);
22480Sstevel@tonic-gate 				break;
22490Sstevel@tonic-gate 			} else {
22500Sstevel@tonic-gate 				nip(env);
22510Sstevel@tonic-gate 				nip(env);
22520Sstevel@tonic-gate 				literal(env);
22530Sstevel@tonic-gate 			}
22540Sstevel@tonic-gate 		}
22550Sstevel@tonic-gate 		parse_word(env);
22560Sstevel@tonic-gate 	}
22570Sstevel@tonic-gate 	two_drop(env);
22580Sstevel@tonic-gate }
22590Sstevel@tonic-gate 
22600Sstevel@tonic-gate void
evaluate(fcode_env_t * env)22610Sstevel@tonic-gate evaluate(fcode_env_t *env)
22620Sstevel@tonic-gate {
22630Sstevel@tonic-gate 	input_typ *old_input = env->input;
22640Sstevel@tonic-gate 	input_typ *eval_bufp = MALLOC(sizeof (input_typ));
22650Sstevel@tonic-gate 
22660Sstevel@tonic-gate 	CHECK_DEPTH(env, 2, "evaluate");
22670Sstevel@tonic-gate 	eval_bufp->separator = ' ';
22680Sstevel@tonic-gate 	eval_bufp->maxlen = POP(DS);
22690Sstevel@tonic-gate 	eval_bufp->buffer = (char *)POP(DS);
22700Sstevel@tonic-gate 	eval_bufp->scanptr = eval_bufp->buffer;
22710Sstevel@tonic-gate 	env->input = eval_bufp;
22720Sstevel@tonic-gate 	interpret(env);
22730Sstevel@tonic-gate 	FREE(eval_bufp);
22740Sstevel@tonic-gate 	env->input = old_input;
22750Sstevel@tonic-gate }
22760Sstevel@tonic-gate 
22770Sstevel@tonic-gate void
make_common_access(fcode_env_t * env,char * name,int len,int ncells,int instance_mode,void (* acf_instance)(fcode_env_t * env),void (* acf_static)(fcode_env_t * env),void (* set_action)(fcode_env_t * env,int))22780Sstevel@tonic-gate make_common_access(fcode_env_t *env,
22790Sstevel@tonic-gate     char *name, int len,
22800Sstevel@tonic-gate     int ncells,
22810Sstevel@tonic-gate     int instance_mode,
22820Sstevel@tonic-gate     void (*acf_instance)(fcode_env_t *env),
22830Sstevel@tonic-gate     void (*acf_static)(fcode_env_t *env),
22840Sstevel@tonic-gate     void (*set_action)(fcode_env_t *env, int))
22850Sstevel@tonic-gate {
22860Sstevel@tonic-gate 	if (instance_mode && !MYSELF) {
22870Sstevel@tonic-gate 		system_message(env, "No instance context");
22880Sstevel@tonic-gate 	}
22890Sstevel@tonic-gate 
22900Sstevel@tonic-gate 	debug_msg(DEBUG_ACTIONS, "make_common_access:%s '%s', %d\n",
22910Sstevel@tonic-gate 	    (instance_mode ? "instance" : ""),
22920Sstevel@tonic-gate 	    (name ? name : ""), ncells);
22930Sstevel@tonic-gate 
22940Sstevel@tonic-gate 	if (len)
22950Sstevel@tonic-gate 		header(env, name, len, 0);
22960Sstevel@tonic-gate 	if (instance_mode) {
22970Sstevel@tonic-gate 		token_t *dptr;
22980Sstevel@tonic-gate 		int offset;
22990Sstevel@tonic-gate 
23000Sstevel@tonic-gate 		COMPILE_TOKEN(acf_instance);
23010Sstevel@tonic-gate 		dptr = alloc_instance_data(env, INIT_DATA, ncells, &offset);
23020Sstevel@tonic-gate 		debug_msg(DEBUG_ACTIONS, "Data: %p, offset %d\n", (char *)dptr,
23030Sstevel@tonic-gate 		    offset);
23040Sstevel@tonic-gate 		PUSH(DS, offset);
23050Sstevel@tonic-gate 		compile_comma(env);
23060Sstevel@tonic-gate 		while (ncells--)
23070Sstevel@tonic-gate 			*dptr++ = MYSELF->data[INIT_DATA][offset++] = POP(DS);
23080Sstevel@tonic-gate 		env->instance_mode = 0;
23090Sstevel@tonic-gate 	} else {
23100Sstevel@tonic-gate 		COMPILE_TOKEN(acf_static);
23110Sstevel@tonic-gate 		while (ncells--)
23120Sstevel@tonic-gate 			compile_comma(env);
23130Sstevel@tonic-gate 	}
23140Sstevel@tonic-gate 	expose_acf(env, name);
23150Sstevel@tonic-gate 	if (set_action)
23160Sstevel@tonic-gate 		set_action(env, instance_mode);
23170Sstevel@tonic-gate }
23180Sstevel@tonic-gate 
23190Sstevel@tonic-gate void
do_constant(fcode_env_t * env)23200Sstevel@tonic-gate do_constant(fcode_env_t *env)
23210Sstevel@tonic-gate {
23220Sstevel@tonic-gate 	PUSH(DS, (variable_t)(*WA));
23230Sstevel@tonic-gate }
23240Sstevel@tonic-gate 
23250Sstevel@tonic-gate void
do_crash(fcode_env_t * env)23260Sstevel@tonic-gate do_crash(fcode_env_t *env)
23270Sstevel@tonic-gate {
23280Sstevel@tonic-gate 	forth_abort(env, "Unitialized defer");
23290Sstevel@tonic-gate }
23300Sstevel@tonic-gate 
23310Sstevel@tonic-gate /*
23320Sstevel@tonic-gate  * 'behavior' Fcode retrieve execution behavior for a defer word.
23330Sstevel@tonic-gate  */
23340Sstevel@tonic-gate static void
behavior(fcode_env_t * env)23350Sstevel@tonic-gate behavior(fcode_env_t *env)
23360Sstevel@tonic-gate {
23370Sstevel@tonic-gate 	acf_t defer_xt;
23380Sstevel@tonic-gate 	token_t token;
23390Sstevel@tonic-gate 	acf_t contents_xt;
23400Sstevel@tonic-gate 
23410Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "behavior");
23420Sstevel@tonic-gate 	defer_xt = (acf_t)POP(DS);
23430Sstevel@tonic-gate 	token = *defer_xt;
23440Sstevel@tonic-gate 	contents_xt = (token_t *)(token & ~1);
23450Sstevel@tonic-gate 	if ((token & 1) == 0 || *contents_xt != (token_t)&do_default_action)
23460Sstevel@tonic-gate 		forth_abort(env, "behavior: bad xt: %p indir: %x/%p\n",
23470Sstevel@tonic-gate 		    defer_xt, token & 1, *contents_xt);
23480Sstevel@tonic-gate 	defer_xt++;
23490Sstevel@tonic-gate 	PUSH(DS, *((variable_t *)defer_xt));
23500Sstevel@tonic-gate }
23510Sstevel@tonic-gate 
23520Sstevel@tonic-gate void
fc_abort(fcode_env_t * env,char * type)23530Sstevel@tonic-gate fc_abort(fcode_env_t *env, char *type)
23540Sstevel@tonic-gate {
23550Sstevel@tonic-gate 	forth_abort(env, "%s Fcode '%s' Executed", type,
23560Sstevel@tonic-gate 	    acf_to_name(env, WA - 1));
23570Sstevel@tonic-gate }
23580Sstevel@tonic-gate 
23590Sstevel@tonic-gate void
f_abort(fcode_env_t * env)23600Sstevel@tonic-gate f_abort(fcode_env_t *env)
23610Sstevel@tonic-gate {
23620Sstevel@tonic-gate 	fc_abort(env, "Abort");
23630Sstevel@tonic-gate }
23640Sstevel@tonic-gate 
23650Sstevel@tonic-gate /*
23660Sstevel@tonic-gate  * Fcodes chosen not to support.
23670Sstevel@tonic-gate  */
23680Sstevel@tonic-gate void
fc_unimplemented(fcode_env_t * env)23690Sstevel@tonic-gate fc_unimplemented(fcode_env_t *env)
23700Sstevel@tonic-gate {
23710Sstevel@tonic-gate 	fc_abort(env, "Unimplemented");
23720Sstevel@tonic-gate }
23730Sstevel@tonic-gate 
23740Sstevel@tonic-gate /*
23750Sstevel@tonic-gate  * Fcodes that are Obsolete per P1275-1994.
23760Sstevel@tonic-gate  */
23770Sstevel@tonic-gate void
fc_obsolete(fcode_env_t * env)23780Sstevel@tonic-gate fc_obsolete(fcode_env_t *env)
23790Sstevel@tonic-gate {
23800Sstevel@tonic-gate 	fc_abort(env, "Obsolete");
23810Sstevel@tonic-gate }
23820Sstevel@tonic-gate 
23830Sstevel@tonic-gate /*
23840Sstevel@tonic-gate  * Fcodes that are Historical per P1275-1994
23850Sstevel@tonic-gate  */
23860Sstevel@tonic-gate void
fc_historical(fcode_env_t * env)23870Sstevel@tonic-gate fc_historical(fcode_env_t *env)
23880Sstevel@tonic-gate {
23890Sstevel@tonic-gate 	fc_abort(env, "Historical");
23900Sstevel@tonic-gate }
23910Sstevel@tonic-gate 
23920Sstevel@tonic-gate void
catch(fcode_env_t * env)23930Sstevel@tonic-gate catch(fcode_env_t *env)
23940Sstevel@tonic-gate {
23950Sstevel@tonic-gate 	error_frame *new;
23960Sstevel@tonic-gate 
23970Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "catch");
23980Sstevel@tonic-gate 	new = MALLOC(sizeof (error_frame));
23990Sstevel@tonic-gate 	new->ds		= DS-1;
24000Sstevel@tonic-gate 	new->rs		= RS;
24010Sstevel@tonic-gate 	new->myself	= MYSELF;
24020Sstevel@tonic-gate 	new->next	= env->catch_frame;
24030Sstevel@tonic-gate 	new->code	= 0;
24040Sstevel@tonic-gate 	env->catch_frame = new;
24050Sstevel@tonic-gate 	execute(env);
24060Sstevel@tonic-gate 	PUSH(DS, new->code);
24070Sstevel@tonic-gate 	env->catch_frame = new->next;
24080Sstevel@tonic-gate 	FREE(new);
24090Sstevel@tonic-gate }
24100Sstevel@tonic-gate 
24110Sstevel@tonic-gate void
throw_from_fclib(fcode_env_t * env,fstack_t errcode,char * fmt,...)24120Sstevel@tonic-gate throw_from_fclib(fcode_env_t *env, fstack_t errcode, char *fmt, ...)
24130Sstevel@tonic-gate {
24140Sstevel@tonic-gate 	error_frame *efp;
24150Sstevel@tonic-gate 	va_list ap;
24160Sstevel@tonic-gate 	char msg[256];
24170Sstevel@tonic-gate 
24180Sstevel@tonic-gate 	va_start(ap, fmt);
24190Sstevel@tonic-gate 	vsprintf(msg, fmt, ap);
24200Sstevel@tonic-gate 
24210Sstevel@tonic-gate 	if (errcode) {
24220Sstevel@tonic-gate 
24230Sstevel@tonic-gate 		env->last_error = errcode;
24240Sstevel@tonic-gate 
24250Sstevel@tonic-gate 		/*
24260Sstevel@tonic-gate 		 * No catch frame set => fatal error
24270Sstevel@tonic-gate 		 */
24280Sstevel@tonic-gate 		efp = env->catch_frame;
24290Sstevel@tonic-gate 		if (!efp)
24300Sstevel@tonic-gate 			forth_abort(env, "%s: No catch frame", msg);
24310Sstevel@tonic-gate 
24320Sstevel@tonic-gate 		debug_msg(DEBUG_TRACING, "throw_from_fclib: throw: %s\n", msg);
24330Sstevel@tonic-gate 
24340Sstevel@tonic-gate 		/*
24350Sstevel@tonic-gate 		 * Setting IP=0 will force the unwinding of the calls
24360Sstevel@tonic-gate 		 * (see execute) which is how we will return (eventually)
24370Sstevel@tonic-gate 		 * to the test in catch that follows 'execute'.
24380Sstevel@tonic-gate 		 */
24390Sstevel@tonic-gate 		DS		= efp->ds;
24400Sstevel@tonic-gate 		RS		= efp->rs;
24410Sstevel@tonic-gate 		MYSELF		= efp->myself;
24420Sstevel@tonic-gate 		IP		= 0;
24430Sstevel@tonic-gate 		efp->code	= errcode;
24440Sstevel@tonic-gate 	}
24450Sstevel@tonic-gate }
24460Sstevel@tonic-gate 
24470Sstevel@tonic-gate void
throw(fcode_env_t * env)24480Sstevel@tonic-gate throw(fcode_env_t *env)
24490Sstevel@tonic-gate {
24500Sstevel@tonic-gate 	fstack_t t;
24510Sstevel@tonic-gate 
24520Sstevel@tonic-gate 	CHECK_DEPTH(env, 1, "throw");
24530Sstevel@tonic-gate 	t = POP(DS);
24540Sstevel@tonic-gate 	if (t >= -20 && t <= 20)
24550Sstevel@tonic-gate 		throw_from_fclib(env, t, "throw Fcode errcode: 0x%x", (int)t);
24560Sstevel@tonic-gate 	else {
24570Sstevel@tonic-gate 		if (t)
24580Sstevel@tonic-gate 			log_message(MSG_ERROR, "throw: errcode: 0x%x\n",
24590Sstevel@tonic-gate 			    (int)t);
24600Sstevel@tonic-gate 		throw_from_fclib(env, t, "throw Fcode err: %s", (char *)t);
24610Sstevel@tonic-gate 	}
24620Sstevel@tonic-gate }
24630Sstevel@tonic-gate 
24640Sstevel@tonic-gate void
tick_literal(fcode_env_t * env)24650Sstevel@tonic-gate tick_literal(fcode_env_t *env)
24660Sstevel@tonic-gate {
24670Sstevel@tonic-gate 	if (env->state) {
24680Sstevel@tonic-gate 		COMPILE_TOKEN(&tlit_ptr);
24690Sstevel@tonic-gate 		compile_comma(env);
24700Sstevel@tonic-gate 	}
24710Sstevel@tonic-gate }
24720Sstevel@tonic-gate 
24730Sstevel@tonic-gate void
do_tick(fcode_env_t * env)24740Sstevel@tonic-gate do_tick(fcode_env_t *env)
24750Sstevel@tonic-gate {
24760Sstevel@tonic-gate 	parse_word(env);
24770Sstevel@tonic-gate 	dollar_find(env);
24780Sstevel@tonic-gate 	invert(env);
24790Sstevel@tonic-gate 	throw(env);
24800Sstevel@tonic-gate 	tick_literal(env);
24810Sstevel@tonic-gate }
24820Sstevel@tonic-gate 
24830Sstevel@tonic-gate void
bracket_tick(fcode_env_t * env)24840Sstevel@tonic-gate bracket_tick(fcode_env_t *env)
24850Sstevel@tonic-gate {
24860Sstevel@tonic-gate 	do_tick(env);
24870Sstevel@tonic-gate }
24880Sstevel@tonic-gate 
24890Sstevel@tonic-gate #pragma init(_init)
24900Sstevel@tonic-gate 
24910Sstevel@tonic-gate static void
_init(void)24920Sstevel@tonic-gate _init(void)
24930Sstevel@tonic-gate {
24940Sstevel@tonic-gate 	fcode_env_t *env = initial_env;
24950Sstevel@tonic-gate 
24960Sstevel@tonic-gate 	NOTICE;
24970Sstevel@tonic-gate 	ASSERT(env);
24980Sstevel@tonic-gate 
24990Sstevel@tonic-gate 	ANSI(0x019, 0,		"i",			loop_i);
25000Sstevel@tonic-gate 	ANSI(0x01a, 0,		"j",			loop_j);
25010Sstevel@tonic-gate 	ANSI(0x01d, 0,		"execute",		execute);
25020Sstevel@tonic-gate 	ANSI(0x01e, 0,		"+",			add);
25030Sstevel@tonic-gate 	ANSI(0x01f, 0,		"-",			subtract);
25040Sstevel@tonic-gate 	ANSI(0x020, 0,		"*",			multiply);
25050Sstevel@tonic-gate 	ANSI(0x021, 0,		"/",			divide);
25060Sstevel@tonic-gate 	ANSI(0x022, 0,		"mod",			mod);
25070Sstevel@tonic-gate 	FORTH(0,		"/mod",			slash_mod);
25080Sstevel@tonic-gate 	ANSI(0x023, 0,		"and",			and);
25090Sstevel@tonic-gate 	ANSI(0x024, 0,		"or",			or);
25100Sstevel@tonic-gate 	ANSI(0x025, 0,		"xor",			xor);
25110Sstevel@tonic-gate 	ANSI(0x026, 0,		"invert",		invert);
25120Sstevel@tonic-gate 	ANSI(0x027, 0,		"lshift",		lshift);
25130Sstevel@tonic-gate 	ANSI(0x028, 0,		"rshift",		rshift);
25140Sstevel@tonic-gate 	ANSI(0x029, 0,		">>a",			rshifta);
25150Sstevel@tonic-gate 	ANSI(0x02a, 0,		"/mod",			slash_mod);
25160Sstevel@tonic-gate 	ANSI(0x02b, 0,		"u/mod",		uslash_mod);
25170Sstevel@tonic-gate 	ANSI(0x02c, 0,		"negate",		negate);
25180Sstevel@tonic-gate 	ANSI(0x02d, 0,		"abs",			f_abs);
25190Sstevel@tonic-gate 	ANSI(0x02e, 0,		"min",			f_min);
25200Sstevel@tonic-gate 	ANSI(0x02f, 0,		"max",			f_max);
25210Sstevel@tonic-gate 	ANSI(0x030, 0,		">r",			to_r);
25220Sstevel@tonic-gate 	ANSI(0x031, 0,		"r>",			from_r);
25230Sstevel@tonic-gate 	ANSI(0x032, 0,		"r@",			rfetch);
25240Sstevel@tonic-gate 	ANSI(0x033, 0,		"exit",			f_exit);
25250Sstevel@tonic-gate 	ANSI(0x034, 0,		"0=",			zero_equals);
25260Sstevel@tonic-gate 	ANSI(0x035, 0,		"0<>",			zero_not_equals);
25270Sstevel@tonic-gate 	ANSI(0x036, 0,		"0<",			zero_less);
25280Sstevel@tonic-gate 	ANSI(0x037, 0,		"0<=",			zero_less_equals);
25290Sstevel@tonic-gate 	ANSI(0x038, 0,		"0>",			zero_greater);
25300Sstevel@tonic-gate 	ANSI(0x039, 0,		"0>=",			zero_greater_equals);
25310Sstevel@tonic-gate 	ANSI(0x03a, 0,		"<",			less);
25320Sstevel@tonic-gate 	ANSI(0x03b, 0,		">",			greater);
25330Sstevel@tonic-gate 	ANSI(0x03c, 0,		"=",			equals);
25340Sstevel@tonic-gate 	ANSI(0x03d, 0,		"<>",			not_equals);
25350Sstevel@tonic-gate 	ANSI(0x03e, 0,		"u>",			unsign_greater);
25360Sstevel@tonic-gate 	ANSI(0x03f, 0,		"u<=",			unsign_less_equals);
25370Sstevel@tonic-gate 	ANSI(0x040, 0,		"u<",			unsign_less);
25380Sstevel@tonic-gate 	ANSI(0x041, 0,		"u>=",			unsign_greater_equals);
25390Sstevel@tonic-gate 	ANSI(0x042, 0,		">=",			greater_equals);
25400Sstevel@tonic-gate 	ANSI(0x043, 0,		"<=",			less_equals);
25410Sstevel@tonic-gate 	ANSI(0x044, 0,		"between",		between);
25420Sstevel@tonic-gate 	ANSI(0x045, 0,		"within",		within);
25430Sstevel@tonic-gate 	ANSI(0x046, 0,		"drop",			drop);
25440Sstevel@tonic-gate 	ANSI(0x047, 0,		"dup",			f_dup);
25450Sstevel@tonic-gate 	ANSI(0x048, 0,		"over",			over);
25460Sstevel@tonic-gate 	ANSI(0x049, 0,		"swap",			swap);
25470Sstevel@tonic-gate 	ANSI(0x04a, 0,		"rot",			rot);
25480Sstevel@tonic-gate 	ANSI(0x04b, 0,		"-rot",			minus_rot);
25490Sstevel@tonic-gate 	ANSI(0x04c, 0,		"tuck",			tuck);
25500Sstevel@tonic-gate 	ANSI(0x04d, 0,		"nip",			nip);
25510Sstevel@tonic-gate 	ANSI(0x04e, 0,		"pick",			pick);
25520Sstevel@tonic-gate 	ANSI(0x04f, 0,		"roll",			roll);
25530Sstevel@tonic-gate 	ANSI(0x050, 0,		"?dup",			qdup);
25540Sstevel@tonic-gate 	ANSI(0x051, 0,		"depth",		depth);
25550Sstevel@tonic-gate 	ANSI(0x052, 0,		"2drop",		two_drop);
25560Sstevel@tonic-gate 	ANSI(0x053, 0,		"2dup",			two_dup);
25570Sstevel@tonic-gate 	ANSI(0x054, 0,		"2over",		two_over);
25580Sstevel@tonic-gate 	ANSI(0x055, 0,		"2swap",		two_swap);
25590Sstevel@tonic-gate 	ANSI(0x056, 0,		"2rot",			two_rot);
25600Sstevel@tonic-gate 	ANSI(0x057, 0,		"2/",			two_slash);
25610Sstevel@tonic-gate 	ANSI(0x058, 0,		"u2/",			utwo_slash);
25620Sstevel@tonic-gate 	ANSI(0x059, 0,		"2*",			two_times);
25630Sstevel@tonic-gate 	ANSI(0x05a, 0,		"/c",			slash_c);
25640Sstevel@tonic-gate 	ANSI(0x05b, 0,		"/w",			slash_w);
25650Sstevel@tonic-gate 	ANSI(0x05c, 0,		"/l",			slash_l);
25660Sstevel@tonic-gate 	ANSI(0x05d, 0,		"/n",			slash_n);
25670Sstevel@tonic-gate 	ANSI(0x05e, 0,		"ca+",			ca_plus);
25680Sstevel@tonic-gate 	ANSI(0x05f, 0,		"wa+",			wa_plus);
25690Sstevel@tonic-gate 	ANSI(0x060, 0,		"la+",			la_plus);
25700Sstevel@tonic-gate 	ANSI(0x061, 0,		"na+",			na_plus);
25710Sstevel@tonic-gate 	ANSI(0x062, 0,		"char+",		char_plus);
25720Sstevel@tonic-gate 	ANSI(0x063, 0,		"wa1+",			wa1_plus);
25730Sstevel@tonic-gate 	ANSI(0x064, 0,		"la1+",			la1_plus);
25740Sstevel@tonic-gate 	ANSI(0x065, 0,		"cell+",		cell_plus);
25750Sstevel@tonic-gate 	ANSI(0x066, 0,		"chars",		do_chars);
25760Sstevel@tonic-gate 	ANSI(0x067, 0,		"/w*",			slash_w_times);
25770Sstevel@tonic-gate 	ANSI(0x068, 0,		"/l*",			slash_l_times);
25780Sstevel@tonic-gate 	ANSI(0x069, 0,		"cells",		cells);
25790Sstevel@tonic-gate 	ANSI(0x06a, 0,		"on",			do_on);
25800Sstevel@tonic-gate 	ANSI(0x06b, 0,		"off",			do_off);
25810Sstevel@tonic-gate 	ANSI(0x06c, 0,		"+!",			addstore);
25820Sstevel@tonic-gate 	ANSI(0x06d, 0,		"@",			fetch);
25830Sstevel@tonic-gate 	ANSI(0x06e, 0,		"l@",			lfetch);
25840Sstevel@tonic-gate 	ANSI(0x06f, 0,		"w@",			wfetch);
25850Sstevel@tonic-gate 	ANSI(0x070, 0,		"<w@",			swfetch);
25860Sstevel@tonic-gate 	ANSI(0x071, 0,		"c@",			cfetch);
25870Sstevel@tonic-gate 	ANSI(0x072, 0,		"!",			store);
25880Sstevel@tonic-gate 	ANSI(0x073, 0,		"l!",			lstore);
25890Sstevel@tonic-gate 	ANSI(0x074, 0,		"w!",			wstore);
25900Sstevel@tonic-gate 	ANSI(0x075, 0,		"c!",			cstore);
25910Sstevel@tonic-gate 	ANSI(0x076, 0,		"2@",			two_fetch);
25920Sstevel@tonic-gate 	ANSI(0x077, 0,		"2!",			two_store);
25930Sstevel@tonic-gate 	ANSI(0x078, 0,		"move",			fc_move);
25940Sstevel@tonic-gate 	ANSI(0x079, 0,		"fill",			fc_fill);
25950Sstevel@tonic-gate 	ANSI(0x07a, 0,		"comp",			fc_comp);
25960Sstevel@tonic-gate 	ANSI(0x07b, 0,		"noop",			noop);
25970Sstevel@tonic-gate 	ANSI(0x07c, 0,		"lwsplit",		lwsplit);
25980Sstevel@tonic-gate 	ANSI(0x07d, 0,		"wljoin",		wljoin);
25990Sstevel@tonic-gate 	ANSI(0x07e, 0,		"lbsplit",		lbsplit);
26000Sstevel@tonic-gate 	ANSI(0x07f, 0,		"bljoin",		bljoin);
26010Sstevel@tonic-gate 	ANSI(0x080, 0,		"wbflip",		wbflip);
26020Sstevel@tonic-gate 	ANSI(0x081, 0,		"upc",			upper_case);
26030Sstevel@tonic-gate 	ANSI(0x082, 0,		"lcc",			lower_case);
26040Sstevel@tonic-gate 	ANSI(0x083, 0,		"pack",			pack_str);
26050Sstevel@tonic-gate 	ANSI(0x084, 0,		"count",		count_str);
26060Sstevel@tonic-gate 	ANSI(0x085, 0,		"body>",		to_acf);
26070Sstevel@tonic-gate 	ANSI(0x086, 0,		">body",		to_body);
26080Sstevel@tonic-gate 
26090Sstevel@tonic-gate 	ANSI(0x089, 0,		"unloop",		unloop);
26100Sstevel@tonic-gate 
26110Sstevel@tonic-gate 	ANSI(0x09f, 0,		".s",			dot_s);
26120Sstevel@tonic-gate 	ANSI(0x0a0, 0,		"base",			base);
26130Sstevel@tonic-gate 	FCODE(0x0a1, 0,		"convert",		fc_historical);
26140Sstevel@tonic-gate 	ANSI(0x0a2, 0,		"$number",		dollar_number);
26150Sstevel@tonic-gate 	ANSI(0x0a3, 0,		"digit",		digit);
26160Sstevel@tonic-gate 
26170Sstevel@tonic-gate 	ANSI(0x0a9, 0,		"bl",			space);
26180Sstevel@tonic-gate 	ANSI(0x0aa, 0,		"bs",			backspace);
26190Sstevel@tonic-gate 	ANSI(0x0ab, 0,		"bell",			bell);
26200Sstevel@tonic-gate 	ANSI(0x0ac, 0,		"bounds",		fc_bounds);
26210Sstevel@tonic-gate 	ANSI(0x0ad, 0,		"here",			here);
26220Sstevel@tonic-gate 
26230Sstevel@tonic-gate 	ANSI(0x0af, 0,		"wbsplit",		wbsplit);
26240Sstevel@tonic-gate 	ANSI(0x0b0, 0,		"bwjoin",		bwjoin);
26250Sstevel@tonic-gate 
26260Sstevel@tonic-gate 	P1275(0x0cb, 0,		"$find",		dollar_find);
26270Sstevel@tonic-gate 
26280Sstevel@tonic-gate 	ANSI(0x0d0, 0,		"c,",			ccomma);
26290Sstevel@tonic-gate 	ANSI(0x0d1, 0,		"w,",			wcomma);
26300Sstevel@tonic-gate 	ANSI(0x0d2, 0,		"l,",			lcomma);
26310Sstevel@tonic-gate 	ANSI(0x0d3, 0,		",",			comma);
26320Sstevel@tonic-gate 	ANSI(0x0d4, 0,		"um*",			um_multiply);
26330Sstevel@tonic-gate 	ANSI(0x0d5, 0,		"um/mod",		um_slash_mod);
26340Sstevel@tonic-gate 
26350Sstevel@tonic-gate 	ANSI(0x0d8, 0,		"d+",			d_plus);
26360Sstevel@tonic-gate 	ANSI(0x0d9, 0,		"d-",			d_minus);
26370Sstevel@tonic-gate 
26380Sstevel@tonic-gate 	ANSI(0x0dc, 0,		"state",		state);
26390Sstevel@tonic-gate 	ANSI(0x0de, 0,		"behavior",		behavior);
26400Sstevel@tonic-gate 	ANSI(0x0dd, 0,		"compile,",		compile_comma);
26410Sstevel@tonic-gate 
26420Sstevel@tonic-gate 	ANSI(0x216, 0,		"abort",		f_abort);
26430Sstevel@tonic-gate 	ANSI(0x217, 0,		"catch",		catch);
26440Sstevel@tonic-gate 	ANSI(0x218, 0,		"throw",		throw);
26450Sstevel@tonic-gate 
26460Sstevel@tonic-gate 	ANSI(0x226, 0,		"lwflip",		lwflip);
26470Sstevel@tonic-gate 	ANSI(0x227, 0,		"lbflip",		lbflip);
26480Sstevel@tonic-gate 	ANSI(0x228, 0,		"lbflips",		lbflips);
26490Sstevel@tonic-gate 
26500Sstevel@tonic-gate 	ANSI(0x236, 0,		"wbflips",		wbflips);
26510Sstevel@tonic-gate 	ANSI(0x237, 0,		"lwflips",		lwflips);
26520Sstevel@tonic-gate 
26530Sstevel@tonic-gate 	FORTH(0,		"forth",		do_forth);
26540Sstevel@tonic-gate 	FORTH(0,		"current",		do_current);
26550Sstevel@tonic-gate 	FORTH(0,		"context",		do_context);
26560Sstevel@tonic-gate 	FORTH(0,		"definitions",		do_definitions);
26570Sstevel@tonic-gate 	FORTH(0,		"vocabulary",		do_vocab);
26580Sstevel@tonic-gate 	FORTH(IMMEDIATE,	":",			colon);
26590Sstevel@tonic-gate 	FORTH(IMMEDIATE,	";",			semi);
26600Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"create",		create);
26610Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"does>",		does);
26620Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"recursive",		recursive);
26630Sstevel@tonic-gate 	FORTH(0,		"parse-word",		parse_word);
26640Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"\"",			run_quote);
26650Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"order",		do_order);
26660Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"also",			do_also);
26670Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"previous",		do_previous);
26680Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"'",			do_tick);
26690Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"[']",			bracket_tick);
26700Sstevel@tonic-gate 	FORTH(0,		"unaligned-l@",		unaligned_lfetch);
26710Sstevel@tonic-gate 	FORTH(0,		"unaligned-l!",		unaligned_lstore);
26720Sstevel@tonic-gate 	FORTH(0,		"unaligned-w@",		unaligned_wfetch);
26730Sstevel@tonic-gate 	FORTH(0,		"unaligned-w!",		unaligned_wstore);
26740Sstevel@tonic-gate }
2675