newMacroFnRegistration-redux.patch: built-ins.h
[nedit-bw.git] / symbol-lookup.patch
blob95652f24821c89a58beea1b499387d9ac7d49e6c
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 @@ -4808,15 +4717,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 @@ -4825,17 +4730,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 @@ -4846,7 +4740,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 @@ -4870,10 +4763,6 @@ 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 else if (offset == 0) {
541 pos = "FrameP";
543 @@ -4881,17 +4770,6 @@ static void stackdumpframe(DataValue *ar
545 printd(posFmt, pos);
547 - /* local symbol names? */
548 - if (0 <= offset && offset < nSyms) {
549 - for (sym = syms; sym != NULL; sym = sym->next) {
550 - if (sym->value.val.n == offset) {
551 - symName = sym->name;
552 - break;
556 - printd(" %-*.*s", symLen, symLen, symName);
558 if (dv == fnNm && dv->tag == STRING_TAG && dv->val.str.rep) {
559 printd(" %s", dv->val.str.rep);
561 @@ -4921,6 +4799,15 @@ static void stackdumpframe(DataValue *ar
562 prog->refcount,
563 prog->name);
565 + else
566 + if (dv == lsFP) {
567 + Symbol *s = dv->val.sym;
568 + while (s) {
569 + printd("\n%*s", 22, s->name);
570 + dumpVal(s->value);
571 + s = s->next;
574 else {
575 dumpVal(*dv);
577 diff --quilt old/source/interpret.h new/source/interpret.h
578 --- old/source/interpret.h
579 +++ new/source/interpret.h
580 @@ -70,7 +70,6 @@ typedef struct InstTag {
581 int immed;
582 const char *str;
583 ptrdiff_t branch;
584 - struct SymbolRec *sym;
585 } val;
586 } Inst;
588 @@ -114,7 +113,6 @@ typedef struct SymbolRec {
590 typedef struct ProgramTag {
591 const char *name;
592 - Symbol *localSymList;
593 Inst *code;
594 unsigned refcount;
595 } Program;
596 @@ -132,7 +130,6 @@ typedef struct {
598 /* state of the accumulator (aka compiler) */
599 typedef struct AccumulatorDataTag {
600 - Symbol *localSymList;
601 Inst prog[PROGRAM_SIZE];
602 Inst *progP;
603 Inst *loopStack[LOOP_STACK_SIZE];
604 @@ -157,13 +154,13 @@ int ArrayCopy(DataValue *dstArray, DataV
605 AccumulatorData *BeginCreatingProgram(const char *name);
606 Program *FinishCreatingProgram(AccumulatorData *old);
607 int AddOp(int op, char **msg);
608 -int AddSym(Symbol *sym, char **msg);
609 +int AddSym(const char *str, char **msg);
610 int AddImmediate(int immed, char **msg);
611 int AddString(const char *str, char **msg);
612 int AddBranchOffset(Inst *to, char **msg);
613 int SetBranchOffset(Inst *from, Inst *to, char **msg);
614 Inst *GetPC(void);
615 -Symbol *LookupSymbol(const char *name);
616 +Symbol *LookupSymbol(const char *name, int create);
617 Symbol *InstallSymbol(const char *name, enum symTypes type, DataValue value);
618 const char *LookupString(const char *str, int create);
619 Inst *SwapCode(Inst *start, Inst *boundary, Inst *end);
620 @@ -194,7 +191,6 @@ int AllocNStringNCpy(NString *string, co
621 int AllocNStringCpy(NString *string, const char *s);
622 void GarbageCollectStrings(void);
623 void FreeRestartData(RestartData *context);
624 -Symbol *PromoteToGlobal(Symbol *sym);
625 void FreeProgram(Program *prog);
626 void ModifyReturnedValue(RestartData *context, DataValue dv);
627 WindowInfo *MacroRunWindow(void);
628 diff --quilt old/source/parse.y new/source/parse.y
629 --- old/source/parse.y
630 +++ new/source/parse.y
631 @@ -117,25 +117,20 @@ static int nextSymIsField = 0;
634 %union {
635 - Symbol *sym;
636 Inst *inst;
637 int num;
638 const char *str;
639 enum operations oper;
640 - struct {
641 - AccumulatorData *acc;
642 - Symbol *sym;
643 - } define;
644 + AccumulatorData *acc;
646 -%token <sym> SYMBOL
647 -%token <str> STRING FIELD
648 +%token <str> SYMBOL STRING FIELD
649 %token <num> NUMBER
650 %token DELETE ARG_LOOKUP
651 %token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN DEFINE TYPEOF KEYVAL
652 %type <num> arglistopt arglist catlist fnarglsopt fnarglist fnarg
653 %type <inst> cond comastmts comastmtlst for while do else and or arrayexpr mark
654 -%type <sym> evalsym
655 -%type <define> definesym
656 +%type <str> evalsym
657 +%type <acc> definesym
658 %type <oper> operassign incrdecr
659 %token <oper> '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
660 %token <oper> INCR DECR
661 @@ -205,31 +200,29 @@ definekw: DEFINE {
664 definesym: SYMBOL {
665 - /* we can't really be sure, that we not overwrite any
666 - ** wrong symbol
667 - **
668 - ** we should only overwrite installed MACRO_FUNCTION_SYM
669 - ** and this is questionable.
670 - */
671 - if ($1->type == MACRO_FUNCTION_SYM) {
672 - FreeProgram($1->value.val.prog);
674 - else if ($1->type == LOCAL_SYM ||
675 - $1->type == GLOBAL_SYM) {
676 - /* newly created sym, or we overwrite a local sym */;
677 - } else {
678 - yyerror("try to override built-in subroutine"); YYERROR;
680 - $$.sym = PromoteToGlobal($1);
681 - $$.acc = BeginCreatingProgram($$.sym->name);
682 + $$ = BeginCreatingProgram($1);
685 define: definekw blank definesym blank blockwb {
686 + Symbol *sym;
687 + Program *prog;
688 ADD_OP(OP_RETURN_NO_VAL);
689 - Program *prog = FinishCreatingProgram($3.acc);
690 - $3.sym->type = MACRO_FUNCTION_SYM;
691 - $3.sym->value.tag = NO_TAG;
692 - $3.sym->value.val.prog = prog;
693 + prog = FinishCreatingProgram($3);
694 + sym = LookupSymbol(prog->name, False);
695 + if (sym) {
696 + if (sym->type != MACRO_FUNCTION_SYM) {
697 + FreeProgram(prog);
698 + yyerror("try to override built-in subroutine"); YYERROR;
700 + FreeProgram(sym->value.val.prog);
702 + else {
703 + DataValue subrPtr;
704 + subrPtr.tag = NO_TAG;
705 + sym = InstallSymbol(prog->name, MACRO_FUNCTION_SYM,
706 + subrPtr);
708 + sym->value.val.prog = prog;
712 @@ -540,18 +533,18 @@ funccall: TYPEOF '(' {
714 | SYMBOL '(' fnarglsopt ')' {
715 ADD_OP(OP_SUBR_CALL);
716 - ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
717 + ADD_SYM($1); ADD_IMMED($3);
719 | SYMBOL '(' blank '=' blank expr blank ')' {
720 /* a single array replaces the argument list */
721 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
722 - ADD_SYM(PromoteToGlobal($1));
723 + ADD_SYM($1);
724 ADD_IMMED(0); /* zero arguments */
726 | SYMBOL '(' fnarglist ARGSEP blank '=' blank expr blank ')' {
727 /* a single array replaces the argument list */
728 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
729 - ADD_SYM(PromoteToGlobal($1));
730 + ADD_SYM($1);
731 ADD_IMMED($3);
734 @@ -618,7 +611,7 @@ expr: catlist {
737 initarraylv: SYMBOL {
738 - ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(1);
739 + ADD_OP(OP_PUSH_ARRAY_SYM); ADD_IMMED(1); ADD_SYM($1);
741 | initarraylv '[' arglistopt ']' {
742 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
743 @@ -629,7 +622,7 @@ initarraylv: SYMBOL {
746 arraylv: SYMBOL {
747 - ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(0);
748 + ADD_OP(OP_PUSH_ARRAY_SYM); ADD_IMMED(0); ADD_SYM($1);
750 | arraylv '[' arglistopt ']' {
751 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
752 @@ -939,19 +932,17 @@ static int yylex(void)
753 if (!strcmp(symName, "delete") && follow_non_whitespace('(', SYMBOL, DELETE) == DELETE) return DELETE;
754 if (!strcmp(symName, "define") && follow_non_whitespace('(', SYMBOL, DEFINE) == DEFINE) return DEFINE;
755 if (!strcmp(symName, "typeof")) return TYPEOF;
757 + yylval.str = LookupString(symName, True);
758 if (nextSymIsField) {
759 nextSymIsField = 0;
760 - yylval.str = LookupString(symName, True);
761 return FIELD;
763 - if ((s=LookupSymbol(symName)) == NULL) {
764 - s = InstallSymbol(symName, symName[0]=='$' ?
765 - (((symName[1] > '0' && symName[1] <= '9') && symName[2] == 0) ?
766 - ARG_SYM : GLOBAL_SYM) : LOCAL_SYM, value);
767 - s->value.tag = NO_TAG;
768 + else {
769 + return SYMBOL;
772 - yylval.sym = s;
773 + yylval.str = LookupString(s->name, True);
774 return SYMBOL;
776 nextSymIsField = 0;
777 @@ -1113,7 +1104,7 @@ static Symbol *matchesActionRoutine(char
778 if (!hasDash)
779 return NULL;
780 *symPtr = '\0';
781 - s = LookupSymbol(symbolName);
782 + s = LookupSymbol(symbolName, False);
783 if (s != NULL)
784 *inPtr = c;
785 return s;
786 diff --quilt old/source/macro.c new/source/macro.c
787 --- old/source/macro.c
788 +++ new/source/macro.c
789 @@ -3454,7 +3454,7 @@ static int callMS(WindowInfo *window, Da
790 if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
791 return False;
793 - sym = LookupSymbol(fnname);
794 + sym = LookupSymbol(fnname, False);
795 if (!sym) {
796 *errMsg = "subroutine name invalid";
797 return False;
798 @@ -3530,7 +3530,7 @@ static int defineMS(WindowInfo *window,
800 XtFree(bodysave);
802 - sym = LookupSymbol(name);
803 + sym = LookupSymbol(name, False);
804 if (sym) {
805 if (!override) {
806 FreeProgram(prog);
807 @@ -6941,7 +6941,7 @@ Boolean MacroApplyHook(WindowInfo *docum
808 Symbol *hookSymbol;
809 Boolean succ = False;
811 - hookSymbol = LookupSymbol(hook);
812 + hookSymbol = LookupSymbol(hook, False);
813 if (NULL != hookSymbol && MACRO_FUNCTION_SYM == hookSymbol->type) {
814 Program *hookProg = hookSymbol->value.val.prog;
815 RestartData *restartData;
816 diff --quilt old/source/ops.h new/source/ops.h
817 --- old/source/ops.h
818 +++ new/source/ops.h
819 @@ -48,7 +48,7 @@ OP(BEGIN_ARRAY_ITER_ARRAY, beginArrayIte
820 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 */
821 OP(IN_ARRAY, inArray) /* pop(a,k), push(a[k]?1:0) */
822 OP(ARRAY_DELETE, deleteArrayElement) /*N*/ /* N>0 ? (pop(kN..k1,a), del(a[k])) : (pop(a), delall(a)) */
823 -OP(PUSH_ARRAY_SYM, pushArraySymVal) /*s,i*/ /* if i: s.v=ary()), push(s.v) */
824 +OP(PUSH_ARRAY_SYM, pushArraySymVal) /*i,s*/ /* if i: s.v=ary()), push(s.v) */
825 OP(ARRAY_REF_ASSIGN_SETUP, arrayRefAndAssignSetup) /*op,N*/ /* pop(v,kN..a), a[k1..kN] op= v */
826 OP(ARRAY_NEXT_NUM_IDX, arrayNextNumIdx) /* pop(a), push(a.nextidx) */
827 OP(PUSH_ARG, pushArgVal) /* pop(num), push($num) */