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:
parent
099d325dd5
commit
47749087ac
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user