2020-12-31 17:03:11 -03:00
|
|
|
#include "common/str.h"
|
2021-01-02 00:58:58 -03:00
|
|
|
#include "common/debug.h"
|
2021-01-06 21:46:54 -03:00
|
|
|
#include "common/hash-ptr.h"
|
2020-12-30 09:16:19 -03:00
|
|
|
|
|
|
|
#include "grammar.h"
|
|
|
|
#include "grammar.tab.h"
|
2021-01-10 15:38:10 -03:00
|
|
|
#include "private.h"
|
2020-12-30 09:16:19 -03:00
|
|
|
|
2020-12-30 19:33:25 -03:00
|
|
|
namespace Private {
|
|
|
|
|
2021-01-10 20:44:27 -03:00
|
|
|
Setting *setting;
|
|
|
|
SettingMap settingMap;
|
2020-12-30 20:57:05 -03:00
|
|
|
|
|
|
|
Datum *stack = NULL; /* the stack */
|
|
|
|
Datum *stackp = NULL; /* next free spot on stack */
|
|
|
|
|
|
|
|
Inst *prog = NULL; /* the machine */
|
|
|
|
Inst *progp = NULL; /* next free spot for code generation */
|
|
|
|
Inst *pc = NULL; /* program counter during execution */
|
|
|
|
|
2021-01-06 21:46:54 -03:00
|
|
|
|
2021-01-09 22:08:41 -03:00
|
|
|
static struct InstDescr {
|
2021-01-07 23:38:18 -03:00
|
|
|
const Inst func;
|
|
|
|
const char *name;
|
2021-01-09 22:08:41 -03:00
|
|
|
} instDescr[] = {
|
|
|
|
{ 0, "STOP", },
|
|
|
|
{ constpush,"constpush" },
|
|
|
|
{ strpush, "strpush", },
|
|
|
|
{ varpush, "varpush", },
|
|
|
|
{ funcpush, "funcpush", },
|
|
|
|
{ eval, "eval", },
|
|
|
|
{ ifcode, "ifcode", },
|
|
|
|
{ add, "add", },
|
|
|
|
{ negate, "negate", },
|
|
|
|
|
|
|
|
{ 0, 0}
|
2021-01-06 21:46:54 -03:00
|
|
|
};
|
|
|
|
|
2021-01-09 22:08:41 -03:00
|
|
|
PtrToName _insts;
|
2021-01-06 21:46:54 -03:00
|
|
|
|
2021-01-09 22:08:41 -03:00
|
|
|
void initInsts() {
|
|
|
|
for (InstDescr *fnc = instDescr; fnc->name; fnc++) {
|
|
|
|
_insts[(void *)fnc->func] = new Common::String(fnc->name);
|
2021-01-07 23:38:18 -03:00
|
|
|
}
|
2021-01-06 21:46:54 -03:00
|
|
|
}
|
|
|
|
|
2021-01-17 21:50:42 -03:00
|
|
|
/* initialize for code generation */
|
2021-01-12 20:49:12 -03:00
|
|
|
void initSetting() {
|
2021-01-10 20:44:27 -03:00
|
|
|
setting = (Setting*) malloc(sizeof(Setting));
|
|
|
|
memset((void *) setting, 0, sizeof(Setting));
|
2020-12-30 20:57:05 -03:00
|
|
|
|
2021-01-10 20:44:27 -03:00
|
|
|
prog = (Inst *) &setting->prog;
|
|
|
|
stack = (Datum *) &setting->stack;
|
2020-12-30 20:57:05 -03:00
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
stackp = stack;
|
|
|
|
progp = prog;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
void saveSetting(char *name) {
|
2021-01-07 23:38:18 -03:00
|
|
|
Common::String s(name);
|
2021-01-10 20:44:27 -03:00
|
|
|
settingMap.setVal(s, setting);
|
2021-01-02 00:58:58 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
void loadSetting(Common::String *name) {
|
2021-01-10 20:44:27 -03:00
|
|
|
assert(settingMap.contains(*name));
|
|
|
|
setting = settingMap.getVal(*name);
|
2021-01-02 00:58:58 -03:00
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
debug("loading setting %s", name->c_str());
|
2021-01-02 00:58:58 -03:00
|
|
|
|
2021-01-10 20:44:27 -03:00
|
|
|
prog = (Inst *) &setting->prog;
|
|
|
|
stack = (Datum *) &setting->stack;
|
2021-01-02 00:58:58 -03:00
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
stackp = stack;
|
|
|
|
progp = prog;
|
2021-01-06 21:46:54 -03:00
|
|
|
|
2021-01-08 22:42:34 -03:00
|
|
|
/*for (Inst *pc_ = progp; pc_-progp < 100; pc_++) {
|
2021-01-07 23:38:18 -03:00
|
|
|
if (_functions.contains((void *) *pc_))
|
|
|
|
debug("%p: %s", (void*) pc_, _functions.getVal((void*) *pc_)->c_str());
|
|
|
|
else if ( (Inst *) *pc_ >= progp && (Inst *) *pc_ <= (progp + NPROG))
|
|
|
|
debug("%p: %p", (void*) pc_, (void*) *pc_);
|
|
|
|
else {
|
|
|
|
debugN("%p:", (void*) pc_);
|
|
|
|
showSymbol((Symbol *) *pc_);
|
|
|
|
}
|
2021-01-08 22:42:34 -03:00
|
|
|
}*/
|
2020-12-31 17:03:11 -03:00
|
|
|
}
|
|
|
|
|
2021-01-17 21:50:42 -03:00
|
|
|
/* push d onto stack */
|
2021-01-12 20:49:12 -03:00
|
|
|
int push(Datum d) {
|
2021-01-07 23:38:18 -03:00
|
|
|
assert (!(stackp >= &stack[NSTACK]));
|
|
|
|
*stackp++ = d;
|
|
|
|
return 0;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
/* pop and return top elem from stack */
|
|
|
|
Datum pop() {
|
2021-01-07 23:38:18 -03:00
|
|
|
assert (!(stackp <= stack));
|
|
|
|
return *--stackp;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-01-17 21:50:42 -03:00
|
|
|
/* push constant onto stack */
|
2021-01-12 20:49:12 -03:00
|
|
|
int constpush() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d;
|
|
|
|
Symbol *s = (Symbol *)*pc++;
|
|
|
|
d.type = NUM;
|
|
|
|
d.u.val = s->u.val;
|
|
|
|
|
|
|
|
debug("pushing const %d with name %s", d.u.val, s->name->c_str());
|
|
|
|
push(d);
|
|
|
|
return 0;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2020-12-30 14:34:32 -03:00
|
|
|
int strpush() /* push constant onto stack */
|
|
|
|
{
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d;
|
|
|
|
d.type = STRING;
|
|
|
|
Symbol *s = (Symbol *)*pc++;
|
|
|
|
d.u.str = s->u.str;
|
|
|
|
debug("pushing const %s with name %s", d.u.str, s->name->c_str());
|
|
|
|
push(d);
|
|
|
|
return 0;
|
2020-12-30 14:34:32 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-30 09:16:19 -03:00
|
|
|
int varpush() /* push variable onto stack */
|
|
|
|
{
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d;
|
|
|
|
d.type = NAME;
|
|
|
|
d.u.sym = (Symbol *)(*pc++);
|
|
|
|
debug("var pushing %s", d.u.sym->name->c_str());
|
|
|
|
push(d);
|
|
|
|
return 0;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
int funcpush() //(char *name, int nargs)
|
2021-01-02 00:58:58 -03:00
|
|
|
{
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum s, n, arg;
|
|
|
|
s = pop();
|
|
|
|
n = pop();
|
|
|
|
ArgArray args;
|
|
|
|
|
2021-01-14 18:48:30 -03:00
|
|
|
//debug("executing %s with %d params", s.u.str, n.u.val);
|
2021-01-07 23:38:18 -03:00
|
|
|
for (int i = 0; i < n.u.val; i++) {
|
|
|
|
arg = pop();
|
|
|
|
args.insert(args.begin(), arg) ;
|
|
|
|
}
|
|
|
|
|
2021-01-09 22:08:41 -03:00
|
|
|
call(s.u.str, args);
|
2021-01-07 23:38:18 -03:00
|
|
|
return 0;
|
2021-01-02 00:58:58 -03:00
|
|
|
}
|
|
|
|
|
2021-01-17 21:50:42 -03:00
|
|
|
/* evaluate variable on stack */
|
2021-01-12 20:49:12 -03:00
|
|
|
int eval() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d;
|
|
|
|
d = pop();
|
2021-01-14 18:48:30 -03:00
|
|
|
//debug("eval %s", d.u.sym->name->c_str());
|
2021-01-07 23:38:18 -03:00
|
|
|
//if (d.sym->type == UNDEF)
|
|
|
|
// execerror("undefined variable", d.sym->name);
|
|
|
|
if (d.u.sym->type == NUM) {
|
|
|
|
d.type = NUM;
|
|
|
|
d.u.val = d.u.sym->u.val;
|
|
|
|
} else if (d.u.sym->type == STRING) {
|
|
|
|
d.type = STRING;
|
|
|
|
d.u.str = d.u.sym->u.str;
|
2021-01-16 15:30:00 -03:00
|
|
|
debug("eval returned %s", d.u.str );
|
2021-01-09 16:11:30 -03:00
|
|
|
} else if (d.u.sym->type == RECT) {
|
|
|
|
d.type = RECT;
|
|
|
|
d.u.rect = d.u.sym->u.rect;
|
2021-01-07 23:38:18 -03:00
|
|
|
} else if (d.u.sym->type == NAME) {
|
2021-01-17 21:50:42 -03:00
|
|
|
// No evaluation until is absolutely needed
|
2021-01-07 23:38:18 -03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
assert(0);
|
|
|
|
|
|
|
|
push(d);
|
|
|
|
return 0;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-01-17 21:50:42 -03:00
|
|
|
/* add top two elems on stack */
|
2021-01-12 20:49:12 -03:00
|
|
|
int add() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
2021-01-09 16:11:30 -03:00
|
|
|
if (d1.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
d1.u.val = d1.u.sym->u.val;
|
|
|
|
d1.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (d2.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
d2.u.val = d2.u.sym->u.val;
|
|
|
|
d2.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
assert(d1.type == NUM);
|
|
|
|
assert(d2.type == NUM);
|
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
//printf("adding %d %d\n",d1.val, d2.val);
|
|
|
|
d1.u.val += d2.u.val;
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int negate() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d;
|
|
|
|
d = pop();
|
|
|
|
int v;
|
|
|
|
if (d.type == NAME) {
|
2021-01-14 18:48:30 -03:00
|
|
|
//debug("negating %s", d.u.sym->name->c_str());
|
2021-01-07 23:38:18 -03:00
|
|
|
v = d.u.sym->u.val;
|
|
|
|
d.type = NUM;
|
|
|
|
}
|
|
|
|
else if (d.type == NUM) {
|
|
|
|
v = d.u.val;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
assert(0);
|
|
|
|
|
|
|
|
d.u.val = !v;
|
|
|
|
push(d);
|
|
|
|
return 0;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int gt() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
2021-01-09 16:11:30 -03:00
|
|
|
if (d1.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d1.u.val = d1.u.sym->u.val;
|
|
|
|
d1.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (d2.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d2.u.val = d2.u.sym->u.val;
|
|
|
|
d2.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
d1.u.val = (int)(d1.u.val > d2.u.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
2020-12-30 21:26:15 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int lt() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
2021-01-09 16:11:30 -03:00
|
|
|
if (d1.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d1.u.val = d1.u.sym->u.val;
|
|
|
|
d1.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (d2.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d2.u.val = d2.u.sym->u.val;
|
|
|
|
d2.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
d1.u.val = (int)(d1.u.val < d2.u.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
2020-12-30 21:26:15 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int ge() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
2021-01-09 16:11:30 -03:00
|
|
|
if (d1.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d1.u.val = d1.u.sym->u.val;
|
|
|
|
d1.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (d2.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d2.u.val = d2.u.sym->u.val;
|
|
|
|
d2.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
d1.u.val = (int)(d1.u.val >= d2.u.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
2020-12-30 21:26:15 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int le() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
2021-01-09 16:11:30 -03:00
|
|
|
if (d1.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d1.u.val = d1.u.sym->u.val;
|
|
|
|
d1.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (d2.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d2.u.val = d2.u.sym->u.val;
|
|
|
|
d2.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
d1.u.val = (int)(d1.u.val <= d2.u.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
2020-12-30 21:26:15 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int eq() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
2021-01-09 16:11:30 -03:00
|
|
|
if (d1.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d1.u.val = d1.u.sym->u.val;
|
|
|
|
d1.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (d2.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d2.u.val = d2.u.sym->u.val;
|
|
|
|
d2.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
d1.u.val = (int)(d1.u.val == d2.u.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
2020-12-30 21:26:15 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int ne() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
2021-01-09 16:11:30 -03:00
|
|
|
if (d1.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d1.u.val = d1.u.sym->u.val;
|
|
|
|
d1.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (d2.type == NAME) {
|
2021-01-09 19:11:41 -03:00
|
|
|
//char *name = d1.u.sym->name->c_str();
|
|
|
|
//debug("eval %s to %d",
|
|
|
|
d2.u.val = d2.u.sym->u.val;
|
|
|
|
d2.type = NUM;
|
2021-01-09 16:11:30 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
d1.u.val = (int)(d1.u.val != d2.u.val);
|
2021-01-07 23:38:18 -03:00
|
|
|
push(d1);
|
|
|
|
return 0;
|
2020-12-30 21:26:15 -03:00
|
|
|
}
|
|
|
|
|
2021-01-17 21:50:42 -03:00
|
|
|
/* install one instruction or operand */
|
2021-01-12 20:49:12 -03:00
|
|
|
Inst *code(Inst f) {
|
2021-01-07 23:38:18 -03:00
|
|
|
//debug("pushing code at %d", progp);
|
|
|
|
Inst *oprogp = progp;
|
|
|
|
assert (!(progp >= &prog[NPROG]));
|
|
|
|
*progp++ = f;
|
|
|
|
return oprogp;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int ifcode() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum d;
|
|
|
|
Inst *savepc = pc; /* then part */
|
|
|
|
debug("ifcode: evaluating condition");
|
|
|
|
|
|
|
|
execute(savepc+3); /* condition */
|
|
|
|
d = pop();
|
|
|
|
|
|
|
|
debug("ifcode: selecting branch");
|
|
|
|
|
|
|
|
if (d.type == NAME) {
|
|
|
|
debug("name %s", d.u.sym->name->c_str()); //, d.sym->u.val);
|
|
|
|
d.u.val = d.u.sym->u.val;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d.u.val) {
|
|
|
|
debug("ifcode: true branch");
|
|
|
|
execute(*((Inst **)(savepc)));
|
|
|
|
}
|
|
|
|
else if (*((Inst **)(savepc+1))) { /* else part? */
|
|
|
|
debug("ifcode: false branch");
|
|
|
|
execute(*((Inst **)(savepc+1)));
|
|
|
|
}
|
|
|
|
debug("ifcode finished");
|
|
|
|
pc = *((Inst **)(savepc+2)); /* next stmt */
|
|
|
|
return 0;
|
2021-01-03 12:19:10 -03:00
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int randbool() {
|
2021-01-10 15:38:10 -03:00
|
|
|
Datum d;
|
|
|
|
d = pop();
|
2021-01-10 20:17:27 -03:00
|
|
|
|
2021-01-10 15:38:10 -03:00
|
|
|
int v = g_private->getRandomBool(d.u.val);
|
2021-01-10 20:17:27 -03:00
|
|
|
|
2021-01-10 15:38:10 -03:00
|
|
|
d.u.val = v;
|
|
|
|
push(d);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-01-12 20:49:12 -03:00
|
|
|
int fail() {
|
2021-01-07 23:38:18 -03:00
|
|
|
assert(0);
|
|
|
|
return 0;
|
2021-01-03 12:19:10 -03:00
|
|
|
}
|
|
|
|
|
2021-01-17 21:50:42 -03:00
|
|
|
/* run the machine */
|
2021-01-12 20:49:12 -03:00
|
|
|
void execute(Inst *p) {
|
2021-01-07 23:38:18 -03:00
|
|
|
for (pc = p; *pc != STOP; ) {
|
|
|
|
(*(*pc++))();
|
|
|
|
}
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
2020-12-30 19:33:25 -03:00
|
|
|
|
|
|
|
}
|