Make use of prototypes to silence warnings.

Change include() so it will be able to load files with forth code,
instead of just builtins. Remove #@- from the include section of the
help file, since they don't work in the new version of include, unless
BOOT_FORTH is not defined.

Change bf_run() so it will return the result returned by ficlExec(). Also,
make bf_run() push "interpret" to be executed by ficlExec(), since ficlExec()
doesn't do it by itself. (Things worked previously because nothing
recursed through ficlExec() by the way of bf_run()).

Change/extend comments on builtin behavior.

Search for "interpret" at the end of bf_init(), so /boot/boot.4th can
provide it's own version.

Remove dead code.
This commit is contained in:
dcs 1999-02-04 17:06:46 +00:00
parent 60ace12c39
commit 755c131c9f
4 changed files with 84 additions and 37 deletions

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bootstrap.h,v 1.18 1999/01/16 03:25:24 jdp Exp $
* $Id: bootstrap.h,v 1.19 1999/01/22 23:50:13 msmith Exp $
*/
#include <sys/types.h>
@ -61,6 +61,10 @@ extern int include(char *filename);
/* interp_parse.c */
extern int parse(int *argc, char ***argv, char *str);
/* interp_forth.c */
extern void bf_init(void);
extern int bf_run(char *line);
/* boot.c */
extern int autoboot(int delay, char *prompt);
extern void autoboot_maybe(void);
@ -71,6 +75,9 @@ extern void hexdump(caddr_t region, size_t len);
extern size_t strlenout(vm_offset_t str);
extern char *strdupout(vm_offset_t str);
/* bcache.c */
extern int bcache_init(int nblks, size_t bsize);
/*
* Disk block cache
*/

View File

