diff --git a/engines/private/code.cpp b/engines/private/code.cpp index 3d7c1cd04b8..f94302b3ead 100644 --- a/engines/private/code.cpp +++ b/engines/private/code.cpp @@ -1,5 +1,6 @@ #include "common/str.h" #include "common/debug.h" +#include "common/hash-ptr.h" #include "grammar.h" #include "grammar.tab.h" @@ -16,6 +17,34 @@ Inst *prog = NULL; /* the machine */ Inst *progp = NULL; /* next free spot for code generation */ Inst *pc = NULL; /* program counter during execution */ + +static struct FuncDescr { + const Inst func; + const char *name; + const char *args; +} funcDescr[] = { + { 0, "STOP", "" }, + { constpush, "constpush", "" }, + { strpush, "strpush", "" }, + { varpush, "varpush", "" }, + { funcpush, "funcpush", "" }, + { eval, "eval", "" }, + { ifcode, "ifcode", "" }, + { add, "add", "" }, + { negate, "negate", "" }, + + { 0, 0, 0 } +}; + +FuncHash _functions; + +void initFuncs() { + for (FuncDescr *fnc = funcDescr; fnc->name; fnc++) { + _functions[(void *)fnc->func] = new Common::String(fnc->name); + } +} + + void initSetting() /* initialize for code generation */ { psetting = (Setting*) malloc(sizeof(Setting)); @@ -47,6 +76,19 @@ void loadSetting(Common::String *name) stackp = stack; progp = prog; + + + for (Inst *pc_ = progp; pc_-progp < 100; pc_++) { + if (_functions.contains((void *) *pc_)) + debug("%x: %s", pc_, _functions.getVal((void*) *pc_)->c_str()); + else if ( (Inst *) *pc_ >= progp && (Inst *) *pc_ <= (progp + NPROG)) + debug("%x: %x", pc_, (void*) *pc_); + else { + debugN("%x:", pc_); + showSymbol((Symbol *) *pc_); + } + + } } diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp index f8cfe6003ba..cce2a809e82 100644 --- a/engines/private/funcs.cpp +++ b/engines/private/funcs.cpp @@ -74,8 +74,6 @@ void CRect(ArgArray args) { d->type = RECTTOK; d->u.rect = rect; push(*d); - //_nextMovie = new Common::String(args[0].u.str); - //_nextSetting = new Common::String(args[1].u.str); } void Bitmap(ArgArray args) { @@ -132,6 +130,9 @@ void execFunction(char *name, ArgArray args) { else if (strcmp(name, "Exit") == 0) { ; } + else if (strcmp(name, "LoadGame") == 0) { + ; + } else if (strcmp(name, "CRect") == 0) { CRect(args); } diff --git a/engines/private/grammar.h b/engines/private/grammar.h index f0bdf728b7e..181cc88e059 100644 --- a/engines/private/grammar.h +++ b/engines/private/grammar.h @@ -1,5 +1,6 @@ #include "common/str.h" #include "common/hash-str.h" +#include "common/hash-ptr.h" #include "common/queue.h" #include "common/list.h" #include "common/array.h" @@ -11,6 +12,11 @@ #define NSTACK 256 #define NPROG 10000 +typedef struct Arg { + int n; + int (**inst)(); +} Arg; + typedef struct Symbol { /* symbol table entry */ Common::String *name; short type; /* NAME, NUM or STRING */ @@ -35,6 +41,10 @@ namespace Private { typedef int (*Inst)(); /* machine instruction */ #define STOP (Inst) 0 +typedef Common::HashMap FuncHash; + +extern void initFuncs(); + typedef struct Setting { Datum stack[NSTACK]; /* the stack */ @@ -58,6 +68,8 @@ extern SettingMap settingcode; // Symbols +extern void showSymbol(Symbol *); + typedef Common::HashMap SymbolMap; typedef Common::List ConstantList; diff --git a/engines/private/grammar.y b/engines/private/grammar.y index 86cfc478b46..0c76ea5c585 100644 --- a/engines/private/grammar.y +++ b/engines/private/grammar.y @@ -45,7 +45,7 @@ int yywrap() %token NAME %token STRING NUM -%type body body1 if cond end expr statements statement fcall value +%type body if startp cond end expr statements statement fcall value %token LTE GTE NEQ EQ FALSETOK TRUETOK IFTOK ELSETOK RECTTOK GOTOTOK DEBUGTOK DEFINETOK SETTINGTOK RANDOMTOK %type params @@ -69,52 +69,30 @@ statements: /* nothing */ { $$ = progp; } statement: GOTOTOK expr ';' { /*TODO*/ } - | fcall ';' { $$ = $1; } - | if cond body1 end { - $$ = $1; + | fcall ';' { } + | if cond body end { + //$$ = $1; /* else-less if */ ($1)[1] = (Inst)$3; /* thenpart */ - ($1)[3] = (Inst)$4; } /* end, if cond fails */ + ($1)[3] = (Inst)$4; + } /* end, if cond fails */ | if cond body end ELSETOK body end { - $$ = $1; + //$$ = $1; /* if with else */ ($1)[1] = (Inst)$3; /* thenpart */ ($1)[2] = (Inst)$6; /* elsepart */ - ($1)[3] = (Inst)$7; } /* end, if cond fails */ - | if cond body end { - $$ = $1; - /* else-less if */ - ($1)[1] = (Inst)$3; /* thenpart */ - ($1)[3] = (Inst)$4; } /* end, if cond fails */ - | if cond body end ELSETOK statement end { /* if with else */ - $$ = $1; - ($1)[1] = (Inst)$3; /* thenpart */ - ($1)[2] = (Inst)$6; /* elsepart */ - ($1)[3] = (Inst)$7; } /* end, if cond fails */ - | if cond body1 end ELSETOK statement end { - $$ = $1; - /* if with else */ - ($1)[1] = (Inst)$3; /* thenpart */ - ($1)[2] = (Inst)$6; /* elsepart */ - ($1)[3] = (Inst)$7; } /* end, if cond fails */ - | if cond body1 end ELSETOK body end { - $$ = $1; - /* if with else */ - ($1)[1] = (Inst)$3; /* thenpart */ - ($1)[2] = (Inst)$6; /* elsepart */ - ($1)[3] = (Inst)$7; } /* end, if cond fails */ + ($1)[3] = (Inst)$7; + } /* end, if cond fails */ ; -body: '{' statements '}' { $$ = progp; } - ; - -body1: statement { $$ = $1; } +body: statement { $$ = $1; } + | '{' statements '}' { $$ = $2; } ; end: /* nothing */ { code(STOP); $$ = progp; } ; -if: IFTOK { $$ = code(ifcode); code3(STOP, STOP, STOP); } +if: IFTOK { $$ = code(ifcode); code1(STOP); code1(STOP); code1(STOP); } //code3(STOP, STOP, STOP); } ; cond: '(' expr ')' { code(STOP); $$ = $2; } @@ -129,26 +107,29 @@ define: /* nothing */ fcall: GOTOTOK '(' NAME ')' { $$ = progp; - code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, $NAME)); - code2(Private::constpush, (Private::Inst) Private::addconstant(NUM, 1, NULL)); - code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, "goto")); - code1(Private::funcpush); + code2(strpush, (Private::Inst) Private::addconstant(STRING, 0, $NAME)); + code2(constpush, (Private::Inst) Private::addconstant(NUM, 1, NULL)); + code2(strpush, (Private::Inst) Private::addconstant(STRING, 0, "goto")); + code1(funcpush); } | RECTTOK '(' NUM ',' NUM ',' NUM ',' NUM ')' { $$ = progp; } - | NAME '(' params ')' { - $$ = progp; - code2(Private::constpush, (Private::Inst) Private::addconstant(NUM, $params, NULL)); - code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, $NAME)); - code1(Private::funcpush); + | NAME '(' startp params ')' { + $$ = $startp; + code2(constpush, (Private::Inst) addconstant(NUM, $params, NULL)); + code2(strpush, (Private::Inst) addconstant(STRING, 0, $NAME)); + code1(funcpush); } ; -params: /* nothing */ { $$ = 0; } +startp: /*nothing*/ { $$ = progp; } + ; + +params: /* nothing */ { $$ = 0; } | fcall ',' params { $$ = $3 + 1; } | expr ',' params { $$ = $3 + 1; } - | expr { $$ = 1; } - | fcall { $$ = 1; } + | expr { $$ = 1; } + | fcall { $$ = 1; } ; value: FALSETOK { code2(Private::constpush, (Private::Inst) Private::addconstant(NUM, 0, NULL)); } diff --git a/engines/private/private.cpp b/engines/private/private.cpp index 68358b6f0ae..00b6c15fbe0 100644 --- a/engines/private/private.cpp +++ b/engines/private/private.cpp @@ -90,6 +90,7 @@ Common::Error PrivateEngine::run() { assert(file->open("GAME.DAT")); void *buf = malloc(191000); file->read(buf, 191000); + initFuncs(); parse((char *) buf); assert(constants.size() > 0); diff --git a/engines/private/symbol.cpp b/engines/private/symbol.cpp index b67f95c67a3..544d6c2ec96 100644 --- a/engines/private/symbol.cpp +++ b/engines/private/symbol.cpp @@ -23,6 +23,19 @@ char *emalloc(unsigned n) /* check return from malloc */ return p; } +void showSymbol(Symbol *s) +{ + if (s->type == NUM) + debug("%s %d",s->name->c_str(), s->u.val); + else if (s->type == STRING) + debug("%s %s", s->name->c_str(), s->u.str); + else if (s->type == NAME) + debug("%s",s->name->c_str()); + else + debug("%s %d", s->name->c_str(), s->type); +} + + Symbol *lookup(Common::String s, SymbolMap symlist) /* find s in symbol table symlist */ { //debug("looking up %s", s.c_str());