1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright (c) 2000 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate * All rights reserved.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <unistd.h>
32*0Sstevel@tonic-gate #include <string.h>
33*0Sstevel@tonic-gate #include <fcntl.h>
34*0Sstevel@tonic-gate #include <setjmp.h>
35*0Sstevel@tonic-gate #include <sys/stat.h>
36*0Sstevel@tonic-gate
37*0Sstevel@tonic-gate #include <fcode/private.h>
38*0Sstevel@tonic-gate #include <fcode/log.h>
39*0Sstevel@tonic-gate
40*0Sstevel@tonic-gate void (*to_ptr)(fcode_env_t *env) = do_set_action;
41*0Sstevel@tonic-gate jmp_buf *jmp_buf_ptr = NULL;
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate char *
parse_a_string(fcode_env_t * env,int * lenp)44*0Sstevel@tonic-gate parse_a_string(fcode_env_t *env, int *lenp)
45*0Sstevel@tonic-gate {
46*0Sstevel@tonic-gate parse_word(env);
47*0Sstevel@tonic-gate return (pop_a_string(env, lenp));
48*0Sstevel@tonic-gate }
49*0Sstevel@tonic-gate
50*0Sstevel@tonic-gate void
constant(fcode_env_t * env)51*0Sstevel@tonic-gate constant(fcode_env_t *env)
52*0Sstevel@tonic-gate {
53*0Sstevel@tonic-gate char *name;
54*0Sstevel@tonic-gate int len;
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate name = parse_a_string(env, &len);
57*0Sstevel@tonic-gate env->instance_mode = 0;
58*0Sstevel@tonic-gate make_common_access(env, name, len, 1, 0,
59*0Sstevel@tonic-gate &do_constant, &do_constant, NULL);
60*0Sstevel@tonic-gate }
61*0Sstevel@tonic-gate
62*0Sstevel@tonic-gate void
buffer_colon(fcode_env_t * env)63*0Sstevel@tonic-gate buffer_colon(fcode_env_t *env)
64*0Sstevel@tonic-gate {
65*0Sstevel@tonic-gate char *name;
66*0Sstevel@tonic-gate int len;
67*0Sstevel@tonic-gate
68*0Sstevel@tonic-gate PUSH(DS, 0);
69*0Sstevel@tonic-gate name = parse_a_string(env, &len);
70*0Sstevel@tonic-gate make_common_access(env, name, len, 2,
71*0Sstevel@tonic-gate env->instance_mode, &noop, &noop, &set_buffer_actions);
72*0Sstevel@tonic-gate }
73*0Sstevel@tonic-gate
74*0Sstevel@tonic-gate void
value(fcode_env_t * env)75*0Sstevel@tonic-gate value(fcode_env_t *env)
76*0Sstevel@tonic-gate {
77*0Sstevel@tonic-gate char *name;
78*0Sstevel@tonic-gate int len;
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate name = parse_a_string(env, &len);
81*0Sstevel@tonic-gate make_common_access(env, name, len, 1,
82*0Sstevel@tonic-gate env->instance_mode, &noop, &noop, &set_value_actions);
83*0Sstevel@tonic-gate }
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gate void
variable(fcode_env_t * env)86*0Sstevel@tonic-gate variable(fcode_env_t *env)
87*0Sstevel@tonic-gate {
88*0Sstevel@tonic-gate char *name;
89*0Sstevel@tonic-gate int len;
90*0Sstevel@tonic-gate
91*0Sstevel@tonic-gate PUSH(DS, 0);
92*0Sstevel@tonic-gate name = parse_a_string(env, &len);
93*0Sstevel@tonic-gate make_common_access(env, name, len, 1,
94*0Sstevel@tonic-gate env->instance_mode, &instance_variable, &do_create, NULL);
95*0Sstevel@tonic-gate }
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gate void
defer(fcode_env_t * env)98*0Sstevel@tonic-gate defer(fcode_env_t *env)
99*0Sstevel@tonic-gate {
100*0Sstevel@tonic-gate static void (*crash_ptr)(fcode_env_t *env) = do_crash;
101*0Sstevel@tonic-gate char *name;
102*0Sstevel@tonic-gate int len;
103*0Sstevel@tonic-gate
104*0Sstevel@tonic-gate PUSH(DS, (fstack_t)&crash_ptr);
105*0Sstevel@tonic-gate name = parse_a_string(env, &len);
106*0Sstevel@tonic-gate make_common_access(env, name, len, 1,
107*0Sstevel@tonic-gate env->instance_mode, &noop, &noop, &set_defer_actions);
108*0Sstevel@tonic-gate }
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gate void
field(fcode_env_t * env)111*0Sstevel@tonic-gate field(fcode_env_t *env)
112*0Sstevel@tonic-gate {
113*0Sstevel@tonic-gate char *name;
114*0Sstevel@tonic-gate int len;
115*0Sstevel@tonic-gate
116*0Sstevel@tonic-gate over(env);
117*0Sstevel@tonic-gate name = parse_a_string(env, &len);
118*0Sstevel@tonic-gate make_common_access(env, name, len, 1, 0, &do_field, &do_field, NULL);
119*0Sstevel@tonic-gate add(env);
120*0Sstevel@tonic-gate }
121*0Sstevel@tonic-gate
122*0Sstevel@tonic-gate void
bye(fcode_env_t * env)123*0Sstevel@tonic-gate bye(fcode_env_t *env)
124*0Sstevel@tonic-gate {
125*0Sstevel@tonic-gate exit(0);
126*0Sstevel@tonic-gate }
127*0Sstevel@tonic-gate
128*0Sstevel@tonic-gate void
do_resume(fcode_env_t * env)129*0Sstevel@tonic-gate do_resume(fcode_env_t *env)
130*0Sstevel@tonic-gate {
131*0Sstevel@tonic-gate if (env->interactive) env->interactive--;
132*0Sstevel@tonic-gate COMPLETE_INTERRUPT;
133*0Sstevel@tonic-gate }
134*0Sstevel@tonic-gate
135*0Sstevel@tonic-gate /*
136*0Sstevel@tonic-gate * In interactive mode, jmp_buf_ptr should be non-null.
137*0Sstevel@tonic-gate */
138*0Sstevel@tonic-gate void
return_to_interact(fcode_env_t * env)139*0Sstevel@tonic-gate return_to_interact(fcode_env_t *env)
140*0Sstevel@tonic-gate {
141*0Sstevel@tonic-gate if (jmp_buf_ptr)
142*0Sstevel@tonic-gate longjmp(*jmp_buf_ptr, 1);
143*0Sstevel@tonic-gate }
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gate void
do_interact(fcode_env_t * env)146*0Sstevel@tonic-gate do_interact(fcode_env_t *env)
147*0Sstevel@tonic-gate {
148*0Sstevel@tonic-gate int level;
149*0Sstevel@tonic-gate jmp_buf jmp_env;
150*0Sstevel@tonic-gate jmp_buf *ojmp_ptr;
151*0Sstevel@tonic-gate error_frame new;
152*0Sstevel@tonic-gate input_typ *old_input = env->input;
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate log_message(MSG_INFO, "Type resume to return\n");
155*0Sstevel@tonic-gate env->interactive++;
156*0Sstevel@tonic-gate level = env->interactive;
157*0Sstevel@tonic-gate
158*0Sstevel@tonic-gate ojmp_ptr = jmp_buf_ptr;
159*0Sstevel@tonic-gate jmp_buf_ptr = &jmp_env;
160*0Sstevel@tonic-gate env->input->separator = ' ';
161*0Sstevel@tonic-gate env->input->maxlen = 256;
162*0Sstevel@tonic-gate env->input->buffer = MALLOC(env->input->maxlen);
163*0Sstevel@tonic-gate env->input->scanptr = env->input->buffer;
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate if (setjmp(jmp_env)) {
166*0Sstevel@tonic-gate if (in_forth_abort > 1) {
167*0Sstevel@tonic-gate RS = env->rs0;
168*0Sstevel@tonic-gate DS = env->ds0;
169*0Sstevel@tonic-gate MYSELF = 0;
170*0Sstevel@tonic-gate IP = 0;
171*0Sstevel@tonic-gate env->input = old_input;
172*0Sstevel@tonic-gate env->order_depth = 0;
173*0Sstevel@tonic-gate } else {
174*0Sstevel@tonic-gate RS = new.rs;
175*0Sstevel@tonic-gate DS = new.ds;
176*0Sstevel@tonic-gate MYSELF = new.myself;
177*0Sstevel@tonic-gate IP = new.ip;
178*0Sstevel@tonic-gate env->input = old_input;
179*0Sstevel@tonic-gate }
180*0Sstevel@tonic-gate do_forth(env);
181*0Sstevel@tonic-gate do_definitions(env);
182*0Sstevel@tonic-gate in_forth_abort = 0;
183*0Sstevel@tonic-gate } else {
184*0Sstevel@tonic-gate new.rs = RS;
185*0Sstevel@tonic-gate new.ds = DS;
186*0Sstevel@tonic-gate new.myself = MYSELF;
187*0Sstevel@tonic-gate new.ip = IP;
188*0Sstevel@tonic-gate }
189*0Sstevel@tonic-gate
190*0Sstevel@tonic-gate while (env->interactive == level) {
191*0Sstevel@tonic-gate int wlen;
192*0Sstevel@tonic-gate char *p;
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gate DEBUGF(SHOW_RS, output_return_stack(env, 0, MSG_FC_DEBUG));
195*0Sstevel@tonic-gate DEBUGF(SHOW_STACK, output_data_stack(env, MSG_FC_DEBUG));
196*0Sstevel@tonic-gate
197*0Sstevel@tonic-gate #define USE_READLINE
198*0Sstevel@tonic-gate #ifdef USE_READLINE
199*0Sstevel@tonic-gate {
200*0Sstevel@tonic-gate char *line;
201*0Sstevel@tonic-gate void read_line(fcode_env_t *);
202*0Sstevel@tonic-gate
203*0Sstevel@tonic-gate read_line(env);
204*0Sstevel@tonic-gate if ((line = pop_a_string(env, NULL)) == NULL)
205*0Sstevel@tonic-gate continue;
206*0Sstevel@tonic-gate
207*0Sstevel@tonic-gate env->input->scanptr = strcpy(env->input->buffer, line);
208*0Sstevel@tonic-gate }
209*0Sstevel@tonic-gate #else
210*0Sstevel@tonic-gate if (isatty(fileno(stdin)))
211*0Sstevel@tonic-gate printf("ok ");
212*0Sstevel@tonic-gate
213*0Sstevel@tonic-gate env->input->scanptr = fgets(env->input->buffer,
214*0Sstevel@tonic-gate env->input->maxlen, stdin);
215*0Sstevel@tonic-gate
216*0Sstevel@tonic-gate if (feof(stdin))
217*0Sstevel@tonic-gate break;
218*0Sstevel@tonic-gate
219*0Sstevel@tonic-gate if (env->input->scanptr == NULL)
220*0Sstevel@tonic-gate continue;
221*0Sstevel@tonic-gate #endif
222*0Sstevel@tonic-gate
223*0Sstevel@tonic-gate if ((p = strpbrk(env->input->scanptr, "\n\r")) != NULL)
224*0Sstevel@tonic-gate *p = '\0';
225*0Sstevel@tonic-gate
226*0Sstevel@tonic-gate if ((wlen = strlen(env->input->scanptr)) == 0)
227*0Sstevel@tonic-gate continue;
228*0Sstevel@tonic-gate
229*0Sstevel@tonic-gate PUSH(DS, (fstack_t)env->input->buffer);
230*0Sstevel@tonic-gate PUSH(DS, wlen);
231*0Sstevel@tonic-gate evaluate(env);
232*0Sstevel@tonic-gate }
233*0Sstevel@tonic-gate
234*0Sstevel@tonic-gate jmp_buf_ptr = ojmp_ptr;
235*0Sstevel@tonic-gate FREE(env->input->buffer);
236*0Sstevel@tonic-gate }
237*0Sstevel@tonic-gate
238*0Sstevel@tonic-gate static void
temp_base(fcode_env_t * env,fstack_t base)239*0Sstevel@tonic-gate temp_base(fcode_env_t *env, fstack_t base)
240*0Sstevel@tonic-gate {
241*0Sstevel@tonic-gate fstack_t obase;
242*0Sstevel@tonic-gate
243*0Sstevel@tonic-gate obase = env->num_base;
244*0Sstevel@tonic-gate env->num_base = base;
245*0Sstevel@tonic-gate parse_word(env);
246*0Sstevel@tonic-gate evaluate(env);
247*0Sstevel@tonic-gate env->num_base = obase;
248*0Sstevel@tonic-gate }
249*0Sstevel@tonic-gate
250*0Sstevel@tonic-gate static void
temp_decimal(fcode_env_t * env)251*0Sstevel@tonic-gate temp_decimal(fcode_env_t *env)
252*0Sstevel@tonic-gate {
253*0Sstevel@tonic-gate temp_base(env, 10);
254*0Sstevel@tonic-gate }
255*0Sstevel@tonic-gate
256*0Sstevel@tonic-gate static void
temp_hex(fcode_env_t * env)257*0Sstevel@tonic-gate temp_hex(fcode_env_t *env)
258*0Sstevel@tonic-gate {
259*0Sstevel@tonic-gate temp_base(env, 0x10);
260*0Sstevel@tonic-gate }
261*0Sstevel@tonic-gate
262*0Sstevel@tonic-gate static void
temp_binary(fcode_env_t * env)263*0Sstevel@tonic-gate temp_binary(fcode_env_t *env)
264*0Sstevel@tonic-gate {
265*0Sstevel@tonic-gate temp_base(env, 2);
266*0Sstevel@tonic-gate }
267*0Sstevel@tonic-gate
268*0Sstevel@tonic-gate static void
do_hex(fcode_env_t * env)269*0Sstevel@tonic-gate do_hex(fcode_env_t *env)
270*0Sstevel@tonic-gate {
271*0Sstevel@tonic-gate env->num_base = 0x10;
272*0Sstevel@tonic-gate }
273*0Sstevel@tonic-gate
274*0Sstevel@tonic-gate static void
do_decimal(fcode_env_t * env)275*0Sstevel@tonic-gate do_decimal(fcode_env_t *env)
276*0Sstevel@tonic-gate {
277*0Sstevel@tonic-gate env->num_base = 10;
278*0Sstevel@tonic-gate }
279*0Sstevel@tonic-gate
280*0Sstevel@tonic-gate static void
do_binary(fcode_env_t * env)281*0Sstevel@tonic-gate do_binary(fcode_env_t *env)
282*0Sstevel@tonic-gate {
283*0Sstevel@tonic-gate env->num_base = 2;
284*0Sstevel@tonic-gate }
285*0Sstevel@tonic-gate
286*0Sstevel@tonic-gate static void
do_clear(fcode_env_t * env)287*0Sstevel@tonic-gate do_clear(fcode_env_t *env)
288*0Sstevel@tonic-gate {
289*0Sstevel@tonic-gate DS = env->ds0;
290*0Sstevel@tonic-gate }
291*0Sstevel@tonic-gate
292*0Sstevel@tonic-gate static void
action_one(fcode_env_t * env)293*0Sstevel@tonic-gate action_one(fcode_env_t *env)
294*0Sstevel@tonic-gate {
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate do_tick(env);
297*0Sstevel@tonic-gate if (env->state) {
298*0Sstevel@tonic-gate COMPILE_TOKEN(&to_ptr);
299*0Sstevel@tonic-gate } else {
300*0Sstevel@tonic-gate PUSH(DS, 1);
301*0Sstevel@tonic-gate perform_action(env);
302*0Sstevel@tonic-gate }
303*0Sstevel@tonic-gate }
304*0Sstevel@tonic-gate
305*0Sstevel@tonic-gate void
do_if(fcode_env_t * env)306*0Sstevel@tonic-gate do_if(fcode_env_t *env)
307*0Sstevel@tonic-gate {
308*0Sstevel@tonic-gate branch_common(env, 1, 1, 0);
309*0Sstevel@tonic-gate }
310*0Sstevel@tonic-gate
311*0Sstevel@tonic-gate void
do_else(fcode_env_t * env)312*0Sstevel@tonic-gate do_else(fcode_env_t *env)
313*0Sstevel@tonic-gate {
314*0Sstevel@tonic-gate branch_common(env, 1, 0, 1);
315*0Sstevel@tonic-gate bresolve(env);
316*0Sstevel@tonic-gate }
317*0Sstevel@tonic-gate
318*0Sstevel@tonic-gate void
do_then(fcode_env_t * env)319*0Sstevel@tonic-gate do_then(fcode_env_t *env)
320*0Sstevel@tonic-gate {
321*0Sstevel@tonic-gate bresolve(env);
322*0Sstevel@tonic-gate }
323*0Sstevel@tonic-gate
324*0Sstevel@tonic-gate void
do_of(fcode_env_t * env)325*0Sstevel@tonic-gate do_of(fcode_env_t *env)
326*0Sstevel@tonic-gate {
327*0Sstevel@tonic-gate branch_common(env, 0, 2, 0);
328*0Sstevel@tonic-gate }
329*0Sstevel@tonic-gate
330*0Sstevel@tonic-gate void
load_file(fcode_env_t * env)331*0Sstevel@tonic-gate load_file(fcode_env_t *env)
332*0Sstevel@tonic-gate {
333*0Sstevel@tonic-gate int fd;
334*0Sstevel@tonic-gate int len, n;
335*0Sstevel@tonic-gate char *name;
336*0Sstevel@tonic-gate char *buffer;
337*0Sstevel@tonic-gate struct stat buf;
338*0Sstevel@tonic-gate
339*0Sstevel@tonic-gate CHECK_DEPTH(env, 2, "load-file");
340*0Sstevel@tonic-gate name = pop_a_string(env, &len);
341*0Sstevel@tonic-gate log_message(MSG_INFO, "load_file: '%s'\n", name);
342*0Sstevel@tonic-gate fd = open(name, O_RDONLY);
343*0Sstevel@tonic-gate if (fd < 0) {
344*0Sstevel@tonic-gate forth_perror(env, "Can't open '%s'", name);
345*0Sstevel@tonic-gate }
346*0Sstevel@tonic-gate fstat(fd, &buf);
347*0Sstevel@tonic-gate len = buf.st_size;
348*0Sstevel@tonic-gate buffer = MALLOC(len);
349*0Sstevel@tonic-gate if (buffer == 0)
350*0Sstevel@tonic-gate forth_perror(env, "load_file: MALLOC(%d)", len);
351*0Sstevel@tonic-gate
352*0Sstevel@tonic-gate if ((n = read(fd, buffer, len)) < 0)
353*0Sstevel@tonic-gate forth_perror(env, "read error '%s'", name);
354*0Sstevel@tonic-gate
355*0Sstevel@tonic-gate close(fd);
356*0Sstevel@tonic-gate PUSH(DS, (fstack_t)buffer);
357*0Sstevel@tonic-gate PUSH(DS, (fstack_t)n);
358*0Sstevel@tonic-gate }
359*0Sstevel@tonic-gate
360*0Sstevel@tonic-gate void
load(fcode_env_t * env)361*0Sstevel@tonic-gate load(fcode_env_t *env)
362*0Sstevel@tonic-gate {
363*0Sstevel@tonic-gate parse_word(env);
364*0Sstevel@tonic-gate if (TOS > 0)
365*0Sstevel@tonic-gate load_file(env);
366*0Sstevel@tonic-gate }
367*0Sstevel@tonic-gate
368*0Sstevel@tonic-gate void
fevaluate(fcode_env_t * env)369*0Sstevel@tonic-gate fevaluate(fcode_env_t *env)
370*0Sstevel@tonic-gate {
371*0Sstevel@tonic-gate char *buffer;
372*0Sstevel@tonic-gate int bytes, len;
373*0Sstevel@tonic-gate
374*0Sstevel@tonic-gate two_dup(env);
375*0Sstevel@tonic-gate buffer = pop_a_string(env, &len);
376*0Sstevel@tonic-gate for (bytes = 0; bytes < len; bytes++) {
377*0Sstevel@tonic-gate if ((buffer[bytes] == '\n') || (buffer[bytes] == '\r'))
378*0Sstevel@tonic-gate buffer[bytes] = ' ';
379*0Sstevel@tonic-gate }
380*0Sstevel@tonic-gate evaluate(env);
381*0Sstevel@tonic-gate }
382*0Sstevel@tonic-gate
383*0Sstevel@tonic-gate void
fload(fcode_env_t * env)384*0Sstevel@tonic-gate fload(fcode_env_t *env)
385*0Sstevel@tonic-gate {
386*0Sstevel@tonic-gate char *buffer;
387*0Sstevel@tonic-gate
388*0Sstevel@tonic-gate load(env);
389*0Sstevel@tonic-gate two_dup(env);
390*0Sstevel@tonic-gate buffer = pop_a_string(env, NULL);
391*0Sstevel@tonic-gate fevaluate(env);
392*0Sstevel@tonic-gate FREE(buffer);
393*0Sstevel@tonic-gate }
394*0Sstevel@tonic-gate
395*0Sstevel@tonic-gate #include <sys/termio.h>
396*0Sstevel@tonic-gate
397*0Sstevel@tonic-gate #define MAX_LINE_BUF 20
398*0Sstevel@tonic-gate
399*0Sstevel@tonic-gate static char *history_lines[MAX_LINE_BUF];
400*0Sstevel@tonic-gate int num_lines = 0;
401*0Sstevel@tonic-gate
402*0Sstevel@tonic-gate static void
add_line_to_history(fcode_env_t * env,char * line)403*0Sstevel@tonic-gate add_line_to_history(fcode_env_t *env, char *line)
404*0Sstevel@tonic-gate {
405*0Sstevel@tonic-gate int i;
406*0Sstevel@tonic-gate
407*0Sstevel@tonic-gate if (num_lines < MAX_LINE_BUF)
408*0Sstevel@tonic-gate history_lines[num_lines++] = STRDUP(line);
409*0Sstevel@tonic-gate else {
410*0Sstevel@tonic-gate FREE(history_lines[0]);
411*0Sstevel@tonic-gate for (i = 0; i < MAX_LINE_BUF - 1; i++)
412*0Sstevel@tonic-gate history_lines[i] = history_lines[i + 1];
413*0Sstevel@tonic-gate history_lines[MAX_LINE_BUF - 1] = STRDUP(line);
414*0Sstevel@tonic-gate }
415*0Sstevel@tonic-gate }
416*0Sstevel@tonic-gate
417*0Sstevel@tonic-gate static void
do_emit_chars(fcode_env_t * env,char c,int n)418*0Sstevel@tonic-gate do_emit_chars(fcode_env_t *env, char c, int n)
419*0Sstevel@tonic-gate {
420*0Sstevel@tonic-gate int i;
421*0Sstevel@tonic-gate
422*0Sstevel@tonic-gate for (i = 0; i < n; i++)
423*0Sstevel@tonic-gate do_emit(env, c);
424*0Sstevel@tonic-gate }
425*0Sstevel@tonic-gate
426*0Sstevel@tonic-gate static void
do_emit_str(fcode_env_t * env,char * str,int n)427*0Sstevel@tonic-gate do_emit_str(fcode_env_t *env, char *str, int n)
428*0Sstevel@tonic-gate {
429*0Sstevel@tonic-gate int i;
430*0Sstevel@tonic-gate
431*0Sstevel@tonic-gate for (i = 0; i < n; i++)
432*0Sstevel@tonic-gate do_emit(env, *str++);
433*0Sstevel@tonic-gate }
434*0Sstevel@tonic-gate
435*0Sstevel@tonic-gate static char *
find_next_word(char * cursor,char * eol)436*0Sstevel@tonic-gate find_next_word(char *cursor, char *eol)
437*0Sstevel@tonic-gate {
438*0Sstevel@tonic-gate while (cursor < eol && *cursor != ' ')
439*0Sstevel@tonic-gate cursor++;
440*0Sstevel@tonic-gate while (cursor < eol && *cursor == ' ')
441*0Sstevel@tonic-gate cursor++;
442*0Sstevel@tonic-gate return (cursor);
443*0Sstevel@tonic-gate }
444*0Sstevel@tonic-gate
445*0Sstevel@tonic-gate static char *
find_prev_word(char * buf,char * cursor)446*0Sstevel@tonic-gate find_prev_word(char *buf, char *cursor)
447*0Sstevel@tonic-gate {
448*0Sstevel@tonic-gate int skippedword = 0;
449*0Sstevel@tonic-gate
450*0Sstevel@tonic-gate if (cursor == buf)
451*0Sstevel@tonic-gate return (cursor);
452*0Sstevel@tonic-gate cursor--;
453*0Sstevel@tonic-gate while (cursor > buf && *cursor == ' ')
454*0Sstevel@tonic-gate cursor--;
455*0Sstevel@tonic-gate while (cursor > buf && *cursor != ' ') {
456*0Sstevel@tonic-gate skippedword++;
457*0Sstevel@tonic-gate cursor--;
458*0Sstevel@tonic-gate }
459*0Sstevel@tonic-gate if (skippedword && *cursor == ' ')
460*0Sstevel@tonic-gate cursor++;
461*0Sstevel@tonic-gate return (cursor);
462*0Sstevel@tonic-gate }
463*0Sstevel@tonic-gate
464*0Sstevel@tonic-gate void
redraw_line(fcode_env_t * env,char * prev_l,char * prev_cursor,char * prev_eol,char * new_l,char * new_cursor,char * new_eol)465*0Sstevel@tonic-gate redraw_line(fcode_env_t *env, char *prev_l, char *prev_cursor, char *prev_eol,
466*0Sstevel@tonic-gate char *new_l, char *new_cursor, char *new_eol)
467*0Sstevel@tonic-gate {
468*0Sstevel@tonic-gate int len;
469*0Sstevel@tonic-gate
470*0Sstevel@tonic-gate /* backup to beginning of previous line */
471*0Sstevel@tonic-gate do_emit_chars(env, '\b', prev_cursor - prev_l);
472*0Sstevel@tonic-gate
473*0Sstevel@tonic-gate /* overwrite new line */
474*0Sstevel@tonic-gate do_emit_str(env, new_l, new_eol - new_l);
475*0Sstevel@tonic-gate
476*0Sstevel@tonic-gate /* Output blanks to erase previous line chars if old line was longer */
477*0Sstevel@tonic-gate len = max(0, (prev_eol - prev_l) - (new_eol - new_l));
478*0Sstevel@tonic-gate do_emit_chars(env, ' ', len);
479*0Sstevel@tonic-gate
480*0Sstevel@tonic-gate /* Backup cursor for new line */
481*0Sstevel@tonic-gate do_emit_chars(env, '\b', len + (new_eol - new_cursor));
482*0Sstevel@tonic-gate }
483*0Sstevel@tonic-gate
484*0Sstevel@tonic-gate #define MAX_LINE_SIZE 256
485*0Sstevel@tonic-gate
486*0Sstevel@tonic-gate static void
do_save_buf(char * save_buf,char * buf,int n)487*0Sstevel@tonic-gate do_save_buf(char *save_buf, char *buf, int n)
488*0Sstevel@tonic-gate {
489*0Sstevel@tonic-gate n = max(0, min(n, MAX_LINE_SIZE));
490*0Sstevel@tonic-gate memcpy(save_buf, buf, n);
491*0Sstevel@tonic-gate save_buf[n] = '\0';
492*0Sstevel@tonic-gate }
493*0Sstevel@tonic-gate
494*0Sstevel@tonic-gate char prompt_string[80] = "ok ";
495*0Sstevel@tonic-gate
496*0Sstevel@tonic-gate void
read_line(fcode_env_t * env)497*0Sstevel@tonic-gate read_line(fcode_env_t *env)
498*0Sstevel@tonic-gate {
499*0Sstevel@tonic-gate char buf[MAX_LINE_SIZE+1], save_buf[MAX_LINE_SIZE+1];
500*0Sstevel@tonic-gate char save_line[MAX_LINE_SIZE+1];
501*0Sstevel@tonic-gate char *p, *cursor, *eol, *tp, *cp;
502*0Sstevel@tonic-gate fstack_t d;
503*0Sstevel@tonic-gate int saw_esc = 0, do_quote = 0, i, cur_line, len, my_line, save_cursor;
504*0Sstevel@tonic-gate struct termio termio, savetermio;
505*0Sstevel@tonic-gate
506*0Sstevel@tonic-gate if (!isatty(fileno(stdin))) {
507*0Sstevel@tonic-gate fgets(buf, sizeof (buf), stdin);
508*0Sstevel@tonic-gate push_string(env, buf, strlen(buf));
509*0Sstevel@tonic-gate return;
510*0Sstevel@tonic-gate }
511*0Sstevel@tonic-gate printf(prompt_string);
512*0Sstevel@tonic-gate fflush(stdout);
513*0Sstevel@tonic-gate ioctl(fileno(stdin), TCGETA, &termio);
514*0Sstevel@tonic-gate savetermio = termio;
515*0Sstevel@tonic-gate termio.c_lflag &= ~(ICANON|ECHO|ECHOE|IEXTEN);
516*0Sstevel@tonic-gate termio.c_cc[VTIME] = 0;
517*0Sstevel@tonic-gate termio.c_cc[VMIN] = 1;
518*0Sstevel@tonic-gate ioctl(fileno(stdin), TCSETA, &termio);
519*0Sstevel@tonic-gate my_line = cur_line = num_lines;
520*0Sstevel@tonic-gate save_buf[0] = '\0';
521*0Sstevel@tonic-gate for (cursor = eol = buf; ; ) {
522*0Sstevel@tonic-gate for (d = FALSE; d == FALSE; d = POP(DS))
523*0Sstevel@tonic-gate keyquestion(env);
524*0Sstevel@tonic-gate key(env);
525*0Sstevel@tonic-gate d = POP(DS);
526*0Sstevel@tonic-gate if (do_quote) {
527*0Sstevel@tonic-gate do_quote = 0;
528*0Sstevel@tonic-gate if ((cursor - buf) < MAX_LINE_SIZE) {
529*0Sstevel@tonic-gate *cursor++ = d;
530*0Sstevel@tonic-gate if (cursor > eol)
531*0Sstevel@tonic-gate eol = cursor;
532*0Sstevel@tonic-gate do_emit(env, d);
533*0Sstevel@tonic-gate }
534*0Sstevel@tonic-gate continue;
535*0Sstevel@tonic-gate }
536*0Sstevel@tonic-gate if (saw_esc) {
537*0Sstevel@tonic-gate saw_esc = 0;
538*0Sstevel@tonic-gate switch (d) {
539*0Sstevel@tonic-gate
540*0Sstevel@tonic-gate default: /* Ignore anything else */
541*0Sstevel@tonic-gate continue;
542*0Sstevel@tonic-gate
543*0Sstevel@tonic-gate case 'b': /* Move backward one word */
544*0Sstevel@tonic-gate case 'B':
545*0Sstevel@tonic-gate tp = find_prev_word(buf, cursor);
546*0Sstevel@tonic-gate if (tp < cursor) {
547*0Sstevel@tonic-gate do_emit_chars(env, '\b', cursor - tp);
548*0Sstevel@tonic-gate cursor = tp;
549*0Sstevel@tonic-gate }
550*0Sstevel@tonic-gate continue;
551*0Sstevel@tonic-gate
552*0Sstevel@tonic-gate case 'f': /* Move forward one word */
553*0Sstevel@tonic-gate case 'F':
554*0Sstevel@tonic-gate tp = find_next_word(cursor, eol);
555*0Sstevel@tonic-gate if (tp > cursor) {
556*0Sstevel@tonic-gate do_emit_str(env, tp, tp - cursor);
557*0Sstevel@tonic-gate cursor = tp;
558*0Sstevel@tonic-gate }
559*0Sstevel@tonic-gate continue;
560*0Sstevel@tonic-gate
561*0Sstevel@tonic-gate case 'h': /* Erase from beginning of word to */
562*0Sstevel@tonic-gate case 'H': /* just before cursor, saving chars */
563*0Sstevel@tonic-gate d = CTRL('w');
564*0Sstevel@tonic-gate break;
565*0Sstevel@tonic-gate
566*0Sstevel@tonic-gate case 'd':
567*0Sstevel@tonic-gate case 'D':
568*0Sstevel@tonic-gate tp = find_next_word(cursor, eol);
569*0Sstevel@tonic-gate if (tp <= cursor)
570*0Sstevel@tonic-gate continue;
571*0Sstevel@tonic-gate len = tp - cursor;
572*0Sstevel@tonic-gate do_save_buf(save_buf, cursor, len);
573*0Sstevel@tonic-gate memmove(cursor, tp, eol - tp);
574*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor,
575*0Sstevel@tonic-gate eol - len);
576*0Sstevel@tonic-gate eol -= len;
577*0Sstevel@tonic-gate continue;
578*0Sstevel@tonic-gate }
579*0Sstevel@tonic-gate }
580*0Sstevel@tonic-gate switch (d) {
581*0Sstevel@tonic-gate
582*0Sstevel@tonic-gate default:
583*0Sstevel@tonic-gate if ((cursor - buf) < MAX_LINE_SIZE) {
584*0Sstevel@tonic-gate *cursor++ = d;
585*0Sstevel@tonic-gate if (cursor > eol)
586*0Sstevel@tonic-gate eol = cursor;
587*0Sstevel@tonic-gate do_emit(env, d);
588*0Sstevel@tonic-gate }
589*0Sstevel@tonic-gate continue;
590*0Sstevel@tonic-gate
591*0Sstevel@tonic-gate case CTRL('['): /* saw esc. character */
592*0Sstevel@tonic-gate saw_esc = 1;
593*0Sstevel@tonic-gate continue;
594*0Sstevel@tonic-gate
595*0Sstevel@tonic-gate case CTRL('f'): /* move forward one char */
596*0Sstevel@tonic-gate if (cursor < eol)
597*0Sstevel@tonic-gate do_emit(env, *cursor++);
598*0Sstevel@tonic-gate continue;
599*0Sstevel@tonic-gate
600*0Sstevel@tonic-gate case CTRL('a'): /* cursor to beginning of line */
601*0Sstevel@tonic-gate do_emit_chars(env, '\b', cursor - buf);
602*0Sstevel@tonic-gate cursor = buf;
603*0Sstevel@tonic-gate continue;
604*0Sstevel@tonic-gate
605*0Sstevel@tonic-gate case CTRL('e'): /* cursor to end of line */
606*0Sstevel@tonic-gate do_emit_str(env, cursor, eol - cursor);
607*0Sstevel@tonic-gate cursor = eol;
608*0Sstevel@tonic-gate continue;
609*0Sstevel@tonic-gate
610*0Sstevel@tonic-gate
611*0Sstevel@tonic-gate case CTRL('n'): /* Move to next line in buffer */
612*0Sstevel@tonic-gate case CTRL('p'): /* Move to previous line in buffer */
613*0Sstevel@tonic-gate if (d == CTRL('p')) {
614*0Sstevel@tonic-gate if (cur_line <= 0)
615*0Sstevel@tonic-gate continue;
616*0Sstevel@tonic-gate if (my_line == cur_line) {
617*0Sstevel@tonic-gate do_save_buf(save_line, buf, eol - buf);
618*0Sstevel@tonic-gate save_cursor = cursor - buf;
619*0Sstevel@tonic-gate }
620*0Sstevel@tonic-gate cur_line--;
621*0Sstevel@tonic-gate } else {
622*0Sstevel@tonic-gate if (cur_line >= num_lines)
623*0Sstevel@tonic-gate continue;
624*0Sstevel@tonic-gate cur_line++;
625*0Sstevel@tonic-gate if (cur_line == num_lines) {
626*0Sstevel@tonic-gate len = strlen(save_line);
627*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol,
628*0Sstevel@tonic-gate save_line, save_line + save_cursor,
629*0Sstevel@tonic-gate save_line + len);
630*0Sstevel@tonic-gate strcpy(buf, save_line);
631*0Sstevel@tonic-gate eol = buf + len;
632*0Sstevel@tonic-gate cursor = buf + save_cursor;
633*0Sstevel@tonic-gate continue;
634*0Sstevel@tonic-gate }
635*0Sstevel@tonic-gate }
636*0Sstevel@tonic-gate p = history_lines[cur_line];
637*0Sstevel@tonic-gate len = strlen(p);
638*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, p, p, p + len);
639*0Sstevel@tonic-gate strcpy(buf, history_lines[cur_line]);
640*0Sstevel@tonic-gate cursor = buf;
641*0Sstevel@tonic-gate eol = buf + len;
642*0Sstevel@tonic-gate continue;
643*0Sstevel@tonic-gate
644*0Sstevel@tonic-gate case CTRL('o'): /* Insert newline */
645*0Sstevel@tonic-gate continue;
646*0Sstevel@tonic-gate
647*0Sstevel@tonic-gate case CTRL('k'): /* Erase from cursor to eol, saving */
648*0Sstevel@tonic-gate /* chars, at eol, joins two lines */
649*0Sstevel@tonic-gate if (cursor == eol) {
650*0Sstevel@tonic-gate if (cur_line >= num_lines)
651*0Sstevel@tonic-gate continue;
652*0Sstevel@tonic-gate if (cur_line == num_lines - 1) {
653*0Sstevel@tonic-gate p = save_line;
654*0Sstevel@tonic-gate len = strlen(save_line);
655*0Sstevel@tonic-gate num_lines -= 1;
656*0Sstevel@tonic-gate my_line = num_lines;
657*0Sstevel@tonic-gate } else {
658*0Sstevel@tonic-gate cur_line++;
659*0Sstevel@tonic-gate p = history_lines[cur_line];
660*0Sstevel@tonic-gate len = strlen(p);
661*0Sstevel@tonic-gate }
662*0Sstevel@tonic-gate len = min(len, MAX_LINE_SIZE - (eol - buf));
663*0Sstevel@tonic-gate memcpy(eol, p, len);
664*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor,
665*0Sstevel@tonic-gate eol + len);
666*0Sstevel@tonic-gate eol += len;
667*0Sstevel@tonic-gate continue;
668*0Sstevel@tonic-gate }
669*0Sstevel@tonic-gate do_save_buf(save_buf, cursor, eol - cursor);
670*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor,
671*0Sstevel@tonic-gate cursor);
672*0Sstevel@tonic-gate eol = cursor;
673*0Sstevel@tonic-gate continue;
674*0Sstevel@tonic-gate
675*0Sstevel@tonic-gate case CTRL('w'): /* Erase word */
676*0Sstevel@tonic-gate tp = find_prev_word(buf, cursor);
677*0Sstevel@tonic-gate if (tp == cursor)
678*0Sstevel@tonic-gate continue;
679*0Sstevel@tonic-gate len = cursor - tp;
680*0Sstevel@tonic-gate do_save_buf(save_buf, tp, len);
681*0Sstevel@tonic-gate memmove(tp, cursor, eol - cursor);
682*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor - len,
683*0Sstevel@tonic-gate eol - len);
684*0Sstevel@tonic-gate eol -= len;
685*0Sstevel@tonic-gate cursor -= len;
686*0Sstevel@tonic-gate continue;
687*0Sstevel@tonic-gate
688*0Sstevel@tonic-gate case CTRL('u'): /* Erases line, saving chars */
689*0Sstevel@tonic-gate do_save_buf(save_buf, buf, eol - buf);
690*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, buf, buf);
691*0Sstevel@tonic-gate cursor = buf;
692*0Sstevel@tonic-gate eol = buf;
693*0Sstevel@tonic-gate continue;
694*0Sstevel@tonic-gate
695*0Sstevel@tonic-gate case CTRL('y'): /* Insert save buffer before cursor */
696*0Sstevel@tonic-gate len = min(strlen(save_buf),
697*0Sstevel@tonic-gate MAX_LINE_SIZE - (eol - buf));
698*0Sstevel@tonic-gate if (len == 0)
699*0Sstevel@tonic-gate continue;
700*0Sstevel@tonic-gate memmove(cursor + len, cursor, eol - cursor);
701*0Sstevel@tonic-gate memcpy(cursor, save_buf, len);
702*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor + len,
703*0Sstevel@tonic-gate eol + len);
704*0Sstevel@tonic-gate cursor += len;
705*0Sstevel@tonic-gate eol += len;
706*0Sstevel@tonic-gate continue;
707*0Sstevel@tonic-gate
708*0Sstevel@tonic-gate case CTRL('q'): /* Quote next char */
709*0Sstevel@tonic-gate do_quote = 1;
710*0Sstevel@tonic-gate continue;
711*0Sstevel@tonic-gate
712*0Sstevel@tonic-gate case CTRL('l'): /* Display edit buffer */
713*0Sstevel@tonic-gate do_emit(env, '\n');
714*0Sstevel@tonic-gate for (i = 0; i < num_lines; i++) {
715*0Sstevel@tonic-gate do_emit_str(env, history_lines[i],
716*0Sstevel@tonic-gate strlen(history_lines[i]));
717*0Sstevel@tonic-gate do_emit(env, '\n');
718*0Sstevel@tonic-gate }
719*0Sstevel@tonic-gate redraw_line(env, buf, buf, buf, buf, cursor, eol);
720*0Sstevel@tonic-gate continue;
721*0Sstevel@tonic-gate
722*0Sstevel@tonic-gate case CTRL('r'): /* redraw line */
723*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor, eol);
724*0Sstevel@tonic-gate continue;
725*0Sstevel@tonic-gate
726*0Sstevel@tonic-gate case CTRL('c'): /* Exit script editor */
727*0Sstevel@tonic-gate continue;
728*0Sstevel@tonic-gate
729*0Sstevel@tonic-gate case CTRL('b'): /* backup cursor */
730*0Sstevel@tonic-gate if (cursor <= buf)
731*0Sstevel@tonic-gate continue;
732*0Sstevel@tonic-gate cursor--;
733*0Sstevel@tonic-gate do_emit(env, '\b');
734*0Sstevel@tonic-gate continue;
735*0Sstevel@tonic-gate
736*0Sstevel@tonic-gate case CTRL('h'): /* Backspace */
737*0Sstevel@tonic-gate case 0x7f: /* DEL */
738*0Sstevel@tonic-gate if (cursor <= buf)
739*0Sstevel@tonic-gate continue;
740*0Sstevel@tonic-gate memmove(cursor - 1, cursor, eol - cursor);
741*0Sstevel@tonic-gate redraw_line(env, buf, cursor, eol, buf, cursor - 1,
742*0Sstevel@tonic-gate eol - 1);
743*0Sstevel@tonic-gate cursor--;
744*0Sstevel@tonic-gate eol--;
745*0Sstevel@tonic-gate continue;
746*0Sstevel@tonic-gate
747*0Sstevel@tonic-gate case '\r':
748*0Sstevel@tonic-gate case '\n':
749*0Sstevel@tonic-gate *eol = '\0';
750*0Sstevel@tonic-gate do_emit(env, '\n');
751*0Sstevel@tonic-gate break;
752*0Sstevel@tonic-gate }
753*0Sstevel@tonic-gate break;
754*0Sstevel@tonic-gate }
755*0Sstevel@tonic-gate add_line_to_history(env, buf);
756*0Sstevel@tonic-gate ioctl(fileno(stdin), TCSETA, &savetermio);
757*0Sstevel@tonic-gate push_string(env, buf, strlen(buf));
758*0Sstevel@tonic-gate }
759*0Sstevel@tonic-gate
760*0Sstevel@tonic-gate static void
set_prompt(fcode_env_t * env)761*0Sstevel@tonic-gate set_prompt(fcode_env_t *env)
762*0Sstevel@tonic-gate {
763*0Sstevel@tonic-gate char *prompt;
764*0Sstevel@tonic-gate
765*0Sstevel@tonic-gate if ((prompt = parse_a_string(env, NULL)) != NULL)
766*0Sstevel@tonic-gate strncpy(prompt_string, prompt, sizeof (prompt_string));
767*0Sstevel@tonic-gate }
768*0Sstevel@tonic-gate
769*0Sstevel@tonic-gate #pragma init(_init)
770*0Sstevel@tonic-gate
771*0Sstevel@tonic-gate static void
_init(void)772*0Sstevel@tonic-gate _init(void)
773*0Sstevel@tonic-gate {
774*0Sstevel@tonic-gate fcode_env_t *env = initial_env;
775*0Sstevel@tonic-gate
776*0Sstevel@tonic-gate ASSERT(env);
777*0Sstevel@tonic-gate NOTICE;
778*0Sstevel@tonic-gate
779*0Sstevel@tonic-gate FORTH(IMMEDIATE, "if", do_if);
780*0Sstevel@tonic-gate FORTH(IMMEDIATE, "else", do_else);
781*0Sstevel@tonic-gate FORTH(IMMEDIATE, "then", do_then);
782*0Sstevel@tonic-gate FORTH(IMMEDIATE, "case", bcase);
783*0Sstevel@tonic-gate FORTH(IMMEDIATE, "of", do_of);
784*0Sstevel@tonic-gate FORTH(IMMEDIATE, "endof", do_else);
785*0Sstevel@tonic-gate FORTH(IMMEDIATE, "endcase", bendcase);
786*0Sstevel@tonic-gate FORTH(IMMEDIATE, "value", value);
787*0Sstevel@tonic-gate FORTH(IMMEDIATE, "variable", variable);
788*0Sstevel@tonic-gate FORTH(IMMEDIATE, "constant", constant);
789*0Sstevel@tonic-gate FORTH(IMMEDIATE, "defer", defer);
790*0Sstevel@tonic-gate FORTH(IMMEDIATE, "buffer:", buffer_colon);
791*0Sstevel@tonic-gate FORTH(IMMEDIATE, "field", field);
792*0Sstevel@tonic-gate FORTH(IMMEDIATE, "struct", zero);
793*0Sstevel@tonic-gate FORTH(IMMEDIATE, "to", action_one);
794*0Sstevel@tonic-gate FORTH(IMMEDIATE, "d#", temp_decimal);
795*0Sstevel@tonic-gate FORTH(IMMEDIATE, "h#", temp_hex);
796*0Sstevel@tonic-gate FORTH(IMMEDIATE, "b#", temp_binary);
797*0Sstevel@tonic-gate FORTH(0, "decimal", do_decimal);
798*0Sstevel@tonic-gate FORTH(0, "hex", do_hex);
799*0Sstevel@tonic-gate FORTH(0, "binary", do_binary);
800*0Sstevel@tonic-gate FORTH(0, "clear", do_clear);
801*0Sstevel@tonic-gate FORTH(IMMEDIATE, "bye", bye);
802*0Sstevel@tonic-gate FORTH(0, "interact", do_interact);
803*0Sstevel@tonic-gate FORTH(IMMEDIATE, "resume", do_resume);
804*0Sstevel@tonic-gate FORTH(0, "fload", fload);
805*0Sstevel@tonic-gate FORTH(0, "load", load);
806*0Sstevel@tonic-gate FORTH(0, "read-line", read_line);
807*0Sstevel@tonic-gate FORTH(0, "set-prompt", set_prompt);
808*0Sstevel@tonic-gate }
809