interp_forth.c revision 40929
1/* 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $Id: interp_forth.c,v 1.2 1998/11/04 03:41:09 msmith Exp $ 27 */ 28 29#include <stand.h> 30#include "bootstrap.h" 31#include "ficl.h" 32 33/* 34 * BootForth Interface to Ficl Forth interpreter. 35 */ 36 37static FICL_VM *bf_vm; 38 39/* 40 * Shim for taking commands from BF and passing them out to 'standard' 41 * argv/argc command functions. 42 */ 43static void 44bf_command(FICL_VM *vm) 45{ 46 struct bootblk_command **cmdp; 47 bootblk_cmd_t *cmd; 48 char *name, *line; 49 FICL_STRING *tail = (FICL_STRING *)vm->pad; 50 int argc, result; 51 char **argv; 52 53 /* Get the name of the current word */ 54 name = vm->runningWord->name; 55 56 /* Find our command structure */ 57 SET_FOREACH(cmdp, Xcommand_set) { 58 if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name)) 59 cmd = (*cmdp)->c_fn; 60 } 61 if (cmd == NULL) 62 panic("callout for unknown command '%s'", name); 63 64 /* Get remainder of invocation */ 65 vmGetString(vm, tail, '\n'); 66 67 /* XXX This is grostic */ 68 line = malloc(strlen(name) + strlen(tail->text) + 2); 69 sprintf(line, "%s %s", name, tail->text); 70 command_errmsg = command_errbuf; 71 command_errbuf[0] = 0; 72 if (!parse(&argc, &argv, line)) { 73 result = (cmd)(argc, argv); 74 free(argv); 75 if (result != 0) { 76 strcpy(command_errmsg, vm->pad); 77 vmTextOut(vm, vm->pad, 1); 78 } 79 } else { 80 vmTextOut(vm, "parse error\n", 1); 81 } 82 free(line); 83} 84 85/* 86 * Initialise the Forth interpreter, create all our commands as words. 87 */ 88void 89bf_init(void) 90{ 91 struct bootblk_command **cmdp; 92 93 ficlInitSystem(4000); /* Default dictionary ~4000 cells */ 94 bf_vm = ficlNewVM(); 95 96 /* make all commands appear as Forth words */ 97 SET_FOREACH(cmdp, Xcommand_set) 98 ficlBuild((*cmdp)->c_name, bf_command, FW_DEFAULT); 99 /* run the init word from softcore */ 100 ficlExec(bf_vm, "init"); 101} 102 103/* 104 * Feed a line of user input to the Forth interpreter 105 */ 106void 107bf_run(char *line) 108{ 109 int result; 110 111 result = ficlExec(bf_vm, line); 112 if (result == VM_USEREXIT) 113 panic("interpreter exit"); 114} 115