re-fresh
[nedit-bw.git] / typed-Inst.patch
blobe3fa78da4dbb917df361741086fc2eb52a3d318d
1 ---
3 source/interpret.c | 295 ++++++++++++++++++++++++++++++++++++++---------------
4 source/interpret.h | 16 +-
5 2 files changed, 226 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";
20 return 0;
22 - ProgP->op = op;
23 + ProgP->type = OP_INST;
24 + ProgP->val.op = op;
25 ProgP++;
26 return 1;
28 @@ -352,7 +354,8 @@ int AddSym(Symbol *sym, char **msg)
29 *msg = "macro too large";
30 return 0;
32 - ProgP->sym = sym;
33 + ProgP->type = SYM_INST;
34 + ProgP->val.sym = sym;
35 ProgP++;
36 return 1;
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";
47 return 0;
49 - ProgP->value = value;
50 + ProgP->type = IMMED_INST;
51 + ProgP->val.immed = immed;
52 ProgP++;
53 return 1;
55 @@ -380,8 +384,8 @@ int AddBranchOffset(Inst *to, char **msg
56 *msg = "macro too large";
57 return 0;
59 - /* Should be ptrdiff_t for branch offsets */
60 - ProgP->value = to - ProgP;
61 + ProgP->type = BRANCH_INST;
62 + ProgP->val.branch = to - ProgP;
63 ProgP++;
65 return 1;
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";
73 + return 0;
74 + }
75 + from->val.branch = to - from;
77 return 1;
79 @@ -445,10 +453,14 @@ int AddBreakAddr(Inst *addr, char **msg)
80 *msg = "break outside loop";
81 return 0;
83 + if (addr->type != BRANCH_INST) {
84 + *msg = "not a branch instruction for break";
85 + return 0;
86 + }
87 if (!addLoopAddr(addr, msg)) {
88 return 0;
90 - addr->value = NEEDS_BREAK;
91 + addr->val.immed = NEEDS_BREAK;
92 return 1;
95 @@ -458,10 +470,14 @@ int AddContinueAddr(Inst *addr, char **m
96 *msg = "continue outside loop";
97 return 0;
99 + if (addr->type != BRANCH_INST) {
100 + *msg = "not a branch instruction for break";
101 + return 0;
103 if (!addLoopAddr(addr, msg)) {
104 return 0;
106 - addr->value = NEEDS_CONTINUE;
107 + addr->val.immed = NEEDS_CONTINUE;
108 return 1;
111 @@ -485,10 +501,10 @@ int FillLoopAddrs(Inst *breakAddr, Inst
113 if (*LoopStackPtr == NULL)
114 break;
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;
123 else {
124 *msg = "internal error (uat)";
125 return 0;
126 @@ -663,14 +679,20 @@ int ContinueMacro(RestartData *continuat
128 /* Execute an instruction */
129 inst = PC++;
130 - switch (inst->op) {
131 + if (inst->type != OP_INST) {
132 + status = execError("Unexpected instruction of type <%s>",
133 + instTypeToStr(inst->type));
135 + else {
136 + switch (inst->val.op) {
137 #define OP(name, fn) case OP_##name:
138 #include "ops.h"
139 #undef OP
140 - status = (OpFns[inst->op])();
141 - break;
142 - default:
143 - status = execError("Illegal instruction at %p", (char *)inst);
144 + status = (OpFns[inst->val.op])();
145 + break;
146 + default:
147 + status = execError("Illegal instruction at %p", (char *)inst);
151 /* If error return was not STAT_OK, return to caller */
152 @@ -746,7 +768,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 @@ -1324,19 +1346,31 @@ static void addToGlobalSymTab(Symbol *sy
163 #define GET_SYM(s) \
164 do { \
165 - s = PC->sym; \
166 + if (PC->type != SYM_INST) { \
167 + return execError("Unexpected instruction, expected <symbol>: <%s>", \
168 + instTypeToStr(PC->type)); \
169 + } \
170 + s = PC->val.sym; \
171 PC++; \
172 } while (0)
174 #define GET_IMMED(i) \
175 do { \
176 - i = PC->value; \
177 + if (PC->type != IMMED_INST) { \
178 + return execError("Unexpected instruction, expected <immediate>: <%s>", \
179 + instTypeToStr(PC->type)); \
180 + } \
181 + i = PC->val.immed; \
182 PC++; \
183 } while (0)
185 #define GET_BRANCH(a) \
186 do { \
187 - a = PC + PC->value; \
188 + if (PC->type != BRANCH_INST) { \
189 + return execError("Unexpected instruction, expected <branch>: <%s>", \
190 + instTypeToStr(PC->type)); \
191 + } \
192 + a = PC + PC->val.branch; \
193 PC++; \
194 } while (0)
196 @@ -1350,7 +1384,7 @@ static void addToGlobalSymTab(Symbol *sy
197 if (PC == NULL) { \
198 PUSH(dv); \
200 - else if (PC->op == OP_FETCH_RET_VAL) { \
201 + else if (PC->type == OP_INST && PC->val.op == OP_FETCH_RET_VAL) { \
202 PUSH(dv); \
203 PC++; \
205 @@ -4245,6 +4279,23 @@ static const char *tagToStr(enum typeTag
209 +static const char *instTypeToStr(enum instTypes type)
211 + switch (type) {
212 + case OP_INST:
213 + return "operation";
214 + case IMMED_INST:
215 + return "immediate";
216 + case BRANCH_INST:
217 + return "branch";
218 + case SYM_INST:
219 + return "symbol";
220 + case NO_INST:
221 + default:
222 + return "unknown";
226 #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */
227 static char *printdBuffer = NULL;
228 static int printdPos = 0;
229 @@ -4381,20 +4432,75 @@ static void dumpVal(DataValue dv)
230 #endif /* #ifdef DEBUG_DISASSEMBLER */
232 #ifdef DEBUG_DISASSEMBLER /* For debugging code generation */
233 -static void disasmInternal(Inst *inst, int nInstr)
234 +static int checkOperands(Inst *inst, int nopers, ...)
236 - static const char *opNames[] = {
237 + va_list args;
238 + int i;
240 + va_start(args, nopers);
241 + for (i = 0; i < nopers; i++) {
242 + enum instTypes type = va_arg(args, enum instTypes);
243 + if (inst[i].type != type) {
244 + va_end(args);
245 + printd(" operand %d is not of type <%s>",
246 + i + 1, instTypeToStr(type));
247 + return False;
250 + va_end(args);
252 + return True;
255 +static const char *OpNames[] = {
256 #define OP(name, fn) #name,
257 #include "ops.h"
258 #undef OP
259 - };
262 +static void dumpInst(Inst *inst, const char *name)
264 + name = name ? name : instTypeToStr(inst->type);
266 + switch (inst->type) {
267 + case OP_INST:
268 + printd(" <%s %s>", name, OpNames[inst->val.op]);
269 + break;
271 + case IMMED_INST:
272 + printd(" <%s %d>", name, inst->val.immed);
273 + break;
275 + case BRANCH_INST:
276 + printd(" <%s %+td:%p>", name,
277 + inst->val.branch, inst + inst->val.branch);
278 + break;
280 + case SYM_INST:
281 + printd(" <%s %s>", name, inst->val.sym->name);
282 + break;
284 + case NO_INST:
285 + default:
286 + printd(" <unknown inst %d:%p>", inst->type,
287 + *(void **)&inst->val.immed);
288 + break;
292 +static void disasmInternal(Inst *inst, int nInstr)
294 +#define CHECK_OPERANDS(n, ...) \
295 + if (!checkOperands(&inst[i+1], n, __VA_ARGS__)) \
296 + break
298 int i;
299 static size_t opLen;
301 if (!opLen) {
302 for (i = 0; i < N_OPS; ++i) {
303 - if (opLen < strlen(opNames[i])) {
304 - opLen = strlen(opNames[i]);
305 + if (opLen < strlen(OpNames[i])) {
306 + opLen = strlen(OpNames[i]);
310 @@ -4402,25 +4508,33 @@ static void disasmInternal(Inst *inst, i
311 for (i = 0; i < nInstr; ++i) {
312 printd("Prog %10p", &inst[i]);
314 - switch (inst[i].op) {
315 + if (inst[i].type != OP_INST) {
316 + dumpInst(&inst[i], NULL);
317 + printd("\n");
318 + continue;
321 + switch (inst[i].val.op) {
322 #define OP(name, fn) case OP_##name:
323 #include "ops.h"
324 #undef OP
325 - printd(" %*s", (int)opLen, opNames[inst[i].op]);
326 + printd(" %*s", (int)opLen, OpNames[inst[i].val.op]);
328 - switch (inst[i].op) {
329 + switch (inst[i].val.op) {
330 case OP_PUSH_SYM:
331 case OP_ASSIGN:
332 - printd(" %s", inst[i+1].sym->name);
333 - if (inst[i+1].sym->type == CONST_SYM
334 - && inst[i+1].sym->value.tag == STRING_TAG) {
335 - dumpVal(inst[i+1].sym->value);
336 + CHECK_OPERANDS(1, SYM_INST);
337 + dumpInst(&inst[i+1], NULL);
338 + if (inst[i+1].val.sym->type == CONST_SYM
339 + && inst[i+1].val.sym->value.tag == STRING_TAG) {
340 + dumpVal(inst[i+1].val.sym->value);
342 ++i;
343 break;
345 case OP_PUSH_IMMED:
346 - printd(" <immediate %d>", inst[i+1].value);
347 + CHECK_OPERANDS(1, IMMED_INST);
348 + dumpInst(&inst[i+1], NULL);
349 ++i;
350 break;
352 @@ -4428,37 +4542,42 @@ static void disasmInternal(Inst *inst, i
353 case OP_BRANCH_TRUE:
354 case OP_BRANCH_FALSE:
355 case OP_BRANCH_NEVER:
356 - printd(" to=(%+d) %p",
357 - inst[i+1].value, &inst[i+1] + inst[i+1].value);
358 + CHECK_OPERANDS(1, BRANCH_INST);
359 + dumpInst(&inst[i+1], NULL);
360 ++i;
361 break;
363 case OP_CONCAT:
364 - printd(" nExpr=%d", inst[i+1].value);
365 + CHECK_OPERANDS(1, IMMED_INST);
366 + dumpInst(&inst[i+1], "nExpr");
367 ++i;
368 break;
370 case OP_SUBR_CALL: {
371 - int args = inst[i+2].value;
372 - printd(" %s", inst[i+1].sym->name);
373 + int args;
374 + CHECK_OPERANDS(2, SYM_INST, IMMED_INST);
375 + args = inst[i+2].val.immed;
376 + dumpInst(&inst[i+1], NULL);
377 if (args < 0) {
378 - printd(" %d+args[] (%d)", -args - 1, args);
379 + printd("(%d+args[])", -args - 1);
381 else {
382 - printd(" %d args", args);
383 + printd("(%d args)", args);
385 i += 2;
387 break;
389 case OP_SUBR_CALL_UNPACK_ARRAY: {
390 - int args = inst[i+2].value;
391 - printd(" %s", inst[i+1].sym->name);
392 + int args;
393 + CHECK_OPERANDS(2, SYM_INST, IMMED_INST);
394 + args = inst[i+2].val.immed;
395 + dumpInst(&inst[i+1], NULL);
396 if (args < 0) {
397 - printd(" %d+args[] =args[]", -args - 1);
398 + printd("(%d+args[], =args[])", -args - 1);
400 else {
401 - printd(" %d args =args[]", args);
402 + printd("(%d args, =args[])", args);
404 i += 2;
406 @@ -4466,50 +4585,64 @@ static void disasmInternal(Inst *inst, i
408 case OP_BEGIN_ARRAY_ITER:
409 case OP_BEGIN_ARRAY_ITER_ARRAY:
410 - printd(" %s in", inst[i+1].sym->name);
411 + CHECK_OPERANDS(1, SYM_INST);
412 + printd(" in");
413 + dumpInst(&inst[i+1], "aryIter");
414 ++i;
415 break;
417 case OP_ARRAY_ITER:
418 - if (!inst[i+1].value) {
419 + CHECK_OPERANDS(1, IMMED_INST);
420 + if (!inst[i+1].val.immed) {
421 /* without val */
422 - printd(" %s = %s++ end-loop=(%+d) %p",
423 - inst[i+2].sym->name,
424 - inst[i+3].sym->name,
425 - inst[i+4].value,
426 - &inst[i+4] + inst[i+4].value);
427 + CHECK_OPERANDS(4, IMMED_INST,
428 + SYM_INST, SYM_INST, BRANCH_INST);
429 + dumpInst(&inst[i+2], "key");
430 + printd(" :=");
431 + dumpInst(&inst[i+3], "aryIter");
432 + printd("++");
433 + dumpInst(&inst[i+4], "end-loop");
434 i += 4;
436 else {
437 /* with val */
438 - printd(" %s=%s = %s++ end-loop=(%+d) %p",
439 - inst[i+2].sym->name,
440 - inst[i+3].sym->name,
441 - inst[i+4].sym->name,
442 - inst[i+5].value,
443 - &inst[i+5] + inst[i+5].value);
444 + CHECK_OPERANDS(5, IMMED_INST,
445 + SYM_INST, SYM_INST, SYM_INST, BRANCH_INST);
446 + dumpInst(&inst[i+2], "key");
447 + printd(" =");
448 + dumpInst(&inst[i+3], "val");
449 + printd(" :=");
450 + dumpInst(&inst[i+4], "aryIter");
451 + printd("++");
452 + dumpInst(&inst[i+5], "end-loop");
453 i += 5;
455 break;
457 case OP_ARRAY_ITER_ARRAY:
458 - if (!inst[i+1].value) {
459 + CHECK_OPERANDS(1, IMMED_INST);
460 + if (!inst[i+1].val.immed) {
461 /* without val */
462 - printd(" %s[] = %s++ end-loop=(%+d) %p",
463 - inst[i+2].sym->name,
464 - inst[i+3].sym->name,
465 - inst[i+4].value,
466 - &inst[i+4] + inst[i+4].value);
467 + CHECK_OPERANDS(4, IMMED_INST,
468 + SYM_INST, SYM_INST, BRANCH_INST);
469 + dumpInst(&inst[i+2], "keyArr");
470 + printd(" :=");
471 + dumpInst(&inst[i+3], "aryIter");
472 + printd("++");
473 + dumpInst(&inst[i+4], "end-loop");
474 i += 4;
476 else {
477 /* with val */
478 - printd(" %s[]=%s = %s++ end-loop=(%+d) %p",
479 - inst[i+2].sym->name,
480 - inst[i+3].sym->name,
481 - inst[i+4].sym->name,
482 - inst[i+5].value,
483 - &inst[i+5] + inst[i+5].value);
484 + CHECK_OPERANDS(5, IMMED_INST,
485 + SYM_INST, SYM_INST, SYM_INST, BRANCH_INST);
486 + dumpInst(&inst[i+2], "keyArr");
487 + printd("[] =");
488 + dumpInst(&inst[i+3], "val");
489 + printd(" :=");
490 + dumpInst(&inst[i+4], "aryIter");
491 + printd("++");
492 + dumpInst(&inst[i+5], "end-loop");
493 i += 5;
495 break;
496 @@ -4520,21 +4653,23 @@ static void disasmInternal(Inst *inst, i
497 case OP_ANONARRAY_INDEX_VAL:
498 case OP_NAMED_ARG1:
499 case OP_NAMED_ARGN:
500 - printd(" nDim=%d", inst[i+1].value);
501 + CHECK_OPERANDS(1, IMMED_INST);
502 + dumpInst(&inst[i+1], "nDim");
503 ++i;
504 break;
506 case OP_ARRAY_REF_ASSIGN_SETUP:
507 - printd(" binOp=%s nDim=%d",
508 - inst[i+1].value ? "true" : "false",
509 - inst[i+2].value);
510 + CHECK_OPERANDS(2, IMMED_INST, IMMED_INST);
511 + printd(" <binOp %s>,",
512 + inst[i+1].val.immed ? "true" : "false");
513 + dumpInst(&inst[i+2], "nDim");
514 i += 2;
515 break;
517 case OP_PUSH_ARRAY_SYM:
518 - printd(" %s %s",
519 - inst[i+1].sym->name,
520 - inst[i+2].value ? "createAndRef" : "refOnly");
521 + CHECK_OPERANDS(2, SYM_INST, IMMED_INST);
522 + dumpInst(&inst[i+1],
523 + inst[i+2].val.immed ? "createAndRef" : "refOnly");
524 i += 2;
525 break;
527 @@ -4546,7 +4681,7 @@ static void disasmInternal(Inst *inst, i
528 break;
530 default:
531 - printd(" <unknown op %d>\n", inst[i].op);
532 + printd(" <unknown op %d>\n", inst[i].val.op);
533 break;
536 diff --quilt old/source/interpret.h new/source/interpret.h
537 --- old/source/interpret.h
538 +++ new/source/interpret.h
539 @@ -54,6 +54,8 @@ enum typeTags {NO_TAG, INT_TAG, STRING_T
541 enum execReturnCodes {MACRO_TIME_LIMIT, MACRO_PREEMPT, MACRO_DONE, MACRO_ERROR};
543 +enum instTypes {NO_INST, OP_INST, IMMED_INST, BRANCH_INST, SYM_INST};
545 #define ARRAY_DIM_SEP "\034"
547 struct DataValueTag;
548 @@ -61,10 +63,14 @@ struct SparseArrayEntryTag;
549 struct ProgramTag;
550 struct SymbolRec;
552 -typedef union InstTag {
553 - enum operations op;
554 - int value;
555 - struct SymbolRec *sym;
556 +typedef struct InstTag {
557 + enum instTypes type;
558 + union {
559 + enum operations op;
560 + int immed;
561 + ptrdiff_t branch;
562 + struct SymbolRec *sym;
563 + } val;
564 } Inst;
566 typedef int (*BuiltInSubr)(WindowInfo *window, struct DataValueTag *argList,
567 @@ -149,7 +155,7 @@ int ArrayCopy(DataValue *dstArray, DataV
568 void BeginCreatingProgram(const char *name, AccumulatorData *acc);
569 int AddOp(int op, char **msg);
570 int AddSym(Symbol *sym, char **msg);
571 -int AddImmediate(int value, char **msg);
572 +int AddImmediate(int immed, char **msg);
573 int AddBranchOffset(Inst *to, char **msg);
574 int SetBranchOffset(Inst *from, Inst *to, char **msg);
575 Inst *GetPC(void);