2020-12-31 17:03:11 -03:00
|
|
|
#include "common/str.h"
|
2020-12-30 09:16:19 -03:00
|
|
|
|
|
|
|
#include "grammar.h"
|
|
|
|
#include "grammar.tab.h"
|
|
|
|
|
2020-12-30 19:33:25 -03:00
|
|
|
namespace Private {
|
|
|
|
|
2020-12-31 17:03:11 -03:00
|
|
|
Setting *psetting;
|
2021-01-01 12:22:05 -03:00
|
|
|
SettingMap settingcode;
|
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 */
|
|
|
|
|
2020-12-31 17:03:11 -03:00
|
|
|
void initsetting() /* initialize for code generation */
|
2020-12-30 09:16:19 -03:00
|
|
|
{
|
2020-12-31 17:03:11 -03:00
|
|
|
psetting = (Setting*) malloc(sizeof(Setting));
|
|
|
|
memset((void *) psetting, 0, sizeof(Setting));
|
2020-12-30 20:57:05 -03:00
|
|
|
|
2020-12-31 17:03:11 -03:00
|
|
|
prog = (Inst *) &psetting->prog;
|
|
|
|
stack = (Datum *) &psetting->stack;
|
2020-12-30 20:57:05 -03:00
|
|
|
|
2020-12-30 09:16:19 -03:00
|
|
|
stackp = stack;
|
|
|
|
progp = prog;
|
|
|
|
}
|
|
|
|
|
2020-12-31 17:03:11 -03:00
|
|
|
void savesetting(char *name)
|
|
|
|
{
|
|
|
|
Common::String s(name);
|
2021-01-01 12:22:05 -03:00
|
|
|
settingcode.setVal(s, psetting);
|
2020-12-31 17:03:11 -03:00
|
|
|
}
|
|
|
|
|
2020-12-30 09:16:19 -03:00
|
|
|
int push(Datum d) /* push d onto stack */
|
|
|
|
{
|
2020-12-31 17:03:11 -03:00
|
|
|
assert (!(stackp >= &stack[NSTACK]));
|
2020-12-30 09:16:19 -03:00
|
|
|
*stackp++ = d;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum pop() /* pop and return top elem from stack */
|
|
|
|
{
|
2020-12-31 17:03:11 -03:00
|
|
|
assert (!(stackp <= stack));
|
2020-12-30 09:16:19 -03:00
|
|
|
return *--stackp;
|
|
|
|
}
|
|
|
|
|
|
|
|
int constpush() /* push constant onto stack */
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
d.val = ((Symbol *)*pc++)->u.val;
|
2020-12-31 17:03:11 -03:00
|
|
|
//printf("pushing %d\n", d.val);
|
2020-12-30 09:16:19 -03:00
|
|
|
push(d);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-12-30 14:34:32 -03:00
|
|
|
int strpush() /* push constant onto stack */
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
d.str = ((Symbol *)*pc++)->u.str;
|
2020-12-31 17:03:11 -03:00
|
|
|
//printf("pushing %s\n", d.str);
|
2020-12-30 14:34:32 -03:00
|
|
|
push(d);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-30 09:16:19 -03:00
|
|
|
int varpush() /* push variable onto stack */
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
d.sym = (Symbol *)(*pc++);
|
2020-12-31 17:03:11 -03:00
|
|
|
//printf("var pushing %s", d.sym->name);
|
2020-12-30 09:16:19 -03:00
|
|
|
push(d);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int eval() /* evaluate variable on stack */
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
d = pop();
|
|
|
|
//if (d.sym->type == UNDEF)
|
|
|
|
// execerror("undefined variable", d.sym->name);
|
|
|
|
d.val = d.sym->u.val;
|
|
|
|
push(d);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int add() /* add top two elems on stack */
|
|
|
|
{
|
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
2020-12-31 17:03:11 -03:00
|
|
|
//printf("adding %d %d\n",d1.val, d2.val);
|
2020-12-30 09:16:19 -03:00
|
|
|
d1.val += d2.val;
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int negate()
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
d = pop();
|
|
|
|
d.val = !d.val;
|
|
|
|
push(d);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int assign() /* assign top value to next value */
|
|
|
|
{
|
|
|
|
Datum d1, d2;
|
|
|
|
d1 = pop();
|
|
|
|
d2 = pop();
|
|
|
|
/*if (d1.sym->type != VAR && d1.sym->type != UNDEF)
|
|
|
|
execerror("assignment to non-variable",
|
|
|
|
d1.sym->name);*/
|
|
|
|
d1.sym->u.val = d2.val;
|
|
|
|
d1.sym->type = NAME;
|
|
|
|
push(d2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-12-30 21:26:15 -03:00
|
|
|
int gt()
|
|
|
|
{
|
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
|
|
|
d1.val = (int)(d1.val > d2.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lt()
|
|
|
|
{
|
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
|
|
|
d1.val = (int)(d1.val < d2.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ge()
|
|
|
|
{
|
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
|
|
|
d1.val = (int)(d1.val >= d2.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int le()
|
|
|
|
{
|
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
|
|
|
d1.val = (int)(d1.val <= d2.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int eq()
|
|
|
|
{
|
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
|
|
|
d1.val = (int)(d1.val == d2.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ne()
|
|
|
|
{
|
|
|
|
Datum d1, d2;
|
|
|
|
d2 = pop();
|
|
|
|
d1 = pop();
|
|
|
|
d1.val = (int)(d1.val != d2.val);
|
|
|
|
push(d1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-12-30 09:16:19 -03:00
|
|
|
int print() /* pop top value from stack, print it */
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
d = pop();
|
2020-12-31 17:03:11 -03:00
|
|
|
//printf("\t%d\n", d.val);
|
2020-12-30 09:16:19 -03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Inst *code(Inst f) /* install one instruction or operand */
|
|
|
|
{
|
2020-12-30 20:57:05 -03:00
|
|
|
Inst *oprogp = progp;
|
2020-12-31 17:03:11 -03:00
|
|
|
assert (!(progp >= &prog[NPROG]));
|
2020-12-30 09:16:19 -03:00
|
|
|
*progp++ = f;
|
|
|
|
return oprogp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void execute(Inst *p) /* run the machine */
|
|
|
|
{
|
|
|
|
for (pc = p; *pc != STOP; )
|
|
|
|
(*(*pc++))();
|
|
|
|
}
|
2020-12-30 19:33:25 -03:00
|
|
|
|
|
|
|
}
|