fix switch statement
[nedit-bw.git] / symbol-lookup.patch
blob9ebdf607098957256a8cdb2f42a131932dfc5e04
1 ---
3 source/interpret.c | 267 +++++++++++++++--------------------------------------
4 source/interpret.h | 8 -
5 source/macro.c | 6 -
6 source/ops.h | 2
7 source/parse.y | 77 ++++++---------
8 5 files changed, 117 insertions(+), 243 deletions(-)
10 diff --quilt old/source/interpret.c new/source/interpret.c
11 --- old/source/interpret.c
12 +++ new/source/interpret.c
13 @@ -171,7 +171,6 @@ static AccumulatorData *Accumulator;
14 #define ProgP (Accumulator->progP)
15 #define LoopStack (Accumulator->loopStack)
16 #define LoopStackPtr (Accumulator->loopStackPtr)
17 -#define LocalSymList (Accumulator->localSymList)
18 #define ProgramName (Accumulator->name)
20 /* Global data for the interpreter */
21 @@ -213,8 +212,8 @@ static int (*OpFns[])() = {
22 #define FP_GET_PROG(xFrameP) ((FP_GET_ITEM(xFrameP, FP_PROG_INDEX)).val.prog)
23 #define FP_ARG_START_INDEX(xFrameP) (-(FP_GET_ARG_COUNT(xFrameP) + FP_TO_ARGS_DIST))
24 #define FP_GET_ARG_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN + FP_ARG_START_INDEX(xFrameP)))
25 -#define FP_GET_SYM_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN))
26 -#define FP_GET_SYM_VAL(xFrameP,xSym) (FP_GET_SYM_N(xFrameP, xSym->value.val.n))
27 +#define FP_GET_SYM_TAB(xFrameP) (FP_GET_ITEM(xFrameP, FP_SYMBOL_TABLE).val.sym)
28 +#define LocalSymList FP_GET_SYM_TAB(Interpreter->frameP)
31 ** Initialize macro language global variables. Must be called before
32 @@ -269,7 +268,6 @@ AccumulatorData *BeginCreatingProgram(co
33 AccumulatorData *old = Accumulator;
34 Accumulator = XtNew(AccumulatorData);
36 - LocalSymList = NULL;
37 ProgP = Prog;
38 LoopStackPtr = LoopStack;
39 ProgramName = name;
40 @@ -285,22 +283,15 @@ AccumulatorData *BeginCreatingProgram(co
41 Program *FinishCreatingProgram(AccumulatorData *old)
43 Program *newProg;
44 - int progLen, fpOffset = 0;
45 - Symbol *s;
46 + int progLen;
48 newProg = XtNew(Program);
49 newProg->name = LookupString(ProgramName, True);
50 progLen = ProgP - Prog;
51 newProg->code = (Inst *)XtCalloc(progLen, sizeof(Inst));
52 memcpy(newProg->code, Prog, progLen * sizeof(Inst));
53 - newProg->localSymList = LocalSymList;
54 newProg->refcount = 1;
56 - /* Local variables' values are stored on the stack. Here we assign
57 - frame pointer offsets to them. */
58 - for (s = newProg->localSymList; s != NULL; s = s->next)
59 - s->value.val.n = fpOffset++;
61 DISASM(newProg->name, newProg->code, ProgP - Prog);
63 XtFree((char *)Accumulator);
64 @@ -312,7 +303,6 @@ Program *FinishCreatingProgram(Accumulat
65 void FreeProgram(Program *prog)
67 if (--prog->refcount == 0) {
68 - freeSymbolList(prog->localSymList);
69 XtFree((char *)prog->code);
70 XtFree((char *)prog);
72 @@ -336,14 +326,14 @@ int AddOp(int op, char **msg)
74 ** Add a symbol operand to the current program
76 -int AddSym(Symbol *sym, char **msg)
77 +int AddSym(const char *sym, char **msg)
79 if (ProgP >= &Prog[PROGRAM_SIZE]) {
80 *msg = "macro too large";
81 return 0;
83 ProgP->type = SYM_INST;
84 - ProgP->val.sym = sym;
85 + ProgP->val.str = sym;
86 ProgP++;
87 return 1;
89 @@ -525,7 +515,6 @@ static int setupFrame(RestartData *conte
91 static DataValue noValue = {NO_TAG, {0}};
92 int i, totalPushs = 7;
93 - Symbol *s;
96 ** we push only if we have room for the whole frame, so pre-calc the
97 @@ -534,9 +523,6 @@ static int setupFrame(RestartData *conte
98 if (nArgs >= 0) {
99 totalPushs += nArgs;
101 - for (s = prog->localSymList; s != NULL; s = s->next) {
102 - totalPushs++;
105 /* !OK_TO_PUSH(totalPushs) */
106 if (!((context->stackP + totalPushs) <= (context->stack + STACK_SIZE))) {
107 @@ -574,9 +560,9 @@ static int setupFrame(RestartData *conte
108 context->stackP->val.dataval = context->frameP;
109 context->stackP++;
111 - /* symbol table */
112 + /* start a new local symbol list */
113 context->stackP->tag = NO_TAG;
114 - context->stackP->val.sym = prog->localSymList;
115 + context->stackP->val.sym = NULL;
116 context->stackP++;
118 /* macro name */
119 @@ -592,12 +578,6 @@ static int setupFrame(RestartData *conte
121 context->frameP = context->stackP;
123 - /* Initialize and make room on the stack for local variables */
124 - for (s = prog->localSymList; s != NULL; s = s->next) {
125 - FP_GET_SYM_VAL(context->frameP, s) = noValue;
126 - context->stackP++;
129 context->pc = prog->code;
131 return STAT_OK;
132 @@ -610,6 +590,9 @@ static void rewindFrame(RestartData *con
133 DataValue *newFrameP = FP_GET_OLD_FP(context->frameP);
134 Inst *newPC = FP_GET_RET_PC(context->frameP);
135 Program *prog = FP_GET_PROG(context->frameP);
136 + Symbol *symList = FP_GET_SYM_TAB(context->frameP);
138 + freeSymbolList(symList);
140 /* pop past local variables */
141 context->stackP = context->frameP;
142 @@ -850,17 +833,20 @@ static Symbol *lookupSymbol(Symbol *syml
145 ** find a symbol in the symbol table
147 +** will create only LOCAL_SYM and GLOBAL_SYM (depending on first character)
148 +** with a NO_TAG value
150 -Symbol *LookupSymbol(const char *name)
151 +Symbol *LookupSymbol(const char *name, int create)
153 unsigned int hash;
154 - Symbol *s;
155 + Symbol *s = NULL;
157 /* calculate hash for name */
158 hash = hashName(name);
160 /* search in local symbols */
161 - if (Accumulator) {
162 + if (Interpreter) {
163 s = lookupSymbol(LocalSymList, name, hash);
164 if (NULL != s)
165 return s;
166 @@ -871,7 +857,13 @@ Symbol *LookupSymbol(const char *name)
167 if (NULL != s)
168 return s;
170 - return NULL;
171 + if (create) {
172 + DataValue noValue = {NO_TAG, {0}};
173 + s = InstallSymbol(name, name[0] == '$' ? GLOBAL_SYM : LOCAL_SYM,
174 + noValue);
177 + return s;
181 @@ -887,8 +879,17 @@ Symbol *InstallSymbol(const char *name,
182 s->value = value;
183 s->hash = hashName(s->name);
184 if (type == LOCAL_SYM) {
185 - s->next = LocalSymList;
186 - LocalSymList = s;
187 + if (Interpreter) {
188 + s->next = LocalSymList;
189 + LocalSymList = s;
191 + else {
192 + fprintf(stderr,
193 + "NEdit: try to install local symbol without "
194 + "macro context: %s\n", name);
195 + XtFree((char *)s);
196 + s = NULL;
198 } else {
199 addToGlobalSymTab(s);
201 @@ -896,70 +897,6 @@ Symbol *InstallSymbol(const char *name,
205 -** Promote a symbol from local to global, removing it from the local symbol
206 -** list.
208 -** This is used as a forward declaration feature for macro functions.
209 -** If a function is called (ie while parsing the macro) where the
210 -** function isn't defined yet, the symbol is put into the GlobalSymList
211 -** so that the function definition uses the same symbol.
214 -Symbol *PromoteToGlobal(Symbol *sym)
216 - Symbol *s;
218 - if (sym->type != LOCAL_SYM)
219 - return sym;
221 - /* Remove sym from the local symbol list */
222 - if (sym == LocalSymList)
223 - LocalSymList = sym->next;
224 - else {
225 - for (s = LocalSymList; s != NULL; s = s->next) {
226 - if (s->next == sym) {
227 - s->next = sym->next;
228 - break;
233 - /* There are two scenarios which could make this check succeed:
234 - a) this sym is in the GlobalSymList as a LOCAL_SYM symbol
235 - b) there is another symbol as a non-LOCAL_SYM in the GlobalSymList
236 - Both are errors, without question.
237 - We currently just print this warning, but we should error out the
238 - parsing process. */
239 - s = LookupSymbol(sym->name);
240 - if (sym == s) {
241 - /* case a)
242 - just make this symbol a GLOBAL_SYM symbol and return */
243 - fprintf(stderr,
244 - "nedit: To boldly go where no local sym has gone before: %s\n",
245 - sym->name);
246 - sym->type = GLOBAL_SYM;
247 - return sym;
248 - } else if (NULL != s) {
249 - /* case b)
250 - sym will shadow the old symbol from the GlobalSymList */
251 - fprintf(stderr,
252 - "nedit: duplicate symbol in LocalSymList and GlobalSymList: %s\n",
253 - sym->name);
256 - /* Add the symbol directly to the GlobalSymList, because InstallSymbol()
257 - will allocate a new Symbol, which results in a memory leak of sym.
258 - Don't use MACRO_FUNCTION_SYM as type, because in
259 - macro.c:readCheckMacroString() we use ProgramFree() for the .val.prog,
260 - but this symbol has no program attached and ProgramFree() is not NULL
261 - pointer safe */
262 - sym->type = GLOBAL_SYM;
263 - addToGlobalSymTab(sym);
265 - return sym;
269 ** Convert a long value to its decimal string representation, returned in a
270 ** static string.
272 @@ -1129,7 +1066,7 @@ static SparseArrayEntry *allocateSparseA
274 SparseArrayEntryWrapper *mem;
276 - mem = (SparseArrayEntryWrapper *)XtMalloc(sizeof(SparseArrayEntryWrapper));
277 + mem = XtNew(SparseArrayEntryWrapper);
278 mem->next = AllocatedSparseArrayEntries;
279 AllocatedSparseArrayEntries = mem;
280 #ifdef TRACK_GARBAGE_LEAKS
281 @@ -1293,14 +1230,19 @@ static void addToGlobalSymTab(Symbol *sy
283 #define EXEC_ERROR(s1, s2) return execError(Interpreter, s1, s2)
285 -#define GET_SYM(s) \
286 +#define GET_SYM(s, create) \
287 do { \
288 + const char *_n; \
289 if (PC->type != SYM_INST) { \
290 EXEC_ERROR("Unexpected instruction, expected <symbol>: <%s>", \
291 instTypeToStr(PC->type)); \
293 - s = PC->val.sym; \
294 + _n = PC->val.str; \
295 + s = LookupSymbol(_n, create); \
296 PC++; \
297 + if (!s) { \
298 + EXEC_ERROR("No such symbol: %s", _n); \
299 + } \
300 } while (0)
302 #define GET_IMMED(i) \
303 @@ -1511,11 +1453,9 @@ static int pushSymVal(void)
304 DISASM_RT();
305 STACKDUMP(0, 3);
307 - GET_SYM(s);
308 + GET_SYM(s, False);
310 - if (s->type == LOCAL_SYM) {
311 - symVal = FP_GET_SYM_VAL(FrameP, s);
312 - } else if (s->type == GLOBAL_SYM) {
313 + if (s->type == LOCAL_SYM || s->type == GLOBAL_SYM) {
314 symVal = s->value;
315 } else if (s->type == ARG_SYM) {
316 nArgs = FP_GET_ARG_COUNT(FrameP);
317 @@ -1665,18 +1605,13 @@ static int pushArraySymVal(void)
318 DISASM_RT();
319 STACKDUMP(0, 3);
321 - GET_SYM(sym);
322 GET_IMMED(initEmpty);
323 + GET_SYM(sym, initEmpty);
325 - if (sym->type == LOCAL_SYM) {
326 - dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
328 - else if (sym->type == GLOBAL_SYM) {
329 - dataPtr = &sym->value;
331 - else {
332 + if (sym->type != LOCAL_SYM && sym->type != GLOBAL_SYM) {
333 EXEC_ERROR("assigning to non-lvalue array or non-array: %s", sym->name);
335 + dataPtr = &sym->value;
337 if (initEmpty && dataPtr->tag == NO_TAG) {
338 dataPtr->tag = ARRAY_TAG;
339 @@ -1978,7 +1913,7 @@ static int assign(void)
340 DISASM_RT();
341 STACKDUMP(1, 3);
343 - GET_SYM(sym);
344 + GET_SYM(sym, True);
346 if (sym->type != GLOBAL_SYM && sym->type != LOCAL_SYM) {
347 if (sym->type == ARG_SYM) {
348 @@ -1991,13 +1926,7 @@ static int assign(void)
349 EXEC_ERROR("assignment to non-variable: %s", sym->name);
353 - if (sym->type == LOCAL_SYM) {
354 - dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
356 - else {
357 - dataPtr = &sym->value;
359 + dataPtr = &sym->value;
361 POP(value);
363 @@ -2781,7 +2710,7 @@ static int callSubroutine(void)
365 DISASM_RT();
367 - GET_SYM(sym);
368 + GET_SYM(sym, False);
369 GET_IMMED(nArgs);
371 STACKDUMP(nArgs > 0 ? nArgs : -nArgs, 3);
372 @@ -2819,7 +2748,7 @@ static int callSubroutineUnpackArray(voi
374 DISASM_RT();
376 - GET_SYM(sym);
377 + GET_SYM(sym, False);
378 GET_IMMED(nArgs);
380 if (nArgs < 0) {
381 @@ -3630,35 +3559,25 @@ static int arrayIter(void)
382 STACKDUMP(1, 4);
384 GET_IMMED(withVal);
385 - GET_SYM(keySym);
386 + GET_SYM(keySym, True);
387 if (withVal) {
388 - GET_SYM(valSym);
389 + GET_SYM(valSym, True);
391 GET_BRANCH(branchAddr);
393 POP(iterator);
395 - if (keySym->type == LOCAL_SYM) {
396 - keyValPtr = &FP_GET_SYM_VAL(FrameP, keySym);
398 - else if (keySym->type == GLOBAL_SYM) {
399 - keyValPtr = &(keySym->value);
401 - else {
402 + if (keySym->type != LOCAL_SYM && keySym->type != GLOBAL_SYM) {
403 EXEC_ERROR("can't assign to: %s", keySym->name);
405 + keyValPtr = &keySym->value;
406 keyValPtr->tag = NO_TAG;
408 if (withVal) {
409 - if (valSym->type == LOCAL_SYM) {
410 - valPtr = &FP_GET_SYM_VAL(FrameP, valSym);
412 - else if (valSym->type == GLOBAL_SYM) {
413 - valPtr = &(valSym->value);
415 - else {
416 + if (valSym->type != LOCAL_SYM && valSym->type != GLOBAL_SYM) {
417 EXEC_ERROR("can't assign to: %s", valSym->name);
419 + valPtr = &valSym->value;
420 valPtr->tag = NO_TAG;
423 @@ -3797,37 +3716,27 @@ static int arrayIterArray(void)
424 STACKDUMP(2, 4);
426 GET_IMMED(withVal);
427 - GET_SYM(keyArraySym);
428 + GET_SYM(keyArraySym, True);
429 if (withVal) {
430 - GET_SYM(valSym);
431 + GET_SYM(valSym, True);
433 GET_BRANCH(branchAddr);
435 POP(iterator);
436 PEEK_INT(nDims, 0);
438 - if (keyArraySym->type == LOCAL_SYM) {
439 - keyArrayPtr = &FP_GET_SYM_VAL(FrameP, keyArraySym);
441 - else if (keyArraySym->type == GLOBAL_SYM) {
442 - keyArrayPtr = &(keyArraySym->value);
444 - else {
445 + if (keyArraySym->type != LOCAL_SYM && keyArraySym->type != GLOBAL_SYM) {
446 EXEC_ERROR("can't assign to: %s", keyArraySym->name);
448 + keyArrayPtr = &keyArraySym->value;
449 keyArrayPtr->tag = ARRAY_TAG;
450 keyArrayPtr->val.arrayPtr = NULL;
452 if (withVal) {
453 - if (valSym->type == LOCAL_SYM) {
454 - valPtr = &FP_GET_SYM_VAL(FrameP, valSym);
456 - else if (valSym->type == GLOBAL_SYM) {
457 - valPtr = &valSym->value;
459 - else {
460 + if (valSym->type != LOCAL_SYM && valSym->type != GLOBAL_SYM) {
461 EXEC_ERROR("can't assign to: %s", valSym->name);
463 + valPtr = &valSym->value;
464 valPtr->tag = NO_TAG;
467 @@ -4583,7 +4492,7 @@ static void dumpInst(Inst *inst, const c
468 break;
470 case SYM_INST:
471 - printd(" <%s %s>", name, inst->val.sym->name);
472 + printd(" <%s %s>", name, inst->val.str);
473 break;
475 case NO_INST:
476 @@ -4763,9 +4672,9 @@ static void disasmInternal(Inst *inst, i
477 break;
479 case OP_PUSH_ARRAY_SYM:
480 - CHECK_OPERANDS(2, SYM_INST, IMMED_INST);
481 - dumpInst(&inst[i+1],
482 - inst[i+2].val.immed ? "createAndRef" : "refOnly");
483 + CHECK_OPERANDS(2, IMMED_INST, SYM_INST);
484 + dumpInst(&inst[i+2],
485 + inst[i+1].val.immed ? "createAndRef" : "refOnly");
486 i += 2;
487 break;
489 @@ -4809,15 +4718,11 @@ static void stackdumpframe(DataValue *ar
490 DataValue *prFP = &FP_GET_ITEM(fp, FP_PROG_INDEX);
491 DataValue *ofFP = &FP_GET_ITEM(fp, FP_OLD_FP_INDEX);
492 DataValue *rpFP = &FP_GET_ITEM(fp, FP_RET_PC_INDEX);
493 + DataValue *lsFP = &FP_GET_ITEM(fp, FP_SYMBOL_TABLE);
494 DataValue *dv;
495 DataValue *endDv = (arg1 > outpt) ? arg1 : outpt;
496 int nArgs = FP_GET_ARG_COUNT(fp);
498 - int nSyms;
499 - static int symLen = 0;
500 - Symbol *syms = FP_GET_ITEM(fp, FP_SYMBOL_TABLE).val.sym;
501 - Symbol *sym;
503 #ifdef DEBUG_STACK_HEADFIRST
504 #else
505 /* do caller's frame */
506 @@ -4826,17 +4731,6 @@ static void stackdumpframe(DataValue *ar
507 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
509 /* do current frame */
510 - /* how many symbols are there? */
511 - for (sym = syms, nSyms = 0; sym != NULL; sym = sym->next) {
512 - nSyms++;
513 - if (symLen < 27) {
514 - int len = strlen(sym->name);
515 - if (len > 27)
516 - len = 27;
517 - if (len > symLen)
518 - symLen = len;
522 /* output instructions between endDv and sp - 1 inclusive */
523 #ifdef DEBUG_STACK_HEADFIRST
524 @@ -4847,7 +4741,6 @@ static void stackdumpframe(DataValue *ar
525 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
527 const char *posFmt = "%-6s";
528 - const char *symName = "";
530 char *pos = "";
531 char buffer[sizeof(STACK_DUMP_ARG_PREFIX) + TYPE_INT_STR_SIZE(int)];
532 @@ -4871,25 +4764,10 @@ static void stackdumpframe(DataValue *ar
533 sprintf(pos = buffer, STACK_DUMP_ARG_PREFIX "%d",
534 offset + FP_TO_ARGS_DIST + nArgs + 1);
536 - else if (0 <= offset && offset < nSyms) {
537 - sprintf(pos = buffer, offset ? "[%d]" : "FP[%d]", offset);
538 - posFmt = "%6s";
540 break;
542 printd(posFmt, pos);
544 - /* local symbol names? */
545 - if (0 <= offset && offset < nSyms) {
546 - for (sym = syms; sym != NULL; sym = sym->next) {
547 - if (sym->value.val.n == offset) {
548 - symName = sym->name;
549 - break;
553 - printd(" %-*.*s", symLen, symLen, symName);
555 if (dv == fnNm && dv->tag == STRING_TAG && dv->val.str.rep) {
556 printd(" %s", dv->val.str.rep);
558 @@ -4918,6 +4796,15 @@ static void stackdumpframe(DataValue *ar
559 prog->name, prog->refcount,
560 prog);
562 + else
563 + if (dv == lsFP) {
564 + Symbol *s = dv->val.sym;
565 + while (s) {
566 + printd("\n%*s", 22, s->name);
567 + dumpVal(s->value);
568 + s = s->next;
571 else {
572 dumpVal(*dv);
574 diff --quilt old/source/interpret.h new/source/interpret.h
575 --- old/source/interpret.h
576 +++ new/source/interpret.h
577 @@ -70,7 +70,6 @@ typedef struct InstTag {
578 int immed;
579 const char *str;
580 ptrdiff_t branch;
581 - struct SymbolRec *sym;
582 } val;
583 } Inst;
585 @@ -114,7 +113,6 @@ typedef struct SymbolRec {
587 typedef struct ProgramTag {
588 const char *name;
589 - Symbol *localSymList;
590 Inst *code;
591 unsigned refcount;
592 } Program;
593 @@ -132,7 +130,6 @@ typedef struct {
595 /* state of the accumulator (aka compiler) */
596 typedef struct AccumulatorDataTag {
597 - Symbol *localSymList;
598 Inst prog[PROGRAM_SIZE];
599 Inst *progP;
600 Inst *loopStack[LOOP_STACK_SIZE];
601 @@ -157,13 +154,13 @@ int ArrayCopy(DataValue *dstArray, DataV
602 AccumulatorData *BeginCreatingProgram(const char *name);
603 Program *FinishCreatingProgram(AccumulatorData *old);
604 int AddOp(int op, char **msg);
605 -int AddSym(Symbol *sym, char **msg);
606 +int AddSym(const char *str, char **msg);
607 int AddImmediate(int immed, char **msg);
608 int AddString(const char *str, char **msg);
609 int AddBranchOffset(Inst *to, char **msg);
610 int SetBranchOffset(Inst *from, Inst *to, char **msg);
611 Inst *GetPC(void);
612 -Symbol *LookupSymbol(const char *name);
613 +Symbol *LookupSymbol(const char *name, int create);
614 Symbol *InstallSymbol(const char *name, enum symTypes type, DataValue value);
615 const char *LookupString(const char *str, int create);
616 Inst *SwapCode(Inst *start, Inst *boundary, Inst *end);
617 @@ -194,7 +191,6 @@ int AllocNStringNCpy(NString *string, co
618 int AllocNStringCpy(NString *string, const char *s);
619 void GarbageCollectStrings(void);
620 void FreeRestartData(RestartData *context);
621 -Symbol *PromoteToGlobal(Symbol *sym);
622 void FreeProgram(Program *prog);
623 void ModifyReturnedValue(RestartData *context, DataValue dv);
624 WindowInfo *MacroRunWindow(void);
625 diff --quilt old/source/parse.y new/source/parse.y
626 --- old/source/parse.y
627 +++ new/source/parse.y
628 @@ -117,25 +117,20 @@ static int nextSymIsField = 0;
631 %union {
632 - Symbol *sym;
633 Inst *inst;
634 int num;
635 const char *str;
636 enum operations oper;
637 - struct {
638 - AccumulatorData *acc;
639 - Symbol *sym;
640 - } define;
641 + AccumulatorData *acc;
643 -%token <sym> SYMBOL
644 -%token <str> STRING FIELD
645 +%token <str> SYMBOL STRING FIELD
646 %token <num> NUMBER
647 %token DELETE ARG_LOOKUP
648 %token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN DEFINE TYPEOF KEYVAL
649 %type <num> arglistopt arglist catlist fnarglsopt fnarglist fnarg
650 %type <inst> cond comastmts comastmtlst for while do else and or arrayexpr mark
651 -%type <sym> evalsym
652 -%type <define> definesym
653 +%type <str> evalsym
654 +%type <acc> definesym
655 %type <oper> operassign incrdecr
656 %token <oper> '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
657 %token <oper> INCR DECR
658 @@ -205,31 +200,29 @@ definekw: DEFINE {
661 definesym: SYMBOL {
662 - /* we can't really be sure, that we not overwrite any
663 - ** wrong symbol
664 - **
665 - ** we should only overwrite installed MACRO_FUNCTION_SYM
666 - ** and this is questionable.
667 - */
668 - if ($1->type == MACRO_FUNCTION_SYM) {
669 - FreeProgram($1->value.val.prog);
671 - else if ($1->type == LOCAL_SYM ||
672 - $1->type == GLOBAL_SYM) {
673 - /* newly created sym, or we overwrite a local sym */;
674 - } else {
675 - yyerror("try to override built-in subroutine"); YYERROR;
677 - $$.sym = PromoteToGlobal($1);
678 - $$.acc = BeginCreatingProgram($$.sym->name);
679 + $$ = BeginCreatingProgram($1);
682 define: definekw blank definesym blank blockwb {
683 + Symbol *sym;
684 + Program *prog;
685 ADD_OP(OP_RETURN_NO_VAL);
686 - Program *prog = FinishCreatingProgram($3.acc);
687 - $3.sym->type = MACRO_FUNCTION_SYM;
688 - $3.sym->value.tag = NO_TAG;
689 - $3.sym->value.val.prog = prog;
690 + prog = FinishCreatingProgram($3);
691 + sym = LookupSymbol(prog->name, False);
692 + if (sym) {
693 + if (sym->type != MACRO_FUNCTION_SYM) {
694 + FreeProgram(prog);
695 + yyerror("try to override built-in subroutine"); YYERROR;
697 + FreeProgram(sym->value.val.prog);
699 + else {
700 + DataValue subrPtr;
701 + subrPtr.tag = NO_TAG;
702 + sym = InstallSymbol(prog->name, MACRO_FUNCTION_SYM,
703 + subrPtr);
705 + sym->value.val.prog = prog;
709 @@ -540,18 +533,18 @@ funccall: TYPEOF '(' {
711 | SYMBOL '(' fnarglsopt ')' {
712 ADD_OP(OP_SUBR_CALL);
713 - ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
714 + ADD_SYM($1); ADD_IMMED($3);
716 | SYMBOL '(' blank '=' blank expr blank ')' {
717 /* a single array replaces the argument list */
718 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
719 - ADD_SYM(PromoteToGlobal($1));
720 + ADD_SYM($1);
721 ADD_IMMED(0); /* zero arguments */
723 | SYMBOL '(' fnarglist ARGSEP blank '=' blank expr blank ')' {
724 /* a single array replaces the argument list */
725 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
726 - ADD_SYM(PromoteToGlobal($1));
727 + ADD_SYM($1);
728 ADD_IMMED($3);
731 @@ -618,7 +611,7 @@ expr: catlist {
734 initarraylv: SYMBOL {
735 - ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(1);
736 + ADD_OP(OP_PUSH_ARRAY_SYM); ADD_IMMED(1); ADD_SYM($1);
738 | initarraylv '[' arglistopt ']' {
739 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
740 @@ -629,7 +622,7 @@ initarraylv: SYMBOL {
743 arraylv: SYMBOL {
744 - ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(0);
745 + ADD_OP(OP_PUSH_ARRAY_SYM); ADD_IMMED(0); ADD_SYM($1);
747 | arraylv '[' arglistopt ']' {
748 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
749 @@ -939,19 +932,17 @@ static int yylex(void)
750 if (!strcmp(symName, "delete") && follow_non_whitespace('(', SYMBOL, DELETE) == DELETE) return DELETE;
751 if (!strcmp(symName, "define") && follow_non_whitespace('(', SYMBOL, DEFINE) == DEFINE) return DEFINE;
752 if (!strcmp(symName, "typeof")) return TYPEOF;
754 + yylval.str = LookupString(symName, True);
755 if (nextSymIsField) {
756 nextSymIsField = 0;
757 - yylval.str = LookupString(symName, True);
758 return FIELD;
760 - if ((s=LookupSymbol(symName)) == NULL) {
761 - s = InstallSymbol(symName, symName[0]=='$' ?
762 - (((symName[1] > '0' && symName[1] <= '9') && symName[2] == 0) ?
763 - ARG_SYM : GLOBAL_SYM) : LOCAL_SYM, value);
764 - s->value.tag = NO_TAG;
765 + else {
766 + return SYMBOL;
769 - yylval.sym = s;
770 + yylval.str = LookupString(s->name, True);
771 return SYMBOL;
773 nextSymIsField = 0;
774 @@ -1113,7 +1104,7 @@ static Symbol *matchesActionRoutine(char
775 if (!hasDash)
776 return NULL;
777 *symPtr = '\0';
778 - s = LookupSymbol(symbolName);
779 + s = LookupSymbol(symbolName, False);
780 if (s != NULL)
781 *inPtr = c;
782 return s;
783 diff --quilt old/source/macro.c new/source/macro.c
784 --- old/source/macro.c
785 +++ new/source/macro.c
786 @@ -3454,7 +3454,7 @@ static int callMS(WindowInfo *window, Da
787 if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
788 return False;
790 - sym = LookupSymbol(fnname);
791 + sym = LookupSymbol(fnname, False);
792 if (!sym) {
793 *errMsg = "subroutine name invalid";
794 return False;
795 @@ -3530,7 +3530,7 @@ static int defineMS(WindowInfo *window,
797 XtFree(bodysave);
799 - sym = LookupSymbol(name);
800 + sym = LookupSymbol(name, False);
801 if (sym) {
802 if (!override) {
803 FreeProgram(prog);
804 @@ -6941,7 +6941,7 @@ Boolean MacroApplyHook(WindowInfo *docum
805 Symbol *hookSymbol;
806 Boolean succ = False;
808 - hookSymbol = LookupSymbol(hook);
809 + hookSymbol = LookupSymbol(hook, False);
810 if (NULL != hookSymbol && MACRO_FUNCTION_SYM == hookSymbol->type) {
811 Program *hookProg = hookSymbol->value.val.prog;
812 RestartData *restartData;
813 diff --quilt old/source/ops.h new/source/ops.h
814 --- old/source/ops.h
815 +++ new/source/ops.h
816 @@ -48,7 +48,7 @@ OP(BEGIN_ARRAY_ITER_ARRAY, beginArrayIte
817 OP(ARRAY_ITER_ARRAY, arrayIterArray) /*w,ka[,v],pc*/ /* top(N),while it: (if dim(it.k)==N: (ka.v=split(it.k),(w?v.v=it.v:),return),it++), PC=pc */
818 OP(IN_ARRAY, inArray) /* pop(a,k), push(a[k]?1:0) */
819 OP(ARRAY_DELETE, deleteArrayElement) /*N*/ /* N>0 ? (pop(kN..k1,a), del(a[k])) : (pop(a), delall(a)) */
820 -OP(PUSH_ARRAY_SYM, pushArraySymVal) /*s,i*/ /* if i: s.v=ary()), push(s.v) */
821 +OP(PUSH_ARRAY_SYM, pushArraySymVal) /*i,s*/ /* if i: s.v=ary()), push(s.v) */
822 OP(ARRAY_REF_ASSIGN_SETUP, arrayRefAndAssignSetup) /*op,N*/ /* pop(v,kN..a), a[k1..kN] op= v */
823 OP(ARRAY_NEXT_NUM_IDX, arrayNextNumIdx) /* pop(a), push(a.nextidx) */
824 OP(PUSH_ARG, pushArgVal) /* pop(num), push($num) */