interp_forth.c revision 40984
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.5 1998/11/06 03:50:44 msmith Exp $ 27 */ 28 29#include <stand.h> 30#include "bootstrap.h" 31#include "ficl.h" 32 33/* #define BFORTH_DEBUG */ 34 35#ifdef BFORTH_DEBUG 36# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __FUNCTION__ , ## args) 37#else 38# define DEBUG(fmt, args...) 39#endif 40 41/* 42 * BootForth Interface to Ficl Forth interpreter. 43 */ 44 45static FICL_VM *bf_vm; 46 47/* 48 * Shim for taking commands from BF and passing them out to 'standard' 49 * argv/argc command functions. 50 */ 51static void 52bf_command(FICL_VM *vm) 53{ 54 char *name, *line, *tail, *cp; 55 int len; 56 struct bootblk_command **cmdp; 57 bootblk_cmd_t *cmd; 58 int argc, result; 59 char **argv; 60 61 /* Get the name of the current word */ 62 name = vm->runningWord->name; 63 64 /* Find our command structure */ 65 cmd == NULL; 66 SET_FOREACH(cmdp, Xcommand_set) { 67 if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name)) 68 cmd = (*cmdp)->c_fn; 69 } 70 if (cmd == NULL) 71 panic("callout for unknown command '%s'", name); 72 73 /* Get remainder of invocation */ 74 tail = vmGetInBuf(vm); 75 for (cp = tail, len = 0; *cp != 0 && *cp != '\n'; cp++, len++) 76 ; 77 78 line = malloc(strlen(name) + len + 2); 79 strcpy(line, name); 80 if (len > 0) { 81 strcat(line, " "); 82 strncat(line, tail, len); 83 vmUpdateTib(vm, tail + len); 84 } 85 DEBUG("cmd '%s'", line); 86 87 command_errmsg = command_errbuf; 88 command_errbuf[0] = 0; 89 if (!parse(&argc, &argv, line)) { 90 result = (cmd)(argc, argv); 91 free(argv); 92 if (result != 0) { 93 strcpy(command_errmsg, vm->pad); 94 vmTextOut(vm, vm->pad, 1); 95 } 96 } else { 97 vmTextOut(vm, "parse error\n", 1); 98 } 99 free(line); 100} 101 102/* 103 * Initialise the Forth interpreter, create all our commands as words. 104 */ 105void 106bf_init(void) 107{ 108 struct bootblk_command **cmdp; 109 110 ficlInitSystem(4000); /* Default dictionary ~4000 cells */ 111 bf_vm = ficlNewVM(); 112 113 /* make all commands appear as Forth words */ 114 SET_FOREACH(cmdp, Xcommand_set) 115 ficlBuild((*cmdp)->c_name, bf_command, FW_DEFAULT); 116 /* run the init word from softcore */ 117 ficlExec(bf_vm, "init"); 118} 119 120/* 121 * Feed a line of user input to the Forth interpreter 122 */ 123void 124bf_run(char *line) 125{ 126 int result; 127 128 result = ficlExec(bf_vm, line); 129 DEBUG("ficlExec '%s' = %d", line, result); 130 131 if (result == VM_USEREXIT) 132 panic("interpreter exit"); 133} 134