aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2019-06-22 12:19:13 -0700
committerPaul Gilbert2019-06-22 14:40:50 -0700
commitbad3ecd643132a09422117b63a687bf758139c01 (patch)
tree3e3af6d0c6085402c428f40adb23d2572aff3137
parent62eb0be065cc2bd911d3e14f4b6356f3081b7817 (diff)
downloadscummvm-rg350-bad3ecd643132a09422117b63a687bf758139c01.tar.gz
scummvm-rg350-bad3ecd643132a09422117b63a687bf758139c01.tar.bz2
scummvm-rg350-bad3ecd643132a09422117b63a687bf758139c01.zip
GLK: ALAN2: Create jump context system to replace original setjmp
This is basically a simplified version of the ScummVM coroutines, since we just need the ability to consistently break out to the main game loop when a call is made to the error method
-rw-r--r--engines/glk/alan2/jumps.h70
-rw-r--r--engines/glk/alan2/main.cpp59
-rw-r--r--engines/glk/alan2/main.h7
-rw-r--r--engines/glk/alan2/parse.cpp190
-rw-r--r--engines/glk/alan2/parse.h4
5 files changed, 221 insertions, 109 deletions
diff --git a/engines/glk/alan2/jumps.h b/engines/glk/alan2/jumps.h
new file mode 100644
index 0000000000..b477354179
--- /dev/null
+++ b/engines/glk/alan2/jumps.h
@@ -0,0 +1,70 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GLK_ALAN2_JUMPS
+#define GLK_ALAN2_JUMPS
+
+/* This provides a simplified version of the ScummVM coroutines to allow for automated
+ * breakouts to the main game loop from subroutinese rather than using unportable setjmps
+ */
+
+namespace Glk {
+namespace Alan2 {
+
+/**
+ * Context used for flagging when a break to the outer game loop
+ */
+struct Context {
+ bool _break;
+ Context() : _break(false) {}
+};
+
+#define CALL0(METHOD) { METHOD(context); if (context._break) return; }
+#define CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return; }
+#define CALL2(METHOD, P1, P2) { METHOD(context, P2); if (context._break) return; }
+#define CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return; }
+#define CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P4); if (context._break) return; }
+#define FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return; }
+#define FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return; }
+#define FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P2); if (context._break) return; }
+#define FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return; }
+#define FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P4); if (context._break) return; }
+
+#define R0CALL0(METHOD) { METHOD(context); if (context._break) return 0; }
+#define R0CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return 0; }
+#define R0CALL2(METHOD, P1, P2) { METHOD(context, P2); if (context._break) return 0; }
+#define R0CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return 0; }
+#define R0CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P4); if (context._break) return 0; }
+#define R0FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return 0; }
+#define R0FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return 0; }
+#define R0FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P2); if (context._break) return 0; }
+#define R0FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return 0; }
+#define R0FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P4); if (context._break) return 0; }
+
+#define CONTEXT Context &context
+#define LONG_JUMP { context._break = true; return; }
+#define LONG_JUMP0 { context._break = true; return 0; }
+
+} // End of namespace Alan2
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan2/main.cpp b/engines/glk/alan2/main.cpp
index 6732bfb791..2dea4519f7 100644
--- a/engines/glk/alan2/main.cpp
+++ b/engines/glk/alan2/main.cpp
@@ -162,16 +162,15 @@ void syserr(const char *str) {
error()
Print an error message, force new player input and abort.
-
*/
-void error(MsgKind msgno /* IN - The error message number */) {
+ /* IN - The error message number */
+void error(CONTEXT, MsgKind msgno) {
if (msgno != MSGMAX)
prmsg(msgno);
wrds[wrdidx] = EOD; /* Force new player input */
dscrstkp = 0; /* Reset describe stack */
- //longjmp(jmpbuf,TRUE);
- ::error("Error occurred");
+ LONG_JUMP
}
@@ -677,13 +676,13 @@ static Boolean trycheck(
Move hero in a direction.
*/
-void go(int dir) {
+void go(CONTEXT, int dir) {
ExtElem *ext;
Boolean ok;
Aword oldloc;
ext = (ExtElem *) addrTo(locs[cur.loc - LOCMIN].exts);
- if (locs[cur.loc - LOCMIN].exts != 0)
+ if (locs[cur.loc - LOCMIN].exts != 0) {
while (!endOfTable(ext)) {
if ((int)ext->code == dir) {
ok = TRUE;
@@ -722,7 +721,9 @@ void go(int dir) {
}
ext++;
}
- error(M_NO_WAY);
+ }
+
+ CALL1(error, M_NO_WAY)
}
@@ -806,7 +807,7 @@ Boolean possible() {
Execute the action commanded by hero.
*/
-static void do_it() {
+static void do_it(CONTEXT) {
AltElem *alt[MAXPARAMS + 2]; /* List of alt-pointers, one for each param */
Boolean done[MAXPARAMS + 2]; /* Is it done */
int i; /* Parameter index */
@@ -855,9 +856,10 @@ static void do_it() {
for (i = 0; i < 2 || params[i - 2].code != EOD; i++)
if (alt[i] != 0 && alt[i]->action != 0)
break;
- if (i >= 2 && params[i - 2].code == EOD)
- /* Didn't find any code for this verb/object combination */
- error(M_CANT0);
+ if (i >= 2 && params[i - 2].code == EOD) {
+ // Didn't find any code for this verb/object combination
+ CALL1(error, M_CANT0)
+ }
/* Perform actions! */
@@ -943,7 +945,7 @@ static void do_it() {
such as THEM or lists of objects.
*/
-void action(ParamElem plst[] /* IN - Plural parameter list */) {
+void action(CONTEXT, ParamElem plst[] /* IN - Plural parameter list */) {
int i, mpos;
char marker[10];
@@ -957,13 +959,14 @@ void action(ParamElem plst[] /* IN - Plural parameter list */) {
for (i = 0; plst[i].code != EOD; i++) {
params[mpos] = plst[i];
output(marker);
- do_it();
+ CALL0(do_it)
if (plst[i + 1].code != EOD)
para();
}
params[mpos].code = 0;
- } else
- do_it();
+ } else {
+ CALL0(do_it)
+ }
}
@@ -1282,14 +1285,14 @@ static void init() {
Let the current actor move. If player, ask him.
*/
-static void movactor() {
+static void movactor(CONTEXT) {
ScrElem *scr;
StepElem *step;
ActElem *act = (ActElem *) &acts[cur.act - ACTMIN];
cur.loc = where(cur.act);
if (cur.act == (int)HERO) {
- parse();
+ CALL0(parse)
if (g_vm->shouldQuit())
return;
fail = FALSE; /* fail only aborts one actor */
@@ -1416,17 +1419,23 @@ void run() {
init(); /* Load, initialise and start the adventure */
- while (TRUE) {
- if (dbgflg)
- debug();
+ Context ctx;
+ for (;;) {
+ if (!ctx._break) {
+ if (dbgflg)
+ debug();
- eventchk();
- cur.tick++;
- // (void) setjmp(jmpbuf);
+ eventchk();
+ cur.tick++;
+ }
+
+ // Execution ends up here after calls to the error method
// Move all characters
- for (cur.act = ACTMIN; cur.act <= (int)ACTMAX; cur.act++) {
- movactor();
+ ctx._break = false;
+ for (cur.act = ACTMIN; cur.act <= (int)ACTMAX && !ctx._break; cur.act++) {
+ movactor(ctx);
+
if (g_vm->shouldQuit())
return;
}
diff --git a/engines/glk/alan2/main.h b/engines/glk/alan2/main.h
index 9dffbc343a..9672899c81 100644
--- a/engines/glk/alan2/main.h
+++ b/engines/glk/alan2/main.h
@@ -27,6 +27,7 @@
#include "common/file.h"
#include "glk/alan2/types.h"
+#include "glk/alan2/jumps.h"
namespace Glk {
namespace Alan2 {
@@ -100,7 +101,7 @@ extern Boolean needsp;
extern void *allocate(unsigned long len);
extern void terminate(int code);
extern void usage(void);
-extern void error(MsgKind msg);
+extern void error(CONTEXT, MsgKind msg);
extern void syserr(const char *msg);
extern void statusline(void);
extern void output(const char string[]);
@@ -111,8 +112,8 @@ extern void newline(void);
extern Boolean checklim(Aword cnt, Aword obj);
extern Boolean possible(void);
extern Boolean exitto(int to, int from);
-extern void action(ParamElem *plst);
-extern void go(int dir);
+extern void action(CONTEXT, ParamElem *plst);
+extern void go(CONTEXT, int dir);
extern Boolean eot(Aword *adr);
extern Boolean isObj(Aword x);
diff --git a/engines/glk/alan2/parse.cpp b/engines/glk/alan2/parse.cpp
index 24961c91e9..9e1c3400b3 100644
--- a/engines/glk/alan2/parse.cpp
+++ b/engines/glk/alan2/parse.cpp
@@ -89,7 +89,7 @@ static char isobuf[LISTLEN + 1]; /* The input buffer in ISO */
static Boolean eol = TRUE; /* Looking at End of line? Yes, initially */
-static void unknown(char token[]) {
+static void unknown(CONTEXT, char token[]) {
char *str = (char *)allocate((int)strlen(token) + 4);
str[0] = '\'';
@@ -98,29 +98,29 @@ static void unknown(char token[]) {
output(str);
free(str);
eol = TRUE;
- error(M_UNKNOWN_WORD);
+ CALL1(error, M_UNKNOWN_WORD)
}
static char *token;
-static int lookup(char wrd[]) {
+static int lookup(CONTEXT, char wrd[]) {
int i;
for (i = 0; !endOfTable(&dict[i]); i++) {
if (strcmp(wrd, (char *) addrTo(dict[i].wrd)) == 0)
return (i);
}
- unknown(wrd);
- return (EOD);
+ R0CALL1(unknown, wrd)
+ return EOD;
}
/* IN - The string to convert to a number */
static int number(char tok[]) {
int i;
- sscanf(tok, "%d", &i);
+ (void)sscanf(tok, "%d", &i);
return i;
}
@@ -185,7 +185,7 @@ static void agetline() {
lin = 1;
}
-static void scan() {
+static void scan(CONTEXT) {
int i;
int w;
char *str;
@@ -203,7 +203,8 @@ static void scan() {
do {
if (isISOLetter(token[0])) {
(void) stringLower(token);
- w = lookup(token);
+ FUNC1(lookup, w, token);
+
if (!isNoise(w))
wrds[i++] = w;
} else if (isdigit(token[0])) {
@@ -223,8 +224,9 @@ static void scan() {
litValues[litCount++].value = (Aptr) str;
} else if (token[0] == ',') {
wrds[i++] = conjWord;
- } else
- unknown(token);
+ } else {
+ CALL1(unknown, token)
+ }
wrds[i] = EOD;
eol = (token = gettoken(NULL)) == NULL;
} while (!eol);
@@ -250,20 +252,22 @@ static void scan() {
static int allLength; /* No. of objects matching 'all' */
-static void nonverb() {
+static void nonverb(CONTEXT) {
if (isDir(wrds[wrdidx])) {
wrdidx++;
- if (wrds[wrdidx] != EOD && !isConj(wrds[wrdidx]))
- error(M_WHAT);
- else
- go(dict[wrds[wrdidx - 1]].code);
+ if (wrds[wrdidx] != EOD && !isConj(wrds[wrdidx])) {
+ CALL1(error, M_WHAT)
+ } else {
+ CALL1(go, dict[wrds[wrdidx - 1]].code)
+ }
if (wrds[wrdidx] != EOD)
wrdidx++;
- } else
- error(M_WHAT);
+ } else {
+ CALL1(error, M_WHAT)
+ }
}
-static void buildall(ParamElem list[]) {
+static void buildall(CONTEXT, ParamElem list[]) {
int i = 0;
Boolean found = FALSE;
@@ -273,13 +277,14 @@ static void buildall(ParamElem list[]) {
list[i].code = o;
list[i++].firstWord = EOD;
}
- if (!found)
- error(M_WHAT_ALL);
- else
+ if (!found) {
+ CALL1(error, M_WHAT_ALL)
+ } else {
list[i].code = EOD;
+ }
}
-static void unambig(ParamElem plst[]) {
+static void unambig(CONTEXT, ParamElem plst[]) {
int i;
Boolean found = FALSE; /* Adjective or noun found ? */
static ParamElem *refs; /* Entities referenced by word */
@@ -305,13 +310,14 @@ static void unambig(ParamElem plst[]) {
wrdidx++;
/* Use last object in previous command! */
for (i = lstlen(pparams) - 1; i >= 0 && (pparams[i].code == 0 || pparams[i].code >= LITMIN); i--);
- if (i < 0)
- error(M_WHAT_IT);
+ if (i < 0) {
+ CALL1(error, M_WHAT_IT)
+ }
if (!isHere(pparams[i].code)) {
params[0].code = pparams[i].code;
params[0].firstWord = EOD;
params[1].code = EOD;
- error(M_NO_SUCH);
+ CALL1(error, M_NO_SUCH)
}
plst[0] = pparams[i];
plst[0].firstWord = EOD; /* No words used! */
@@ -345,7 +351,7 @@ static void unambig(ParamElem plst[]) {
}
wrdidx++;
} else
- error(M_NOUN);
+ CALL1(error, M_NOUN)
} else if (found) {
if (isNoun(wrds[wrdidx - 1])) {
/* Perhaps the last word was also a noun? */
@@ -355,8 +361,9 @@ static void unambig(ParamElem plst[]) {
lstcpy(plst, refs);
else
isect(plst, refs);
- } else
- error(M_NOUN);
+ } else {
+ CALL1(error, M_NOUN)
+ }
}
lastWord = wrdidx - 1;
@@ -373,17 +380,18 @@ static void unambig(ParamElem plst[]) {
params[0].firstWord = firstWord; /* Remember words for errors below */
params[0].lastWord = lastWord;
params[1].code = EOD; /* But be sure to terminate */
- if (lstlen(plst) > 1)
- error(M_WHICH_ONE);
- else if (found && lstlen(plst) == 0)
- error(M_NO_SUCH);
+ if (lstlen(plst) > 1) {
+ CALL1(error, M_WHICH_ONE)
+ } else if (found && lstlen(plst) == 0) {
+ CALL1(error, M_NO_SUCH)
+ }
} else {
plst[0].firstWord = firstWord;
plst[0].lastWord = lastWord;
}
}
-static void simple(ParamElem olst[]) {
+static void simple(CONTEXT, ParamElem olst[]) {
static ParamElem *tlst = NULL;
int savidx = wrdidx;
Boolean savplur = FALSE;
@@ -400,13 +408,16 @@ static void simple(ParamElem olst[]) {
if (!isHere(pmlst[i].code))
pmlst[i].code = 0;
compact(pmlst);
- if (lstlen(pmlst) == 0)
- error(M_WHAT_THEM);
+ if (lstlen(pmlst) == 0) {
+ CALL1(error, M_WHAT_THEM)
+ }
+
lstcpy(olst, pmlst);
olst[0].firstWord = EOD; /* No words used */
wrdidx++;
} else {
- unambig(olst); /* Look for unambigous noun phrase */
+ // Look for unambigous noun phrase
+ CALL1(unambig, olst)
if (lstlen(olst) == 0) { /* Failed! */
lstcpy(olst, tlst);
wrdidx = savidx;
@@ -440,7 +451,7 @@ static void simple(ParamElem olst[]) {
entity tables. Particularly this goes for literals...
*/
-static void complex(ParamElem olst[]) {
+static void complex(CONTEXT, ParamElem olst[]) {
static ParamElem *alst = NULL;
if (alst == NULL)
@@ -448,21 +459,24 @@ static void complex(ParamElem olst[]) {
if (isAll(wrds[wrdidx])) {
plural = TRUE;
- buildall(alst); /* Build list of all objects */
+ // Build list of all objects
+ CALL1(buildall, alst)
wrdidx++;
if (wrds[wrdidx] != EOD && isBut(wrds[wrdidx])) {
wrdidx++;
- simple(olst);
+ CALL1(simple, olst)
if (lstlen(olst) == 0)
- error(M_AFTER_BUT);
+ CALL1(error, M_AFTER_BUT)
sublst(alst, olst);
if (lstlen(alst) == 0)
- error(M_NOT_MUCH);
+ CALL1(error, M_NOT_MUCH)
}
lstcpy(olst, alst);
allLength = lstlen(olst);
- } else
- simple(olst); /* Look for simple noun group */
+ } else {
+ // Look for simple noun group
+ CALL1(simple, olst)
+ }
}
static Boolean claCheck(ClaElem *cla /* IN - The cla elem to check */) {
@@ -494,7 +508,7 @@ static Boolean claCheck(ClaElem *cla /* IN - The cla elem to check */) {
access to remote object), we need to remove non-present parameters
*/
-static void resolve(ParamElem plst[]) {
+static void resolve(CONTEXT, ParamElem plst[]) {
int i;
if (allLength > 0) return; /* ALL has already done this */
@@ -505,11 +519,12 @@ static void resolve(ParamElem plst[]) {
if (!isHere(plst[i].code)) {
params[0] = plst[i]; /* Copy error param as first one for message */
params[1].code = EOD; /* But be sure to terminate */
- error(M_NO_SUCH);
+ CALL1(error, M_NO_SUCH)
}
}
-static void tryMatch(ParamElem matchLst[] /* OUT - List of params allowed by multiple */) {
+/* OUT - List of params allowed by multiple */
+static void tryMatch(CONTEXT, ParamElem matchLst[]) {
ElmElem *elms; /* Pointer to element list */
StxElem *stx; /* Pointer to syntax list */
ClaElem *cla; /* Pointer to class definitions */
@@ -526,8 +541,9 @@ static void tryMatch(ParamElem matchLst[] /* OUT - List of params allowed by mul
for (stx = stxs; !endOfTable(stx); stx++)
if ((int)stx->code == vrbcode)
break;
- if (endOfTable(stx))
- error(M_WHAT);
+ if (endOfTable(stx)) {
+ CALL1(error, M_WHAT)
+ }
elms = (ElmElem *) addrTo(stx->elms);
@@ -536,37 +552,43 @@ static void tryMatch(ParamElem matchLst[] /* OUT - List of params allowed by mul
if (wrds[wrdidx] == EOD || isConj(wrds[wrdidx])) {
while (!endOfTable(elms) && elms->code != EOS)
elms++;
- if (endOfTable(elms))
- error(M_WHAT);
- else
+ if (endOfTable(elms)) {
+ CALL1(error, M_WHAT)
+ } else
break;
} else {
/* A preposition? */
if (isPrep(wrds[wrdidx])) {
while (!endOfTable(elms) && elms->code != dict[wrds[wrdidx]].code)
elms++;
- if (endOfTable(elms))
- error(M_WHAT);
- else
+ if (endOfTable(elms)) {
+ CALL1(error, M_WHAT)
+ } else
wrdidx++;
} else {
/* Must be a parameter! */
while (!endOfTable(elms) && elms->code != 0)
elms++;
- if (endOfTable(elms))
- error(M_WHAT);
+ if (endOfTable(elms)) {
+ CALL1(error, M_WHAT)
+ }
/* Get it! */
plural = FALSE;
- complex(tlst);
- if (lstlen(tlst) == 0) /* No object!? */
- error(M_WHAT);
- if ((elms->flags & OMNIBIT) == 0) /* Omnipotent parameter? */
+ CALL1(complex, tlst)
+ if (lstlen(tlst) == 0) {
+ /* No object!? */
+ CALL1(error, M_WHAT)
+ }
+ /* Omnipotent parameter? */
+ if ((elms->flags & OMNIBIT) == 0) {
/* If its not an omnipotent parameter, resolve by presence */
- resolve(tlst);
+ CALL1(resolve, tlst)
+ }
if (plural) {
- if ((elms->flags & MULTIPLEBIT) == 0) /* Allowed multiple? */
- error(M_MULTIPLE);
- else {
+ /* Allowed multiple? */
+ if ((elms->flags & MULTIPLEBIT) == 0) {
+ CALL1(error, M_MULTIPLE)
+ } else {
/*
Mark this as the multiple position in which to insert
actual parameter values later
@@ -584,8 +606,10 @@ static void tryMatch(ParamElem matchLst[] /* OUT - List of params allowed by mul
}
/* Now perform class checks */
- if (elms->next == 0) /* No verb code, verb not declared! */
- error(M_CANT0);
+ if (elms->next == 0) {
+ /* No verb code, verb not declared! */
+ CALL1(error, M_CANT0)
+ }
for (p = 0; params[p].code != EOD; p++) /* Mark all parameters unchecked */
checked[p] = FALSE;
@@ -613,8 +637,9 @@ static void tryMatch(ParamElem matchLst[] /* OUT - List of params allowed by mul
params[cla->code - 1].code = 0;
} else {
if (!claCheck(cla)) {
+ /* Return to player without saying anything */
interpret(cla->stms);
- error(MSGMAX); /* Return to player without saying anything */
+ CALL1(error, MSGMAX)
}
}
checked[cla->code - 1] = TRUE; /* Remember that it's already checked */
@@ -628,8 +653,9 @@ static void tryMatch(ParamElem matchLst[] /* OUT - List of params allowed by mul
if (matchLst[i].code != 0) /* Skip any empty slots */
if (!isObj(matchLst[i].code))
matchLst[i].code = 0;
- } else if (!isObj(params[p].code))
- error(M_CANT0);
+ } else if (!isObj(params[p].code)) {
+ CALL1(error, M_CANT0)
+ }
}
/* Set verb code */
@@ -649,28 +675,30 @@ static void tryMatch(ParamElem matchLst[] /* OUT - List of params allowed by mul
compact(matchLst);
if (lstlen(matchLst) == 0) {
params[0].code = EOD;
- error(M_WHAT_ALL);
+ CALL1(error, M_WHAT_ALL)
}
} else if (anyPlural) {
compact(matchLst);
if (lstlen(matchLst) == 0)
/* If there where multiple parameters but non left, exit without a */
/* word, assuming we have already said enough */
- error(MSGMAX);
+ CALL1(error, MSGMAX)
}
plural = anyPlural; /* Remember that we found plural objects */
}
/* OUT - List of params allowed by multiple */
-static void match(ParamElem *matchLst) {
- tryMatch(matchLst); /* ... to understand what he said */
- if (wrds[wrdidx] != EOD && !isConj(wrds[wrdidx]))
- error(M_WHAT);
+static void match(CONTEXT, ParamElem *matchLst) {
+ /* ... to understand what he said */
+ CALL1(tryMatch, matchLst)
+ if (wrds[wrdidx] != EOD && !isConj(wrds[wrdidx])) {
+ CALL1(error, M_WHAT)
+ }
if (wrds[wrdidx] != EOD) /* More on this line? */
wrdidx++; /* If so skip the AND */
}
-void parse() {
+void parse(CONTEXT) {
if (mlst == NULL) { /* Allocate large enough paramlists */
mlst = (ParamElem *) allocate(sizeof(ParamElem) * (MAXENTITY + 1));
mlst[0].code = EOD;
@@ -682,7 +710,8 @@ void parse() {
if (wrds[wrdidx] == EOD) {
wrdidx = 0;
- scan();
+ CALL0(scan)
+
if (g_vm->shouldQuit())
return;
} else if (anyOutput)
@@ -698,12 +727,13 @@ void parse() {
vrbwrd = wrds[wrdidx];
vrbcode = dict[vrbwrd].code;
wrdidx++;
- match(mlst);
- action(mlst); /* mlst contains possible multiple params */
+ CALL1(match, mlst)
+ /* mlst contains possible multiple params */
+ CALL1(action, mlst)
} else {
params[0].code = EOD;
pmlst[0].code = EOD;
- nonverb();
+ CALL0(nonverb)
}
}
diff --git a/engines/glk/alan2/parse.h b/engines/glk/alan2/parse.h
index af3276fd14..100d739aa7 100644
--- a/engines/glk/alan2/parse.h
+++ b/engines/glk/alan2/parse.h
@@ -25,6 +25,8 @@
/* Parse data for ALAN interpreter module. */
+#include "engines/glk/alan2/jumps.h"
+
namespace Glk {
namespace Alan2 {
@@ -40,7 +42,7 @@ extern int litCount;
extern int vrbwrd;
// Parse a new player command
-extern void parse(void);
+extern void parse(CONTEXT);
} // End of namespace Alan2
} // End of namespace Glk