PRIVATE: some fixes and added debug functions

This commit is contained in:
neuromancer 2021-01-06 21:46:54 -03:00 committed by Eugene Sandulenko
parent 695eae1421
commit 2a04c04c35
6 changed files with 98 additions and 48 deletions

View File

@ -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_);
}
}
}

View File

@ -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);
}

View File

@ -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<void *, Common::String *> 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<Common::String, Symbol*> SymbolMap;
typedef Common::List<Symbol*> ConstantList;

View File

@ -45,7 +45,7 @@ int yywrap()
%token<s> NAME
%token<sym> STRING NUM
%type <inst> body body1 if cond end expr statements statement fcall value
%type <inst> 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<narg> 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)); }

View File

@ -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);

View File

@ -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());