2021-02-13 14:55:30 -03:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2021-02-16 21:44:16 -03:00
|
|
|
// Heavily inspired by hoc
|
|
|
|
// Copyright (C) AT&T 1995
|
|
|
|
// All Rights Reserved
|
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and distribute this software and
|
|
|
|
// its documentation for any purpose and without fee is hereby
|
|
|
|
// granted, provided that the above copyright notice appear in all
|
|
|
|
// copies and that both that the copyright notice and this
|
|
|
|
// permission notice and warranty disclaimer appear in supporting
|
|
|
|
// documentation, and that the name of AT&T or any of its entities
|
|
|
|
// not be used in advertising or publicity pertaining to
|
|
|
|
// distribution of the software without specific, written prior
|
|
|
|
// permission.
|
|
|
|
//
|
|
|
|
// AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
|
|
// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
|
|
|
// IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
|
|
|
// SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
|
|
|
// IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
|
|
// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
|
|
// THIS SOFTWARE.
|
|
|
|
|
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
|
|
|
|
2021-02-13 16:43:38 -03:00
|
|
|
#include "private/grammar.h"
|
2021-02-14 18:15:59 -03:00
|
|
|
#include "private/tokens.h"
|
2021-02-13 16:43:38 -03:00
|
|
|
#include "private/private.h"
|
2020-12-30 09:16:19 -03:00
|
|
|
|
2020-12-30 19:33:25 -03:00
|
|
|
namespace Private {
|
|
|
|
|
2021-02-13 18:44:23 -03:00
|
|
|
Datum *stack = NULL; /* the stack */
|
|
|
|
Datum *stackp = NULL; /* next free spot on stack */
|
2020-12-30 20:57:05 -03:00
|
|
|
|
2021-02-13 18:44:23 -03:00
|
|
|
Inst *prog = NULL; /* the machine */
|
|
|
|
Inst *progp = NULL; /* next free spot for code generation */
|
|
|
|
Inst *pc = NULL; /* program counter during execution */
|
2020-12-30 20:57:05 -03:00
|
|
|
|
2021-02-17 20:36:22 -03:00
|
|
|
/* initialize setting for code generation */
|
|
|
|
void SettingMaps::init() {
|
2021-02-15 00:17:29 -03:00
|
|
|
setting = (Setting *)malloc(sizeof(Setting));
|
2021-02-13 16:43:38 -03:00
|
|
|
memset((void *)setting, 0, sizeof(Setting));
|
2020-12-30 20:57:05 -03:00
|
|
|
|
2021-02-13 16:43:38 -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-02-17 20:36:22 -03:00
|
|
|
void SettingMaps::save(char *name) {
|
|
|
|
map.setVal(name, setting);
|
2021-01-02 00:58:58 -03:00
|
|
|
}
|
|
|
|
|
2021-02-17 20:36:22 -03:00
|
|
|
void SettingMaps::load(Common::String *name) {
|
|
|
|
assert(map.contains(*name));
|
|
|
|
setting = map.getVal(*name);
|
2021-01-02 00:58:58 -03:00
|
|
|
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "loading setting %s", name->c_str());
|
2021-01-02 00:58:58 -03:00
|
|
|
|
2021-02-13 16:43:38 -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;
|
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 */
|
2021-02-13 18:44:23 -03:00
|
|
|
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-02-13 18:44:23 -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;
|
|
|
|
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "pushing const %d with name %s", d.u.val, s->name->c_str());
|
2021-01-07 23:38:18 -03:00
|
|
|
push(d);
|
|
|
|
return 0;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-02-13 18:13:40 -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;
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "pushing const %s with name %s", d.u.str, s->name->c_str());
|
|
|
|
|
2021-01-07 23:38:18 -03:00
|
|
|
push(d);
|
|
|
|
return 0;
|
2020-12-30 14:34:32 -03:00
|
|
|
}
|
|
|
|
|
2021-02-13 18:44:23 -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++);
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "var pushing %s", d.u.sym->name->c_str());
|
2021-01-07 23:38:18 -03:00
|
|
|
push(d);
|
|
|
|
return 0;
|
2020-12-30 09:16:19 -03:00
|
|
|
}
|
|
|
|
|
2021-02-13 18:13:40 -03:00
|
|
|
int funcpush() {
|
2021-01-07 23:38:18 -03:00
|
|
|
Datum s, n, arg;
|
|
|
|
s = pop();
|
|
|
|
n = pop();
|
|
|
|
ArgArray args;
|
|
|
|
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "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();
|
|
|
|
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-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "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-02-13 19:11:11 -03:00
|
|
|
} else
|
2021-01-07 23:38:18 -03:00
|
|
|
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-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "adding %d %d\n", d1.u.val, d2.u.val);
|
2021-01-07 23:38:18 -03:00
|
|
|
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;
|
2021-02-13 19:11:11 -03:00
|
|
|
} else if (d.type == NUM) {
|
2021-01-07 23:38:18 -03:00
|
|
|
v = d.u.val;
|
2021-02-13 19:11:11 -03:00
|
|
|
} else
|
2021-01-07 23:38:18 -03:00
|
|
|
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
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
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-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "pushing code at %x", progp);
|
2021-01-07 23:38:18 -03:00
|
|
|
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;
|
2021-02-13 18:44:23 -03:00
|
|
|
Inst *savepc = pc; /* then part */
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "ifcode: evaluating condition");
|
2021-01-07 23:38:18 -03:00
|
|
|
|
2021-02-13 18:44:23 -03:00
|
|
|
execute(savepc+3); /* condition */
|
2021-01-07 23:38:18 -03:00
|
|
|
d = pop();
|
|
|
|
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "ifcode: selecting branch");
|
2021-01-07 23:38:18 -03:00
|
|
|
|
|
|
|
if (d.type == NAME) {
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "name %s", d.u.sym->name->c_str());
|
2021-01-07 23:38:18 -03:00
|
|
|
d.u.val = d.u.sym->u.val;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d.u.val) {
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "ifcode: true branch");
|
2021-01-07 23:38:18 -03:00
|
|
|
execute(*((Inst **)(savepc)));
|
2021-02-13 19:11:11 -03:00
|
|
|
} else if (*((Inst **)(savepc+1))) { /* else part? */
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "ifcode: false branch");
|
2021-01-07 23:38:18 -03:00
|
|
|
execute(*((Inst **)(savepc+1)));
|
|
|
|
}
|
2021-02-14 13:15:36 -03:00
|
|
|
debugC(1, kPrivateDebugCode, "ifcode finished");
|
2021-02-13 18:44:23 -03:00
|
|
|
pc = *((Inst **)(savepc+2)); /* next stmt */
|
2021-01-07 23:38:18 -03:00
|
|
|
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
|
|
|
|
2021-02-13 18:27:24 -03:00
|
|
|
} // End of namespace Private
|