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/str.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/hash-ptr.h"
#include "grammar.h" #include "grammar.h"
#include "grammar.tab.h" #include "grammar.tab.h"
@ -16,6 +17,34 @@ Inst *prog = NULL; /* the machine */
Inst *progp = NULL; /* next free spot for code generation */ Inst *progp = NULL; /* next free spot for code generation */
Inst *pc = NULL; /* program counter during execution */ 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 */ void initSetting() /* initialize for code generation */
{ {
psetting = (Setting*) malloc(sizeof(Setting)); psetting = (Setting*) malloc(sizeof(Setting));
@ -47,6 +76,19 @@ void loadSetting(Common::String *name)
stackp = stack; stackp = stack;
progp = prog; 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->type = RECTTOK;
d->u.rect = rect; d->u.rect = rect;
push(*d); push(*d);
//_nextMovie = new Common::String(args[0].u.str);
//_nextSetting = new Common::String(args[1].u.str);
} }
void Bitmap(ArgArray args) { void Bitmap(ArgArray args) {
@ -132,6 +130,9 @@ void execFunction(char *name, ArgArray args) {
else if (strcmp(name, "Exit") == 0) { else if (strcmp(name, "Exit") == 0) {
; ;
} }
else if (strcmp(name, "LoadGame") == 0) {
;
}
else if (strcmp(name, "CRect") == 0) { else if (strcmp(name, "CRect") == 0) {
CRect(args); CRect(args);
} }

View file

@ -1,5 +1,6 @@
#include "common/str.h" #include "common/str.h"
#include "common/hash-str.h" #include "common/hash-str.h"
#include "common/hash-ptr.h"
#include "common/queue.h" #include "common/queue.h"
#include "common/list.h" #include "common/list.h"
#include "common/array.h" #include "common/array.h"
@ -11,6 +12,11 @@
#define NSTACK 256 #define NSTACK 256
#define NPROG 10000 #define NPROG 10000
typedef struct Arg {
int n;
int (**inst)();
} Arg;
typedef struct Symbol { /* symbol table entry */ typedef struct Symbol { /* symbol table entry */
Common::String *name; Common::String *name;
short type; /* NAME, NUM or STRING */ short type; /* NAME, NUM or STRING */
@ -35,6 +41,10 @@ namespace Private {
typedef int (*Inst)(); /* machine instruction */ typedef int (*Inst)(); /* machine instruction */
#define STOP (Inst) 0 #define STOP (Inst) 0
typedef Common::HashMap<void *, Common::String *> FuncHash;
extern void initFuncs();
typedef struct Setting { typedef struct Setting {
Datum stack[NSTACK]; /* the stack */ Datum stack[NSTACK]; /* the stack */
@ -58,6 +68,8 @@ extern SettingMap settingcode;
// Symbols // Symbols
extern void showSymbol(Symbol *);
typedef Common::HashMap<Common::String, Symbol*> SymbolMap; typedef Common::HashMap<Common::String, Symbol*> SymbolMap;
typedef Common::List<Symbol*> ConstantList; typedef Common::List<Symbol*> ConstantList;

View file

@ -45,7 +45,7 @@ int yywrap()
%token<s> NAME %token<s> NAME
%token<sym> STRING NUM %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 %token LTE GTE NEQ EQ FALSETOK TRUETOK IFTOK ELSETOK RECTTOK GOTOTOK DEBUGTOK DEFINETOK SETTINGTOK RANDOMTOK
%type<narg> params %type<narg> params
@ -69,52 +69,30 @@ statements: /* nothing */ { $$ = progp; }
statement: GOTOTOK expr ';' { /*TODO*/ } statement: GOTOTOK expr ';' { /*TODO*/ }
| fcall ';' { $$ = $1; } | fcall ';' { }
| if cond body1 end { | if cond body end {
$$ = $1; //$$ = $1;
/* else-less if */ /* else-less if */
($1)[1] = (Inst)$3; /* thenpart */ ($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 { | if cond body end ELSETOK body end {
$$ = $1; //$$ = $1;
/* if with else */ /* if with else */
($1)[1] = (Inst)$3; /* thenpart */ ($1)[1] = (Inst)$3; /* thenpart */
($1)[2] = (Inst)$6; /* elsepart */ ($1)[2] = (Inst)$6; /* elsepart */
($1)[3] = (Inst)$7; } /* end, if cond fails */ ($1)[3] = (Inst)$7;
| if cond body end { } /* end, if cond fails */
$$ = $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 */
; ;
body: '{' statements '}' { $$ = progp; } body: statement { $$ = $1; }
; | '{' statements '}' { $$ = $2; }
body1: statement { $$ = $1; }
; ;
end: /* nothing */ { code(STOP); $$ = progp; } 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; } cond: '(' expr ')' { code(STOP); $$ = $2; }
@ -129,26 +107,29 @@ define: /* nothing */
fcall: GOTOTOK '(' NAME ')' { fcall: GOTOTOK '(' NAME ')' {
$$ = progp; $$ = progp;
code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, $NAME)); code2(strpush, (Private::Inst) Private::addconstant(STRING, 0, $NAME));
code2(Private::constpush, (Private::Inst) Private::addconstant(NUM, 1, NULL)); code2(constpush, (Private::Inst) Private::addconstant(NUM, 1, NULL));
code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, "goto")); code2(strpush, (Private::Inst) Private::addconstant(STRING, 0, "goto"));
code1(Private::funcpush); code1(funcpush);
} }
| RECTTOK '(' NUM ',' NUM ',' NUM ',' NUM ')' { $$ = progp; } | RECTTOK '(' NUM ',' NUM ',' NUM ',' NUM ')' { $$ = progp; }
| NAME '(' params ')' { | NAME '(' startp params ')' {
$$ = progp; $$ = $startp;
code2(Private::constpush, (Private::Inst) Private::addconstant(NUM, $params, NULL)); code2(constpush, (Private::Inst) addconstant(NUM, $params, NULL));
code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, $NAME)); code2(strpush, (Private::Inst) addconstant(STRING, 0, $NAME));
code1(Private::funcpush); code1(funcpush);
} }
; ;
params: /* nothing */ { $$ = 0; } startp: /*nothing*/ { $$ = progp; }
;
params: /* nothing */ { $$ = 0; }
| fcall ',' params { $$ = $3 + 1; } | fcall ',' params { $$ = $3 + 1; }
| expr ',' params { $$ = $3 + 1; } | expr ',' params { $$ = $3 + 1; }
| expr { $$ = 1; } | expr { $$ = 1; }
| fcall { $$ = 1; } | fcall { $$ = 1; }
; ;
value: FALSETOK { code2(Private::constpush, (Private::Inst) Private::addconstant(NUM, 0, NULL)); } 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")); assert(file->open("GAME.DAT"));
void *buf = malloc(191000); void *buf = malloc(191000);
file->read(buf, 191000); file->read(buf, 191000);
initFuncs();
parse((char *) buf); parse((char *) buf);
assert(constants.size() > 0); assert(constants.size() > 0);

View file

@ -23,6 +23,19 @@ char *emalloc(unsigned n) /* check return from malloc */
return p; 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 */ Symbol *lookup(Common::String s, SymbolMap symlist) /* find s in symbol table symlist */
{ {
//debug("looking up %s", s.c_str()); //debug("looking up %s", s.c_str());