summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/boot/sys/boot/common/interp_forth.c395
1 files changed, 201 insertions, 194 deletions
diff --git a/usr/src/boot/sys/boot/common/interp_forth.c b/usr/src/boot/sys/boot/common/interp_forth.c
index b3eebaede4..280bbee732 100644
--- a/usr/src/boot/sys/boot/common/interp_forth.c
+++ b/usr/src/boot/sys/boot/common/interp_forth.c
@@ -37,9 +37,9 @@ extern unsigned bootprog_rev;
/* #define BFORTH_DEBUG */
#ifdef BFORTH_DEBUG
-# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
+#define DEBUG(fmt, args...) printf("%s: " fmt "\n", __func__, ## args)
#else
-# define DEBUG(fmt, args...)
+#define DEBUG(fmt, args...)
#endif
/*
@@ -47,7 +47,7 @@ extern unsigned bootprog_rev;
* elsewhere, possibly bootstrap.h. For now, just this code, used
* just in this file, it is getting defined.
*/
-#define BF_PARSE 100
+#define BF_PARSE 100
/*
* FreeBSD loader default dictionary cells
@@ -71,94 +71,100 @@ ficlVm *bf_vm;
static void
bf_command(ficlVm *vm)
{
- char *name, *line, *tail, *cp;
- size_t len;
- struct bootblk_command **cmdp;
- bootblk_cmd_t *cmd;
- int nstrings, i;
- int argc, result;
- char **argv;
-
- /* Get the name of the current word */
- name = vm->runningWord->name;
-
- /* Find our command structure */
- cmd = NULL;
- SET_FOREACH(cmdp, Xcommand_set) {
- if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name))
- cmd = (*cmdp)->c_fn;
- }
- if (cmd == NULL)
- panic("callout for unknown command '%s'", name);
-
- /* Check whether we have been compiled or are being interpreted */
- if (ficlStackPopInteger(ficlVmGetDataStack(vm))) {
+ char *name, *line, *tail, *cp;
+ size_t len;
+ struct bootblk_command **cmdp;
+ bootblk_cmd_t *cmd;
+ int nstrings, i;
+ int argc, result;
+ char **argv;
+
+ /* Get the name of the current word */
+ name = vm->runningWord->name;
+
+ /* Find our command structure */
+ cmd = NULL;
+ SET_FOREACH(cmdp, Xcommand_set) {
+ if (((*cmdp)->c_name != NULL) &&
+ strcmp(name, (*cmdp)->c_name) == 0)
+ cmd = (*cmdp)->c_fn;
+ }
+ if (cmd == NULL)
+ panic("callout for unknown command '%s'", name);
+
+ /* Check whether we have been compiled or are being interpreted */
+ if (ficlStackPopInteger(ficlVmGetDataStack(vm))) {
+ /*
+ * Get parameters from stack, in the format:
+ * an un ... a2 u2 a1 u1 n --
+ * Where n is the number of strings, a/u are pairs of
+ * address/size for strings, and they will be concatenated
+ * in LIFO order.
+ */
+ nstrings = ficlStackPopInteger(ficlVmGetDataStack(vm));
+ for (i = 0, len = 0; i < nstrings; i++) {
+ ficlStack *stack = ficlVmGetDataStack(vm);
+ len += ficlStackFetch(stack, i * 2).i + 1;
+ }
+ line = malloc(strlen(name) + len + 1);
+ strcpy(line, name);
+
+ if (nstrings)
+ for (i = 0; i < nstrings; i++) {
+ ficlStack *stack = ficlVmGetDataStack(vm);
+
+ len = ficlStackPopInteger(stack);
+ cp = ficlStackPopPointer(stack);
+ strcat(line, " ");
+ strncat(line, cp, len);
+ }
+ } else {
+ /* Get remainder of invocation */
+ tail = ficlVmGetInBuf(vm);
+
+ len = 0;
+ cp = tail;
+ for (; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++)
+ len++;
+
+ line = malloc(strlen(name) + len + 2);
+ strcpy(line, name);
+ if (len > 0) {
+ strcat(line, " ");
+ strncat(line, tail, len);
+ ficlVmUpdateTib(vm, tail + len);
+ }
+ }
+ DEBUG("cmd '%s'", line);
+
+ command_errmsg = command_errbuf;
+ command_errbuf[0] = 0;
+ if (!parse(&argc, &argv, line)) {
+ result = (cmd)(argc, argv);
+ free(argv);
+ } else {
+ result = BF_PARSE;
+ }
+
+ switch (result) {
+ case CMD_CRIT:
+ printf("%s\n", command_errmsg);
+ command_errmsg = NULL;
+ break;
+ case CMD_FATAL:
+ panic("%s\n", command_errmsg);
+ }
+
+ free(line);
/*
- * Get parameters from stack, in the format:
- * an un ... a2 u2 a1 u1 n --
- * Where n is the number of strings, a/u are pairs of
- * address/size for strings, and they will be concatenated
- * in LIFO order.
+ * If there was error during nested ficlExec(), we may no longer have
+ * valid environment to return. Throw all exceptions from here.
*/
- nstrings = ficlStackPopInteger(ficlVmGetDataStack(vm));
- for (i = 0, len = 0; i < nstrings; i++)
- len += ficlStackFetch(ficlVmGetDataStack(vm), i * 2).i + 1;
- line = malloc(strlen(name) + len + 1);
- strcpy(line, name);
-
- if (nstrings)
- for (i = 0; i < nstrings; i++) {
- len = ficlStackPopInteger(ficlVmGetDataStack(vm));
- cp = ficlStackPopPointer(ficlVmGetDataStack(vm));
- strcat(line, " ");
- strncat(line, cp, len);
- }
- } else {
- /* Get remainder of invocation */
- tail = ficlVmGetInBuf(vm);
-
- len = 0;
- for (cp = tail; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++)
- len++;
-
- line = malloc(strlen(name) + len + 2);
- strcpy(line, name);
- if (len > 0) {
- strcat(line, " ");
- strncat(line, tail, len);
- ficlVmUpdateTib(vm, tail + len);
- }
- }
- DEBUG("cmd '%s'", line);
-
- command_errmsg = command_errbuf;
- command_errbuf[0] = 0;
- if (!parse(&argc, &argv, line)) {
- result = (cmd)(argc, argv);
- free(argv);
- } else {
- result = BF_PARSE;
- }
-
- switch (result) {
- case CMD_CRIT:
- printf("%s\n", command_errmsg);
- command_errmsg = NULL;
- break;
- case CMD_FATAL:
- panic("%s\n", command_errmsg);
- }
-
- free(line);
- /*
- * If there was error during nested ficlExec(), we may no longer have
- * valid environment to return. Throw all exceptions from here.
- */
- if (result != CMD_OK)
- ficlVmThrow(vm, result);
-
- /* This is going to be thrown!!! */
- ficlStackPushInteger(ficlVmGetDataStack(vm),result);
+ if (result != CMD_OK)
+ ficlVmThrow(vm, result);
+
+ /* This is going to be thrown!!! */
+ ficlStackPushInteger(ficlVmGetDataStack(vm), result);
}
/*
@@ -229,25 +235,25 @@ bf_command(ficlVm *vm)
* (if you edit this definition, pay attention to trailing spaces after
* each word -- I warned you! :-) )
*/
-#define BUILTIN_CONSTRUCTOR \
+#define BUILTIN_CONSTRUCTOR \
": builtin: " \
- ">in @ " /* save the tib index pointer */ \
- "' " /* get next word's xt */ \
- "swap >in ! " /* point again to next word */ \
- "create " /* create a new definition of the next word */ \
- ", " /* save previous definition's xt */ \
- "immediate " /* make the new definition an immediate word */ \
+ ">in @ " /* save the tib index pointer */ \
+ "' " /* get next word's xt */ \
+ "swap >in ! " /* point again to next word */ \
+ "create " /* create a new definition of the next word */ \
+ ", " /* save previous definition's xt */ \
+ "immediate " /* make the new definition an immediate word */ \
\
- "does> " /* Now, the *new* definition will: */ \
- "state @ if " /* if in compiling state: */ \
- "1 postpone literal " /* pass 1 flag to indicate compile */ \
- "@ compile, " /* compile in previous definition */ \
- "postpone throw " /* throw stack-returned result */ \
- "else " /* if in interpreting state: */ \
- "0 swap " /* pass 0 flag to indicate interpret */ \
- "@ execute " /* call previous definition */ \
- "throw " /* throw stack-returned result */ \
- "then ; "
+ "does> " /* Now, the *new* definition will: */ \
+ "state @ if " /* if in compiling state: */ \
+ "1 postpone literal " /* pass 1 flag to indicate compile */ \
+ "@ compile, " /* compile in previous definition */ \
+ "postpone throw " /* throw stack-returned result */ \
+ "else " /* if in interpreting state: */ \
+ "0 swap " /* pass 0 flag to indicate interpret */ \
+ "@ execute " /* call previous definition */ \
+ "throw " /* throw stack-returned result */ \
+ "then ; "
/*
* Initialise the Forth interpreter, create all our commands as words.
@@ -255,72 +261,73 @@ bf_command(ficlVm *vm)
void
bf_init(char *rc)
{
- struct bootblk_command **cmdp;
- char create_buf[41]; /* 31 characters-long builtins */
- int fd, rv;
- ficlDictionary *dict;
- ficlDictionary *env;
-
- fsi = malloc(sizeof(ficlSystemInformation));
- ficlSystemInformationInitialize(fsi);
- fsi->dictionarySize = BF_DICTSIZE;
-
- bf_sys = ficlSystemCreate(fsi);
- bf_vm = ficlSystemCreateVm(bf_sys);
-
- /* Put all private definitions in a "builtins" vocabulary */
- rv = ficlVmEvaluate(bf_vm, "vocabulary builtins also builtins definitions");
- if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
- panic("error interpreting forth: %d\n", rv);
- }
-
- /* Builtin constructor word */
- rv = ficlVmEvaluate(bf_vm, BUILTIN_CONSTRUCTOR);
- if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
- panic("error interpreting forth: %d\n", rv);
- }
-
- /* make all commands appear as Forth words */
- dict = ficlSystemGetDictionary(bf_sys);
- SET_FOREACH(cmdp, Xcommand_set) {
- ficlDictionaryAppendPrimitive(dict, (char *)(*cmdp)->c_name,
- bf_command, FICL_WORD_DEFAULT);
- rv = ficlVmEvaluate(bf_vm, "forth definitions builtins");
+ struct bootblk_command **cmdp;
+ char create_buf[41]; /* 31 characters-long builtins */
+ int fd, rv;
+ ficlDictionary *dict;
+ ficlDictionary *env;
+
+ fsi = malloc(sizeof (ficlSystemInformation));
+ ficlSystemInformationInitialize(fsi);
+ fsi->dictionarySize = BF_DICTSIZE;
+
+ bf_sys = ficlSystemCreate(fsi);
+ bf_vm = ficlSystemCreateVm(bf_sys);
+
+ /* Put all private definitions in a "builtins" vocabulary */
+ rv = ficlVmEvaluate(bf_vm,
+ "vocabulary builtins also builtins definitions");
if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
panic("error interpreting forth: %d\n", rv);
}
- sprintf(create_buf, "builtin: %s", (*cmdp)->c_name);
- rv = ficlVmEvaluate(bf_vm, create_buf);
+
+ /* Builtin constructor word */
+ rv = ficlVmEvaluate(bf_vm, BUILTIN_CONSTRUCTOR);
if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
panic("error interpreting forth: %d\n", rv);
}
- rv = ficlVmEvaluate(bf_vm, "builtins definitions");
+
+ /* make all commands appear as Forth words */
+ dict = ficlSystemGetDictionary(bf_sys);
+ SET_FOREACH(cmdp, Xcommand_set) {
+ ficlDictionaryAppendPrimitive(dict, (char *)(*cmdp)->c_name,
+ bf_command, FICL_WORD_DEFAULT);
+ rv = ficlVmEvaluate(bf_vm, "forth definitions builtins");
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+ sprintf(create_buf, "builtin: %s", (*cmdp)->c_name);
+ rv = ficlVmEvaluate(bf_vm, create_buf);
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+ rv = ficlVmEvaluate(bf_vm, "builtins definitions");
+ if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
+ panic("error interpreting forth: %d\n", rv);
+ }
+ }
+ rv = ficlVmEvaluate(bf_vm, "only forth definitions");
if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
panic("error interpreting forth: %d\n", rv);
}
- }
- rv = ficlVmEvaluate(bf_vm, "only forth definitions");
- if (rv != FICL_VM_STATUS_OUT_OF_TEXT) {
- panic("error interpreting forth: %d\n", rv);
- }
-
- /*
- * Export some version numbers so that code can detect the loader/host
- * version
- */
- env = ficlSystemGetEnvironment(bf_sys);
- ficlDictionarySetConstant(env, "loader_version", bootprog_rev);
-
- /* try to load and run init file if present */
- if (rc == NULL)
- rc = "/boot/forth/boot.4th";
- if (*rc != '\0') {
- fd = open(rc, O_RDONLY);
- if (fd != -1) {
- (void)ficlExecFD(bf_vm, fd);
- close(fd);
+
+ /*
+ * Export some version numbers so that code can detect the loader/host
+ * version
+ */
+ env = ficlSystemGetEnvironment(bf_sys);
+ ficlDictionarySetConstant(env, "loader_version", bootprog_rev);
+
+ /* try to load and run init file if present */
+ if (rc == NULL)
+ rc = "/boot/forth/boot.4th";
+ if (*rc != '\0') {
+ fd = open(rc, O_RDONLY);
+ if (fd != -1) {
+ (void) ficlExecFD(bf_vm, fd);
+ close(fd);
+ }
}
- }
}
/*
@@ -329,39 +336,39 @@ bf_init(char *rc)
int
bf_run(char *line)
{
- int result;
- ficlString s;
-
- FICL_STRING_SET_FROM_CSTRING(s, line);
- result = ficlVmExecuteString(bf_vm, s);
-
- DEBUG("ficlExec '%s' = %d", line, result);
- switch (result) {
- case FICL_VM_STATUS_OUT_OF_TEXT:
- case FICL_VM_STATUS_ABORTQ:
- case FICL_VM_STATUS_QUIT:
- case FICL_VM_STATUS_ERROR_EXIT:
- break;
- case FICL_VM_STATUS_USER_EXIT:
- printf("No where to leave to!\n");
- break;
- case FICL_VM_STATUS_ABORT:
- printf("Aborted!\n");
- break;
- case BF_PARSE:
- printf("Parse error!\n");
- break;
- default:
- if (command_errmsg != NULL) {
- printf("%s\n", command_errmsg);
- command_errmsg = NULL;
+ int result;
+ ficlString s;
+
+ FICL_STRING_SET_FROM_CSTRING(s, line);
+ result = ficlVmExecuteString(bf_vm, s);
+
+ DEBUG("ficlExec '%s' = %d", line, result);
+ switch (result) {
+ case FICL_VM_STATUS_OUT_OF_TEXT:
+ case FICL_VM_STATUS_ABORTQ:
+ case FICL_VM_STATUS_QUIT:
+ case FICL_VM_STATUS_ERROR_EXIT:
+ break;
+ case FICL_VM_STATUS_USER_EXIT:
+ printf("No where to leave to!\n");
+ break;
+ case FICL_VM_STATUS_ABORT:
+ printf("Aborted!\n");
+ break;
+ case BF_PARSE:
+ printf("Parse error!\n");
+ break;
+ default:
+ if (command_errmsg != NULL) {
+ printf("%s\n", command_errmsg);
+ command_errmsg = NULL;
+ }
}
- }
- /* bye is same as reboot and will behave depending on platform */
- if (result == FICL_VM_STATUS_USER_EXIT)
- bf_run("reboot");
- setenv("interpret", bf_vm->state ? "" : "ok", 1);
+ /* bye is same as reboot and will behave depending on platform */
+ if (result == FICL_VM_STATUS_USER_EXIT)
+ bf_run("reboot");
+ setenv("interpret", bf_vm->state ? "" : "ok", 1);
- return (result);
+ return (result);
}