3 source/interpret.c | 293 ++++++++++++++++++++++++++++++++++++++---------------
4 source/interpret.h | 16 +-
5 2 files changed, 224 insertions(+), 85 deletions(-)
7 diff --quilt old/source/interpret.c new/source/interpret.c
8 --- old/source/interpret.c
9 +++ new/source/interpret.c
10 @@ -112,6 +112,7 @@ static SparseArrayEntry *allocateSparseA
11 static int inTypeOfMode;
13 static const char *tagToStr(enum typeTags tag);
14 +static const char *instTypeToStr(enum instTypes type);
16 /*#define DEBUG_ASSEMBLY*/
17 /*#define DEBUG_STACK*/
18 @@ -338,7 +339,8 @@ int AddOp(int op, char **msg)
19 *msg = "macro too large";
23 + ProgP->type = OP_INST;
28 @@ -352,7 +354,8 @@ int AddSym(Symbol *sym, char **msg)
29 *msg = "macro too large";
33 + ProgP->type = SYM_INST;
34 + ProgP->val.sym = sym;
38 @@ -360,13 +363,14 @@ int AddSym(Symbol *sym, char **msg)
40 ** Add an immediate value operand to the current program
42 -int AddImmediate(int value, char **msg)
43 +int AddImmediate(int immed, char **msg)
45 if (ProgP >= &Prog[PROGRAM_SIZE]) {
46 *msg = "macro too large";
49 - ProgP->value = value;
50 + ProgP->type = IMMED_INST;
51 + ProgP->val.immed = immed;
55 @@ -380,8 +384,8 @@ int AddBranchOffset(Inst *to, char **msg
56 *msg = "macro too large";
59 - /* Should be ptrdiff_t for branch offsets */
60 - ProgP->value = to - ProgP;
61 + ProgP->type = BRANCH_INST;
62 + ProgP->val.branch = to - ProgP;
66 @@ -392,7 +396,11 @@ int AddBranchOffset(Inst *to, char **msg
68 int SetBranchOffset(Inst *from, Inst *to, char **msg)
70 - from->value = to - from;
71 + if (from->type != BRANCH_INST) {
72 + *msg = "not a branch instruction";
75 + from->val.branch = to - from;
79 @@ -445,10 +453,14 @@ int AddBreakAddr(Inst *addr, char **msg)
80 *msg = "break outside loop";
83 + if (addr->type != BRANCH_INST) {
84 + *msg = "not a branch instruction for break";
87 if (!addLoopAddr(addr, msg)) {
90 - addr->value = NEEDS_BREAK;
91 + addr->val.immed = NEEDS_BREAK;
95 @@ -458,10 +470,14 @@ int AddContinueAddr(Inst *addr, char **m
96 *msg = "continue outside loop";
99 + if (addr->type != BRANCH_INST) {
100 + *msg = "not a branch instruction for break";
103 if (!addLoopAddr(addr, msg)) {
106 - addr->value = NEEDS_CONTINUE;
107 + addr->val.immed = NEEDS_CONTINUE;
111 @@ -485,10 +501,10 @@ void FillLoopAddrs(Inst *breakAddr, Inst
113 if (*LoopStackPtr == NULL)
115 - if ((*LoopStackPtr)->value == NEEDS_BREAK)
116 - (*LoopStackPtr)->value = breakAddr - *LoopStackPtr;
117 - else if ((*LoopStackPtr)->value == NEEDS_CONTINUE)
118 - (*LoopStackPtr)->value = continueAddr - *LoopStackPtr;
119 + if ((*LoopStackPtr)->val.immed == NEEDS_BREAK)
120 + (*LoopStackPtr)->val.branch = breakAddr - *LoopStackPtr;
121 + else if ((*LoopStackPtr)->val.immed == NEEDS_CONTINUE)
122 + (*LoopStackPtr)->val.branch = continueAddr - *LoopStackPtr;
124 fprintf(stderr, "NEdit: internal error (uat) in macro parser\n");
126 @@ -660,14 +676,20 @@ int ContinueMacro(RestartData *continuat
128 /* Execute an instruction */
130 - switch (inst->op) {
131 + if (inst->type != OP_INST) {
132 + status = execError("Unexpected instruction of type <%s>",
133 + instTypeToStr(inst->type));
136 + switch (inst->val.op) {
137 #define OP(name, fn) case OP_##name:
140 - status = (OpFns[inst->op])();
143 - status = execError("Illegal instruction at %8p", (char *)inst);
144 + status = (OpFns[inst->val.op])();
147 + status = execError("Illegal instruction at %8p", (char *)inst);
151 /* If error return was not STAT_OK, return to caller */
152 @@ -743,7 +765,7 @@ void PreemptMacro(void)
154 void ModifyReturnedValue(RestartData *context, DataValue dv)
156 - if ((context->pc-1)->op == OP_FETCH_RET_VAL)
157 + if ((context->pc-1)->val.op == OP_FETCH_RET_VAL)
158 *(context->stackP-1) = dv;
161 @@ -1321,19 +1343,31 @@ static void addToGlobalSymTab(Symbol *sy
166 + if (PC->type != SYM_INST) { \
167 + return execError("Unexpected instruction, expected <symbol>: <%s>", \
168 + instTypeToStr(PC->type)); \
174 #define GET_IMMED(i) \
177 + if (PC->type != IMMED_INST) { \
178 + return execError("Unexpected instruction, expected <immediate>: <%s>", \
179 + instTypeToStr(PC->type)); \
181 + i = PC->val.immed; \
185 #define GET_BRANCH(a) \
187 - a = PC + PC->value; \
188 + if (PC->type != BRANCH_INST) { \
189 + return execError("Unexpected instruction, expected <branch>: <%s>", \
190 + instTypeToStr(PC->type)); \
192 + a = PC + PC->val.branch; \
196 @@ -1347,7 +1381,7 @@ static void addToGlobalSymTab(Symbol *sy
200 - else if (PC->op == OP_FETCH_RET_VAL) { \
201 + else if (PC->type == OP_INST && PC->val.op == OP_FETCH_RET_VAL) { \
205 @@ -4242,6 +4276,22 @@ static const char *tagToStr(enum typeTag
209 +static const char *instTypeToStr(enum instTypes type)
213 + return "operation";
215 + return "immediate";
225 #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */
226 static char *printdBuffer = NULL;
227 static int printdPos = 0;
228 @@ -4378,20 +4428,74 @@ static void dumpVal(DataValue dv)
229 #endif /* #ifdef DEBUG_DISASSEMBLER */
231 #ifdef DEBUG_DISASSEMBLER /* For debugging code generation */
232 -static void disasmInternal(Inst *inst, int nInstr)
233 +static int checkOperands(Inst *inst, int nopers, ...)
235 - static const char *opNames[] = {
239 + va_start(args, nopers);
240 + for (i = 0; i < nopers; i++) {
241 + enum instTypes type = va_arg(args, enum instTypes);
242 + if (inst[i].type != type) {
244 + printd(" operand %d is not of type <%s>",
245 + i + 1, instTypeToStr(type));
254 +static const char *OpNames[] = {
255 #define OP(name, fn) #name,
261 +static void dumpInst(Inst *inst, const char *name)
263 + name = name ? name : instTypeToStr(inst->type);
265 + switch (inst->type) {
267 + printd(" <%s %s>", name, OpNames[inst->val.op]);
271 + printd(" <%s %d>", name, inst->val.immed);
275 + printd(" <%s %+td:%8p>", name,
276 + inst->val.branch, inst + inst->val.branch);
280 + printd(" <%s %s>", name, inst->val.sym->name);
284 + printd(" <unknown inst %d:%8p>", inst->type,
285 + *(void **)&inst->val.immed);
290 +static void disasmInternal(Inst *inst, int nInstr)
292 +#define CHECK_OPERANDS(n, ...) \
293 + if (!checkOperands(&inst[i+1], n, __VA_ARGS__)) \
300 for (i = 0; i < N_OPS; ++i) {
301 - if (opLen < strlen(opNames[i])) {
302 - opLen = strlen(opNames[i]);
303 + if (opLen < strlen(OpNames[i])) {
304 + opLen = strlen(OpNames[i]);
308 @@ -4399,25 +4503,33 @@ static void disasmInternal(Inst *inst, i
309 for (i = 0; i < nInstr; ++i) {
310 printd("Prog %8p", &inst[i]);
312 - switch (inst[i].op) {
313 + if (inst[i].type != OP_INST) {
314 + dumpInst(&inst[i], NULL);
319 + switch (inst[i].val.op) {
320 #define OP(name, fn) case OP_##name:
323 - printd(" %*s", (int)opLen, opNames[inst[i].op]);
324 + printd(" %*s", (int)opLen, OpNames[inst[i].val.op]);
326 - switch (inst[i].op) {
327 + switch (inst[i].val.op) {
330 - printd(" %s", inst[i+1].sym->name);
331 - if (inst[i+1].sym->type == CONST_SYM
332 - && inst[i+1].sym->value.tag == STRING_TAG) {
333 - dumpVal(inst[i+1].sym->value);
334 + CHECK_OPERANDS(1, SYM_INST);
335 + dumpInst(&inst[i+1], NULL);
336 + if (inst[i+1].val.sym->type == CONST_SYM
337 + && inst[i+1].val.sym->value.tag == STRING_TAG) {
338 + dumpVal(inst[i+1].val.sym->value);
344 - printd(" <immediate %d>", inst[i+1].value);
345 + CHECK_OPERANDS(1, IMMED_INST);
346 + dumpInst(&inst[i+1], NULL);
350 @@ -4425,37 +4537,42 @@ static void disasmInternal(Inst *inst, i
352 case OP_BRANCH_FALSE:
353 case OP_BRANCH_NEVER:
354 - printd(" to=(%+d) %8p",
355 - inst[i+1].value, &inst[i+1] + inst[i+1].value);
356 + CHECK_OPERANDS(1, BRANCH_INST);
357 + dumpInst(&inst[i+1], NULL);
362 - printd(" nExpr=%d", inst[i+1].value);
363 + CHECK_OPERANDS(1, IMMED_INST);
364 + dumpInst(&inst[i+1], "nExpr");
369 - int args = inst[i+2].value;
370 - printd(" %s", inst[i+1].sym->name);
372 + CHECK_OPERANDS(2, SYM_INST, IMMED_INST);
373 + args = inst[i+2].val.immed;
374 + dumpInst(&inst[i+1], NULL);
376 - printd(" %d+args[] (%d)", -args - 1, args);
377 + printd("(%d+args[])", -args - 1);
380 - printd(" %d args", args);
381 + printd("(%d args)", args);
387 case OP_SUBR_CALL_UNPACK_ARRAY: {
388 - int args = inst[i+2].value;
389 - printd(" %s", inst[i+1].sym->name);
391 + CHECK_OPERANDS(2, SYM_INST, IMMED_INST);
392 + args = inst[i+2].val.immed;
393 + dumpInst(&inst[i+1], NULL);
395 - printd(" %d+args[] =args[]", -args - 1);
396 + printd("(%d+args[], =args[])", -args - 1);
399 - printd(" %d args =args[]", args);
400 + printd("(%d args, =args[])", args);
404 @@ -4463,50 +4580,64 @@ static void disasmInternal(Inst *inst, i
406 case OP_BEGIN_ARRAY_ITER:
407 case OP_BEGIN_ARRAY_ITER_ARRAY:
408 - printd(" %s in", inst[i+1].sym->name);
409 + CHECK_OPERANDS(1, SYM_INST);
411 + dumpInst(&inst[i+1], "aryIter");
416 - if (!inst[i+1].value) {
417 + CHECK_OPERANDS(1, IMMED_INST);
418 + if (!inst[i+1].val.immed) {
420 - printd(" %s = %s++ end-loop=(%+d) %8p",
421 - inst[i+2].sym->name,
422 - inst[i+3].sym->name,
424 - &inst[i+4] + inst[i+4].value);
425 + CHECK_OPERANDS(4, IMMED_INST,
426 + SYM_INST, SYM_INST, BRANCH_INST);
427 + dumpInst(&inst[i+2], "key");
429 + dumpInst(&inst[i+3], "aryIter");
431 + dumpInst(&inst[i+4], "end-loop");
436 - printd(" %s=%s = %s++ end-loop=(%+d) %8p",
437 - inst[i+2].sym->name,
438 - inst[i+3].sym->name,
439 - inst[i+4].sym->name,
441 - &inst[i+5] + inst[i+5].value);
442 + CHECK_OPERANDS(5, IMMED_INST,
443 + SYM_INST, SYM_INST, SYM_INST, BRANCH_INST);
444 + dumpInst(&inst[i+2], "key");
446 + dumpInst(&inst[i+3], "val");
448 + dumpInst(&inst[i+4], "aryIter");
450 + dumpInst(&inst[i+5], "end-loop");
455 case OP_ARRAY_ITER_ARRAY:
456 - if (!inst[i+1].value) {
457 + CHECK_OPERANDS(1, IMMED_INST);
458 + if (!inst[i+1].val.immed) {
460 - printd(" %s[] = %s++ end-loop=(%+d) %8p",
461 - inst[i+2].sym->name,
462 - inst[i+3].sym->name,
464 - &inst[i+4] + inst[i+4].value);
465 + CHECK_OPERANDS(4, IMMED_INST,
466 + SYM_INST, SYM_INST, BRANCH_INST);
467 + dumpInst(&inst[i+2], "keyArr");
469 + dumpInst(&inst[i+3], "aryIter");
471 + dumpInst(&inst[i+4], "end-loop");
476 - printd(" %s[]=%s = %s++ end-loop=(%+d) %8p",
477 - inst[i+2].sym->name,
478 - inst[i+3].sym->name,
479 - inst[i+4].sym->name,
481 - &inst[i+5] + inst[i+5].value);
482 + CHECK_OPERANDS(5, IMMED_INST,
483 + SYM_INST, SYM_INST, SYM_INST, BRANCH_INST);
484 + dumpInst(&inst[i+2], "keyArr");
486 + dumpInst(&inst[i+3], "val");
488 + dumpInst(&inst[i+4], "aryIter");
490 + dumpInst(&inst[i+5], "end-loop");
494 @@ -4517,21 +4648,23 @@ static void disasmInternal(Inst *inst, i
495 case OP_ANONARRAY_INDEX_VAL:
498 - printd(" nDim=%d", inst[i+1].value);
499 + CHECK_OPERANDS(1, IMMED_INST);
500 + dumpInst(&inst[i+1], "nDim");
504 case OP_ARRAY_REF_ASSIGN_SETUP:
505 - printd(" binOp=%s nDim=%d",
506 - inst[i+1].value ? "true" : "false",
508 + CHECK_OPERANDS(2, IMMED_INST, IMMED_INST);
509 + printd(" <binOp %s>,",
510 + inst[i+1].val.immed ? "true" : "false");
511 + dumpInst(&inst[i+2], "nDim");
515 case OP_PUSH_ARRAY_SYM:
517 - inst[i+1].sym->name,
518 - inst[i+2].value ? "createAndRef" : "refOnly");
519 + CHECK_OPERANDS(2, SYM_INST, IMMED_INST);
520 + dumpInst(&inst[i+1],
521 + inst[i+2].val.immed ? "createAndRef" : "refOnly");
525 @@ -4543,7 +4676,7 @@ static void disasmInternal(Inst *inst, i
529 - printd(" <unknown op %d>\n", inst[i].op);
530 + printd(" <unknown op %d>\n", inst[i].val.op);
534 diff --quilt old/source/interpret.h new/source/interpret.h
535 --- old/source/interpret.h
536 +++ new/source/interpret.h
537 @@ -54,6 +54,8 @@ enum typeTags {NO_TAG, INT_TAG, STRING_T
539 enum execReturnCodes {MACRO_TIME_LIMIT, MACRO_PREEMPT, MACRO_DONE, MACRO_ERROR};
541 +enum instTypes {OP_INST, IMMED_INST, BRANCH_INST, SYM_INST};
543 #define ARRAY_DIM_SEP "\034"
546 @@ -61,10 +63,14 @@ struct SparseArrayEntryTag;
550 -typedef union InstTag {
551 - enum operations op;
553 - struct SymbolRec *sym;
554 +typedef struct InstTag {
555 + enum instTypes type;
557 + enum operations op;
560 + struct SymbolRec *sym;
564 typedef int (*BuiltInSubr)(WindowInfo *window, struct DataValueTag *argList,
565 @@ -149,7 +155,7 @@ int ArrayCopy(DataValue *dstArray, DataV
566 void BeginCreatingProgram(const char *name, AccumulatorData *acc);
567 int AddOp(int op, char **msg);
568 int AddSym(Symbol *sym, char **msg);
569 -int AddImmediate(int value, char **msg);
570 +int AddImmediate(int immed, char **msg);
571 int AddBranchOffset(Inst *to, char **msg);
572 int SetBranchOffset(Inst *from, Inst *to, char **msg);