@ -260,16 +260,6 @@
The entire contents of <filename> are read into memory before executing
commands, so it is safe to source a file from removable media.
A number of modifiers may be prefixed to commands within a script file
to alter their behaviour:
# Ignore the line (use for comments).
@ Suppresses the printing of the command when executed.
- Prevents the script from terminating if the command returns
an error.
################################################################################
# Tread DRead input from the terminal

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: interp.c,v 1.12 1999/01/15 00:31:45 abial Exp $
* $Id: interp.c,v 1.13 1999/01/22 23:50:13 msmith Exp $
*/
/*
* Simple commandline interpreter, toplevel and misc.
@ -170,9 +170,15 @@ include(char *filename)
{
struct includeline *script, *se, *sp;
char input[256]; /* big enough? */
#ifdef BOOT_FORTH
int res;
char *cp;
int fd, line;
#else
int argc,res;
char **argv, *cp;
int fd, flags, line;
#endif
if (((fd = open(filename, O_RDONLY)) == -1)) {
sprintf(command_errbuf,"can't open '%s': %s\n", filename, strerror(errno));
@ -187,6 +193,9 @@ include(char *filename)
while (fgetstr(input, sizeof(input), fd) > 0) {
line++;
#ifdef BOOT_FORTH
cp = input;
#else
flags = 0;
/* Discard comments */
if (input[0] == '#')
@ -202,11 +211,14 @@ include(char *filename)
cp++;
flags |= SL_IGNOREERR;
}
#endif
/* Allocate script line structure and copy line, flags */
sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
sp->text = (char *)sp + sizeof(struct includeline);
strcpy(sp->text, cp);
#ifndef BOOT_FORTH
sp->flags = flags;
#endif
sp->line = line;
sp->next = NULL;
@ -222,10 +234,21 @@ include(char *filename)
/*
* Execute the script
*/
#ifndef BOOT_FORTH
argv = NULL;
#endif
res = CMD_OK;
for (sp = script; sp != NULL; sp = sp->next) {
#ifdef BOOT_FORTH
res = bf_run(sp->text);
if (res != VM_OUTOFTEXT) {
sprintf(command_errbuf, "Error while including %s:\n%s", filename, sp->text);
res = CMD_ERROR;
break;
} else
res = CMD_OK;
#else
/* print if not being quiet */
if (!(sp->flags & SL_QUIET)) {
prompt();
@ -249,9 +272,12 @@ include(char *filename)
res=CMD_ERROR;
break;
}
#endif
}
#ifndef BOOT_FORTH
if (argv != NULL)
free(argv);
#endif
while(script != NULL) {
se = script;
script = script->next;

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: interp_forth.c,v 1.10 1999/01/22 23:50:14 msmith Exp $
* $Id: interp_forth.c,v 1.11 1999/01/28 06:33:03 jkh Exp $
*/
#include <sys/param.h> /* to pick up __FreeBSD_version */
@ -54,6 +54,7 @@ extern char bootprog_rev[];
*/
FICL_VM *bf_vm;
FICL_WORD *pInterp;
/*
* Shim for taking commands from BF and passing them out to 'standard'
@ -125,17 +126,7 @@ bf_command(FICL_VM *vm)
if (!parse(&argc, &argv, line)) {
result = (cmd)(argc, argv);
free(argv);
/* ** Let's deal with it elsewhere **
if(result != 0) {
vmTextOut(vm,argv[0],0);
vmTextOut(vm,": ",0);
vmTextOut(vm,command_errmsg,1);
}
*/
} else {
/* ** Let's deal with it elsewhere **
vmTextOut(vm, "parse error\n", 1);
*/
result=BF_PARSE;
}
free(line);
@ -152,18 +143,18 @@ bf_command(FICL_VM *vm)
* being interpreted.
*
* There is one major problem with builtins that cannot be overcome
* in anyway, except by outlawing it, such as done below. We want
* builtins to behave differently depending on whether they have been
* compiled or they are being interpreted. Notice that this is *not*
* the current state. For example:
* in anyway, except by outlawing it. We want builtins to behave
* differently depending on whether they have been compiled or they
* are being interpreted. Notice that this is *not* the interpreter's
* current state. For example:
*
* : example ls ; immediate
* : problem example ;
* example
* : problem example ; \ "ls" gets executed while compiling
* example \ "ls" gets executed while interpreting
*
* Notice that the current state is different in the two invocations
* of "example", but, in both cases, "ls" has been *compiled in*, which
* is what we really want.
* Notice that, though the current state is different in the two
* invocations of "example", in both cases "ls" has been
* *compiled in*, which is what we really want.
*
* The problem arises when you tick the builtin. For example:
*
@ -174,16 +165,37 @@ bf_command(FICL_VM *vm)
*
* We have no way, when we get EXECUTEd, of knowing what our behavior
* should be. Thus, our only alternative is to "outlaw" this. See RFI
* 0007, and ANS Forth Standard's appendix D, item 6.7.
* 0007, and ANS Forth Standard's appendix D, item 6.7 for a related
* problem, concerning compile semantics.
*
* The problem is compounded by the fact that ' builtin CATCH is valid
* The problem is compounded by the fact that "' builtin CATCH" is valid
* and desirable. The only solution is to create an intermediary word.
* For example:
*
* : my-ls ls ;
* : example ['] my-ls catch ;
*
* As the this definition is particularly tricky, and it's side effects
* So, with the below implementation, here is a summary of the behavior
* of builtins:
*
* ls -l \ "interpret" behavior, ie,
* \ takes parameters from TIB
* : ex-1 s" -l" 1 ls ; \ "compile" behavior, ie,
* \ takes parameters from the stack
* : ex-2 ['] ls catch ; immediate \ undefined behavior
* : ex-3 ['] ls catch ; \ undefined behavior
* ex-2 ex-3 \ "interpret" behavior,
* \ catch works
* : ex-4 ex-2 ; \ "compile" behavior,
* \ catch does not work
* : ex-5 ex-3 ; immediate \ same as ex-2
* : ex-6 ex-3 ; \ same as ex-3
* : ex-7 ['] ex-1 catch ; \ "compile" behavior,
* \ catch works
* : ex-8 postpone ls ; immediate \ same as ex-2
* : ex-9 postpone ls ; \ same as ex-3
*
* As the definition below is particularly tricky, and it's side effects
* must be well understood by those playing with it, I'll be heavy on
* the comments.
*
@ -243,17 +255,27 @@ bf_init(void)
(void)ficlExecFD(bf_vm, fd);
close(fd);
}
/* Do this last, so /boot/boot.4th can change it */
pInterp = ficlLookup("interpret");
}
/*
* Feed a line of user input to the Forth interpreter
*/
void
int
bf_run(char *line)
{
int result;
CELL id;
id = bf_vm->sourceID;
bf_vm->sourceID.i = -1;
vmPushIP(bf_vm, &pInterp);
result = ficlExec(bf_vm, line, -1);
vmPopIP(bf_vm);
bf_vm->sourceID = id;
DEBUG("ficlExec '%s' = %d", line, result);
switch (result) {
case VM_OUTOFTEXT:
@ -278,4 +300,6 @@ bf_run(char *line)
if (result == VM_USEREXIT)
panic("interpreter exit");
setenv("interpret", bf_vm->state ? "" : "ok", 1);
return result;
}