break/continue to outer loops, !!booleanize
[nedit-bw.git] / symbol-lookup.patch
blobfc95c244ee8e55bb32e1255e49f7ed68651ae4ea
1 ---
3 source/interpret.c | 257 +++++++++++++----------------------------------------
4 source/interpret.h | 8 -
5 source/macro.c | 6 -
6 source/ops.h | 2
7 source/parse.y | 77 +++++++--------
8 5 files changed, 107 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,11 +4718,6 @@ static void stackdumpframe(DataValue *ar
490 DataValue *endDv = (arg1 > outpt) ? arg1 : outpt;
491 int nArgs = FP_GET_ARG_COUNT(fp);
493 - int nSyms;
494 - static int symLen = 0;
495 - Symbol *syms = FP_GET_ITEM(fp, FP_SYMBOL_TABLE).val.sym;
496 - Symbol *sym;
498 #ifdef DEBUG_STACK_HEADFIRST
499 #else
500 /* do caller's frame */
501 @@ -4822,17 +4726,6 @@ static void stackdumpframe(DataValue *ar
502 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
504 /* do current frame */
505 - /* how many symbols are there? */
506 - for (sym = syms, nSyms = 0; sym != NULL; sym = sym->next) {
507 - nSyms++;
508 - if (symLen < 27) {
509 - int len = strlen(sym->name);
510 - if (len > 27)
511 - len = 27;
512 - if (len > symLen)
513 - symLen = len;
517 /* output instructions between endDv and sp - 1 inclusive */
518 #ifdef DEBUG_STACK_HEADFIRST
519 @@ -4843,7 +4736,6 @@ static void stackdumpframe(DataValue *ar
520 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
522 const char *posFmt = "%-6s";
523 - const char *symName = "";
525 char *pos = "";
526 char buffer[sizeof(STACK_DUMP_ARG_PREFIX) + TYPE_INT_STR_SIZE(int)];
527 @@ -4867,10 +4759,6 @@ static void stackdumpframe(DataValue *ar
528 sprintf(pos = buffer, STACK_DUMP_ARG_PREFIX "%d",
529 offset + FP_TO_ARGS_DIST + nArgs + 1);
531 - else if (0 <= offset && offset < nSyms) {
532 - sprintf(pos = buffer, offset ? "[%d]" : "FP[%d]", offset);
533 - posFmt = "%6s";
535 else if (offset == 0) {
536 pos = "FrameP";
538 @@ -4878,17 +4766,6 @@ static void stackdumpframe(DataValue *ar
540 printd(posFmt, pos);
542 - /* local symbol names? */
543 - if (0 <= offset && offset < nSyms) {
544 - for (sym = syms; sym != NULL; sym = sym->next) {
545 - if (sym->value.val.n == offset) {
546 - symName = sym->name;
547 - break;
551 - printd(" %-*.*s", symLen, symLen, symName);
553 if (dv == fnNm && dv->tag == STRING_TAG && dv->val.str.rep)
554 printd(" %s", dv->val.str.rep);
555 else
556 diff --quilt old/source/interpret.h new/source/interpret.h
557 --- old/source/interpret.h
558 +++ new/source/interpret.h
559 @@ -70,7 +70,6 @@ typedef struct InstTag {
560 int immed;
561 const char *str;
562 ptrdiff_t branch;
563 - struct SymbolRec *sym;
564 } val;
565 } Inst;
567 @@ -114,7 +113,6 @@ typedef struct SymbolRec {
569 typedef struct ProgramTag {
570 const char *name;
571 - Symbol *localSymList;
572 Inst *code;
573 unsigned refcount;
574 } Program;
575 @@ -132,7 +130,6 @@ typedef struct {
577 /* state of the accumulator (aka compiler) */
578 typedef struct AccumulatorDataTag {
579 - Symbol *localSymList;
580 Inst prog[PROGRAM_SIZE];
581 Inst *progP;
582 Inst *loopStack[LOOP_STACK_SIZE];
583 @@ -157,13 +154,13 @@ int ArrayCopy(DataValue *dstArray, DataV
584 AccumulatorData *BeginCreatingProgram(const char *name);
585 Program *FinishCreatingProgram(AccumulatorData *old);
586 int AddOp(int op, char **msg);
587 -int AddSym(Symbol *sym, char **msg);
588 +int AddSym(const char *str, char **msg);
589 int AddImmediate(int immed, char **msg);
590 int AddString(const char *str, char **msg);
591 int AddBranchOffset(Inst *to, char **msg);
592 int SetBranchOffset(Inst *from, Inst *to, char **msg);
593 Inst *GetPC(void);
594 -Symbol *LookupSymbol(const char *name);
595 +Symbol *LookupSymbol(const char *name, int create);
596 Symbol *InstallSymbol(const char *name, enum symTypes type, DataValue value);
597 const char *LookupString(const char *str, int create);
598 Inst *SwapCode(Inst *start, Inst *boundary, Inst *end);
599 @@ -194,7 +191,6 @@ int AllocNStringNCpy(NString *string, co
600 int AllocNStringCpy(NString *string, const char *s);
601 void GarbageCollectStrings(void);
602 void FreeRestartData(RestartData *context);
603 -Symbol *PromoteToGlobal(Symbol *sym);
604 void FreeProgram(Program *prog);
605 void ModifyReturnedValue(RestartData *context, DataValue dv);
606 WindowInfo *MacroRunWindow(void);
607 diff --quilt old/source/parse.y new/source/parse.y
608 --- old/source/parse.y
609 +++ new/source/parse.y
610 @@ -117,25 +117,20 @@ static int nextSymIsField = 0;
613 %union {
614 - Symbol *sym;
615 Inst *inst;
616 int num;
617 const char *str;
618 enum operations oper;
619 - struct {
620 - AccumulatorData *acc;
621 - Symbol *sym;
622 - } define;
623 + AccumulatorData *acc;
625 -%token <sym> SYMBOL
626 -%token <str> STRING FIELD
627 +%token <str> SYMBOL STRING FIELD
628 %token <num> NUMBER
629 %token DELETE ARG_LOOKUP
630 %token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN DEFINE TYPEOF KEYVAL
631 %type <num> arglistopt arglist catlist fnarglsopt fnarglist fnarg
632 %type <inst> cond comastmts comastmtlst for while do else and or arrayexpr mark
633 -%type <sym> evalsym
634 -%type <define> definesym
635 +%type <str> evalsym
636 +%type <acc> definesym
637 %type <oper> operassign incrdecr
638 %token <oper> '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
639 %token <oper> INCR DECR
640 @@ -205,31 +200,29 @@ definekw: DEFINE {
643 definesym: SYMBOL {
644 - /* we can't really be sure, that we not overwrite any
645 - ** wrong symbol
646 - **
647 - ** we should only overwrite installed MACRO_FUNCTION_SYM
648 - ** and this is questionable.
649 - */
650 - if ($1->type == MACRO_FUNCTION_SYM) {
651 - FreeProgram($1->value.val.prog);
653 - else if ($1->type == LOCAL_SYM ||
654 - $1->type == GLOBAL_SYM) {
655 - /* newly created sym, or we overwrite a local sym */;
656 - } else {
657 - yyerror("try to override built-in subroutine"); YYERROR;
659 - $$.sym = PromoteToGlobal($1);
660 - $$.acc = BeginCreatingProgram($$.sym->name);
661 + $$ = BeginCreatingProgram($1);
664 define: definekw blank definesym blank blockwb {
665 + Symbol *sym;
666 + Program *prog;
667 ADD_OP(OP_RETURN_NO_VAL);
668 - Program *prog = FinishCreatingProgram($3.acc);
669 - $3.sym->type = MACRO_FUNCTION_SYM;
670 - $3.sym->value.tag = NO_TAG;
671 - $3.sym->value.val.prog = prog;
672 + prog = FinishCreatingProgram($3);
673 + sym = LookupSymbol(prog->name, False);
674 + if (sym) {
675 + if (sym->type != MACRO_FUNCTION_SYM) {
676 + FreeProgram(prog);
677 + yyerror("try to override built-in subroutine"); YYERROR;
679 + FreeProgram(sym->value.val.prog);
681 + else {
682 + DataValue subrPtr;
683 + subrPtr.tag = NO_TAG;
684 + sym = InstallSymbol(prog->name, MACRO_FUNCTION_SYM,
685 + subrPtr);
687 + sym->value.val.prog = prog;
691 @@ -540,18 +533,18 @@ funccall: TYPEOF '(' {
693 | SYMBOL '(' fnarglsopt ')' {
694 ADD_OP(OP_SUBR_CALL);
695 - ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
696 + ADD_SYM($1); ADD_IMMED($3);
698 | SYMBOL '(' blank '=' blank expr blank ')' {
699 /* a single array replaces the argument list */
700 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
701 - ADD_SYM(PromoteToGlobal($1));
702 + ADD_SYM($1);
703 ADD_IMMED(0); /* zero arguments */
705 | SYMBOL '(' fnarglist ARGSEP blank '=' blank expr blank ')' {
706 /* a single array replaces the argument list */
707 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
708 - ADD_SYM(PromoteToGlobal($1));
709 + ADD_SYM($1);
710 ADD_IMMED($3);
713 @@ -618,7 +611,7 @@ expr: catlist {
716 initarraylv: SYMBOL {
717 - ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(1);
718 + ADD_OP(OP_PUSH_ARRAY_SYM); ADD_IMMED(1); ADD_SYM($1);
720 | initarraylv '[' arglistopt ']' {
721 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
722 @@ -629,7 +622,7 @@ initarraylv: SYMBOL {
725 arraylv: SYMBOL {
726 - ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(0);
727 + ADD_OP(OP_PUSH_ARRAY_SYM); ADD_IMMED(0); ADD_SYM($1);
729 | arraylv '[' arglistopt ']' {
730 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
731 @@ -939,19 +932,17 @@ static int yylex(void)
732 if (!strcmp(symName, "delete") && follow_non_whitespace('(', SYMBOL, DELETE) == DELETE) return DELETE;
733 if (!strcmp(symName, "define") && follow_non_whitespace('(', SYMBOL, DEFINE) == DEFINE) return DEFINE;
734 if (!strcmp(symName, "typeof")) return TYPEOF;
736 + yylval.str = LookupString(symName, True);
737 if (nextSymIsField) {
738 nextSymIsField = 0;
739 - yylval.str = LookupString(symName, True);
740 return FIELD;
742 - if ((s=LookupSymbol(symName)) == NULL) {
743 - s = InstallSymbol(symName, symName[0]=='$' ?
744 - (((symName[1] > '0' && symName[1] <= '9') && symName[2] == 0) ?
745 - ARG_SYM : GLOBAL_SYM) : LOCAL_SYM, value);
746 - s->value.tag = NO_TAG;
747 + else {
748 + return SYMBOL;
751 - yylval.sym = s;
752 + yylval.str = LookupString(s->name, True);
753 return SYMBOL;
755 nextSymIsField = 0;
756 @@ -1113,7 +1104,7 @@ static Symbol *matchesActionRoutine(char
757 if (!hasDash)
758 return NULL;
759 *symPtr = '\0';
760 - s = LookupSymbol(symbolName);
761 + s = LookupSymbol(symbolName, False);
762 if (s != NULL)
763 *inPtr = c;
764 return s;
765 diff --quilt old/source/macro.c new/source/macro.c
766 --- old/source/macro.c
767 +++ new/source/macro.c
768 @@ -3826,7 +3826,7 @@ static int callMS(WindowInfo *window, Da
769 if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
770 return False;
772 - sym = LookupSymbol(fnname);
773 + sym = LookupSymbol(fnname, False);
774 if (!sym) {
775 *errMsg = "subroutine name invalid";
776 return False;
777 @@ -3902,7 +3902,7 @@ static int defineMS(WindowInfo *window,
779 XtFree(bodysave);
781 - sym = LookupSymbol(name);
782 + sym = LookupSymbol(name, False);
783 if (sym) {
784 if (!override) {
785 FreeProgram(prog);
786 @@ -7313,7 +7313,7 @@ Boolean MacroApplyHook(WindowInfo *docum
787 Symbol *hookSymbol;
788 Boolean succ = False;
790 - hookSymbol = LookupSymbol(hook);
791 + hookSymbol = LookupSymbol(hook, False);
792 if (NULL != hookSymbol && MACRO_FUNCTION_SYM == hookSymbol->type) {
793 Program *hookProg = hookSymbol->value.val.prog;
794 RestartData *restartData;
795 diff --quilt old/source/ops.h new/source/ops.h
796 --- old/source/ops.h
797 +++ new/source/ops.h
798 @@ -48,7 +48,7 @@ OP(BEGIN_ARRAY_ITER_ARRAY, beginArrayIte
799 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 */
800 OP(IN_ARRAY, inArray) /* pop(a,k), push(a[k]?1:0) */
801 OP(ARRAY_DELETE, deleteArrayElement) /*N*/ /* N>0 ? (pop(kN..k1,a), del(a[k])) : (pop(a), delall(a)) */
802 -OP(PUSH_ARRAY_SYM, pushArraySymVal) /*s,i*/ /* if i: s.v=ary()), push(s.v) */
803 +OP(PUSH_ARRAY_SYM, pushArraySymVal) /*i,s*/ /* if i: s.v=ary()), push(s.v) */
804 OP(ARRAY_REF_ASSIGN_SETUP, arrayRefAndAssignSetup) /*op,N*/ /* pop(v,kN..a), a[k1..kN] op= v */
805 OP(ARRAY_NEXT_NUM_IDX, arrayNextNumIdx) /* pop(a), push(a.nextidx) */
806 OP(PUSH_ARG, pushArgVal) /* pop(num), push($num) */