3 source/interpret.c | 251 +++++++++++++----------------------------------------
4 source/interpret.h | 8 -
6 source/parse.y | 55 ++++-------
7 4 files changed, 91 insertions(+), 229 deletions(-)
9 diff --quilt old/source/interpret.c new/source/interpret.c
10 --- old/source/interpret.c
11 +++ new/source/interpret.c
12 @@ -170,7 +170,6 @@ static AccumulatorData *Accumulator;
13 #define ProgP (Accumulator->progP)
14 #define LoopStack (Accumulator->loopStack)
15 #define LoopStackPtr (Accumulator->loopStackPtr)
16 -#define LocalSymList (Accumulator->localSymList)
17 #define ProgramName (Accumulator->name)
19 /* Global data for the interpreter */
20 @@ -212,8 +211,8 @@ static int (*OpFns[])() = {
21 #define FP_GET_PROG(xFrameP) ((FP_GET_ITEM(xFrameP, FP_PROG_INDEX)).val.prog)
22 #define FP_ARG_START_INDEX(xFrameP) (-(FP_GET_ARG_COUNT(xFrameP) + FP_TO_ARGS_DIST))
23 #define FP_GET_ARG_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN + FP_ARG_START_INDEX(xFrameP)))
24 -#define FP_GET_SYM_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN))
25 -#define FP_GET_SYM_VAL(xFrameP,xSym) (FP_GET_SYM_N(xFrameP, xSym->value.val.n))
26 +#define FP_GET_SYM_TAB(xFrameP) (FP_GET_ITEM(xFrameP, FP_SYMBOL_TABLE).val.sym)
27 +#define LocalSymList FP_GET_SYM_TAB(Interpreter->frameP)
30 ** Initialize macro language global variables. Must be called before
31 @@ -268,7 +267,6 @@ AccumulatorData *BeginCreatingProgram(co
32 AccumulatorData *old = Accumulator;
33 Accumulator = XtNew(AccumulatorData);
35 - LocalSymList = NULL;
37 LoopStackPtr = LoopStack;
39 @@ -284,22 +282,15 @@ AccumulatorData *BeginCreatingProgram(co
40 Program *FinishCreatingProgram(AccumulatorData *old)
43 - int progLen, fpOffset = 0;
47 newProg = XtNew(Program);
48 newProg->name = LookupString(ProgramName, True);
49 progLen = ProgP - Prog;
50 newProg->code = (Inst *)XtCalloc(progLen, sizeof(Inst));
51 memcpy(newProg->code, Prog, progLen * sizeof(Inst));
52 - newProg->localSymList = LocalSymList;
53 newProg->refcount = 1;
55 - /* Local variables' values are stored on the stack. Here we assign
56 - frame pointer offsets to them. */
57 - for (s = newProg->localSymList; s != NULL; s = s->next)
58 - s->value.val.n = fpOffset++;
60 DISASM(newProg->name, newProg->code, ProgP - Prog);
62 XtFree((char *)Accumulator);
63 @@ -311,7 +302,6 @@ Program *FinishCreatingProgram(Accumulat
64 void FreeProgram(Program *prog)
66 if (--prog->refcount == 0) {
67 - freeSymbolList(prog->localSymList);
68 XtFree((char *)prog->code);
71 @@ -335,14 +325,14 @@ int AddOp(int op, char **msg)
73 ** Add a symbol operand to the current program
75 -int AddSym(Symbol *sym, char **msg)
76 +int AddSym(const char *sym, char **msg)
78 if (ProgP >= &Prog[PROGRAM_SIZE]) {
79 *msg = "macro too large";
82 ProgP->type = SYM_INST;
83 - ProgP->val.sym = sym;
84 + ProgP->val.str = sym;
88 @@ -521,7 +511,6 @@ static int setupFrame(RestartData *conte
90 static DataValue noValue = {NO_TAG, {0}};
91 int i, totalPushs = 7;
95 ** we push only if we have room for the whole frame, so pre-calc the
96 @@ -530,9 +519,6 @@ static int setupFrame(RestartData *conte
100 - for (s = prog->localSymList; s != NULL; s = s->next) {
104 /* !OK_TO_PUSH(totalPushs) */
105 if (!((context->stackP + totalPushs) <= (context->stack + STACK_SIZE))) {
106 @@ -570,9 +556,9 @@ static int setupFrame(RestartData *conte
107 context->stackP->val.dataval = context->frameP;
111 + /* start a new local symbol list */
112 context->stackP->tag = NO_TAG;
113 - context->stackP->val.sym = prog->localSymList;
114 + context->stackP->val.sym = NULL;
118 @@ -588,12 +574,6 @@ static int setupFrame(RestartData *conte
120 context->frameP = context->stackP;
122 - /* Initialize and make room on the stack for local variables */
123 - for (s = prog->localSymList; s != NULL; s = s->next) {
124 - FP_GET_SYM_VAL(context->frameP, s) = noValue;
128 context->pc = prog->code;
131 @@ -606,6 +586,9 @@ static void rewindFrame(RestartData *con
132 DataValue *newFrameP = FP_GET_OLD_FP(context->frameP);
133 Inst *newPC = FP_GET_RET_PC(context->frameP);
134 Program *prog = FP_GET_PROG(context->frameP);
135 + Symbol *symList = FP_GET_SYM_TAB(context->frameP);
137 + freeSymbolList(symList);
139 /* pop past local variables */
140 context->stackP = context->frameP;
141 @@ -844,17 +827,20 @@ static Symbol *lookupSymbol(Symbol *syml
144 ** find a symbol in the symbol table
146 +** will create only LOCAL_SYM and GLOBAL_SYM (depending on first character)
147 +** with a NO_TAG value
149 -Symbol *LookupSymbol(const char *name)
150 +Symbol *LookupSymbol(const char *name, int create)
156 /* calculate hash for name */
157 hash = hashName(name);
159 /* search in local symbols */
162 s = lookupSymbol(LocalSymList, name, hash);
165 @@ -865,7 +851,13 @@ Symbol *LookupSymbol(const char *name)
171 + DataValue noValue = {NO_TAG, {0}};
172 + s = InstallSymbol(name, name[0] == '$' ? GLOBAL_SYM : LOCAL_SYM,
180 @@ -881,8 +873,17 @@ Symbol *InstallSymbol(const char *name,
182 s->hash = hashName(s->name);
183 if (type == LOCAL_SYM) {
184 - s->next = LocalSymList;
187 + s->next = LocalSymList;
192 + "NEdit: try to install local symbol without "
193 + "macro context: %s\n", name);
198 addToGlobalSymTab(s);
200 @@ -890,70 +891,6 @@ Symbol *InstallSymbol(const char *name,
204 -** Promote a symbol from local to global, removing it from the local symbol
207 -** This is used as a forward declaration feature for macro functions.
208 -** If a function is called (ie while parsing the macro) where the
209 -** function isn't defined yet, the symbol is put into the GlobalSymList
210 -** so that the function definition uses the same symbol.
213 -Symbol *PromoteToGlobal(Symbol *sym)
217 - if (sym->type != LOCAL_SYM)
220 - /* Remove sym from the local symbol list */
221 - if (sym == LocalSymList)
222 - LocalSymList = sym->next;
224 - for (s = LocalSymList; s != NULL; s = s->next) {
225 - if (s->next == sym) {
226 - s->next = sym->next;
232 - /* There are two scenarios which could make this check succeed:
233 - a) this sym is in the GlobalSymList as a LOCAL_SYM symbol
234 - b) there is another symbol as a non-LOCAL_SYM in the GlobalSymList
235 - Both are errors, without question.
236 - We currently just print this warning, but we should error out the
237 - parsing process. */
238 - s = LookupSymbol(sym->name);
241 - just make this symbol a GLOBAL_SYM symbol and return */
243 - "nedit: To boldly go where no local sym has gone before: %s\n",
245 - sym->type = GLOBAL_SYM;
247 - } else if (NULL != s) {
249 - sym will shadow the old symbol from the GlobalSymList */
251 - "nedit: duplicate symbol in LocalSymList and GlobalSymList: %s\n",
255 - /* Add the symbol directly to the GlobalSymList, because InstallSymbol()
256 - will allocate a new Symbol, which results in a memory leak of sym.
257 - Don't use MACRO_FUNCTION_SYM as type, because in
258 - macro.c:readCheckMacroString() we use ProgramFree() for the .val.prog,
259 - but this symbol has no program attached and ProgramFree() is not NULL
261 - sym->type = GLOBAL_SYM;
262 - addToGlobalSymTab(sym);
268 ** Convert a long value to its decimal string representation, returned in a
271 @@ -1123,7 +1060,7 @@ static SparseArrayEntry *allocateSparseA
273 SparseArrayEntryWrapper *mem;
275 - mem = (SparseArrayEntryWrapper *)XtMalloc(sizeof(SparseArrayEntryWrapper));
276 + mem = XtNew(SparseArrayEntryWrapper);
277 mem->next = AllocatedSparseArrayEntries;
278 AllocatedSparseArrayEntries = mem;
279 #ifdef TRACK_GARBAGE_LEAKS
280 @@ -1287,14 +1224,19 @@ static void addToGlobalSymTab(Symbol *sy
282 #define EXEC_ERROR(s1, s2) return execError(s1, s2)
284 -#define GET_SYM(s) \
285 +#define GET_SYM(s, create) \
288 if (PC->type != SYM_INST) { \
289 EXEC_ERROR("Unexpected instruction, expected <symbol>: <%s>", \
290 instTypeToStr(PC->type)); \
293 + _n = PC->val.str; \
294 + s = LookupSymbol(_n, create); \
297 + EXEC_ERROR("No such symbol: %s", _n); \
301 #define GET_IMMED(i) \
302 @@ -1505,11 +1447,9 @@ static int pushSymVal(void)
309 - if (s->type == LOCAL_SYM) {
310 - symVal = FP_GET_SYM_VAL(FrameP, s);
311 - } else if (s->type == GLOBAL_SYM) {
312 + if (s->type == LOCAL_SYM || s->type == GLOBAL_SYM) {
314 } else if (s->type == ARG_SYM) {
315 nArgs = FP_GET_ARG_COUNT(FrameP);
316 @@ -1659,18 +1599,13 @@ static int pushArraySymVal(void)
321 + GET_SYM(sym, True);
322 GET_IMMED(initEmpty);
324 - if (sym->type == LOCAL_SYM) {
325 - dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
327 - else if (sym->type == GLOBAL_SYM) {
328 - dataPtr = &sym->value;
331 + if (sym->type != LOCAL_SYM && sym->type != GLOBAL_SYM) {
332 EXEC_ERROR("assigning to non-lvalue array or non-array: %s", sym->name);
334 + dataPtr = &sym->value;
336 if (initEmpty && dataPtr->tag == NO_TAG) {
337 dataPtr->tag = ARRAY_TAG;
338 @@ -1972,7 +1907,7 @@ static int assign(void)
343 + GET_SYM(sym, True);
345 if (sym->type != GLOBAL_SYM && sym->type != LOCAL_SYM) {
346 if (sym->type == ARG_SYM) {
347 @@ -1985,13 +1920,7 @@ static int assign(void)
348 EXEC_ERROR("assignment to non-variable: %s", sym->name);
352 - if (sym->type == LOCAL_SYM) {
353 - dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
356 - dataPtr = &sym->value;
358 + dataPtr = &sym->value;
362 @@ -2775,7 +2704,7 @@ static int callSubroutine(void)
367 + GET_SYM(sym, False);
370 STACKDUMP(nArgs > 0 ? nArgs : -nArgs, 3);
371 @@ -2813,7 +2742,7 @@ static int callSubroutineUnpackArray(voi
376 + GET_SYM(sym, False);
380 @@ -3624,35 +3553,25 @@ static int arrayIter(void)
385 + GET_SYM(keySym, True);
388 + GET_SYM(valSym, True);
390 GET_BRANCH(branchAddr);
394 - if (keySym->type == LOCAL_SYM) {
395 - keyValPtr = &FP_GET_SYM_VAL(FrameP, keySym);
397 - else if (keySym->type == GLOBAL_SYM) {
398 - keyValPtr = &(keySym->value);
401 + if (keySym->type != LOCAL_SYM && keySym->type != GLOBAL_SYM) {
402 EXEC_ERROR("can't assign to: %s", keySym->name);
404 + keyValPtr = &keySym->value;
405 keyValPtr->tag = NO_TAG;
408 - if (valSym->type == LOCAL_SYM) {
409 - valPtr = &FP_GET_SYM_VAL(FrameP, valSym);
411 - else if (valSym->type == GLOBAL_SYM) {
412 - valPtr = &(valSym->value);
415 + if (valSym->type != LOCAL_SYM && valSym->type != GLOBAL_SYM) {
416 EXEC_ERROR("can't assign to: %s", valSym->name);
418 + valPtr = &valSym->value;
419 valPtr->tag = NO_TAG;
422 @@ -3791,37 +3710,27 @@ static int arrayIterArray(void)
426 - GET_SYM(keyArraySym);
427 + GET_SYM(keyArraySym, True);
430 + GET_SYM(valSym, True);
432 GET_BRANCH(branchAddr);
437 - if (keyArraySym->type == LOCAL_SYM) {
438 - keyArrayPtr = &FP_GET_SYM_VAL(FrameP, keyArraySym);
440 - else if (keyArraySym->type == GLOBAL_SYM) {
441 - keyArrayPtr = &(keyArraySym->value);
444 + if (keyArraySym->type != LOCAL_SYM && keyArraySym->type != GLOBAL_SYM) {
445 EXEC_ERROR("can't assign to: %s", keyArraySym->name);
447 + keyArrayPtr = &keyArraySym->value;
448 keyArrayPtr->tag = ARRAY_TAG;
449 keyArrayPtr->val.arrayPtr = NULL;
452 - if (valSym->type == LOCAL_SYM) {
453 - valPtr = &FP_GET_SYM_VAL(FrameP, valSym);
455 - else if (valSym->type == GLOBAL_SYM) {
456 - valPtr = &valSym->value;
459 + if (valSym->type != LOCAL_SYM && valSym->type != GLOBAL_SYM) {
460 EXEC_ERROR("can't assign to: %s", valSym->name);
462 + valPtr = &valSym->value;
463 valPtr->tag = NO_TAG;
466 @@ -4586,7 +4495,7 @@ static void dumpInst(Inst *inst, const c
470 - printd(" <%s %s>", name, inst->val.sym->name);
471 + printd(" <%s %s>", name, inst->val.str);
475 @@ -4809,11 +4718,6 @@ static void stackdumpframe(DataValue *ar
476 DataValue *endDv = (arg1 > outpt) ? arg1 : outpt;
477 int nArgs = FP_GET_ARG_COUNT(fp);
480 - static int symLen = 0;
481 - Symbol *syms = FP_GET_ITEM(fp, FP_SYMBOL_TABLE).val.sym;
484 #ifdef DEBUG_STACK_HEADFIRST
486 /* do caller's frame */
487 @@ -4822,17 +4726,6 @@ static void stackdumpframe(DataValue *ar
488 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
490 /* do current frame */
491 - /* how many symbols are there? */
492 - for (sym = syms, nSyms = 0; sym != NULL; sym = sym->next) {
495 - int len = strlen(sym->name);
503 /* output instructions between endDv and sp - 1 inclusive */
504 #ifdef DEBUG_STACK_HEADFIRST
505 @@ -4843,7 +4736,6 @@ static void stackdumpframe(DataValue *ar
506 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
508 const char *posFmt = "%-6s";
509 - const char *symName = "";
512 char buffer[sizeof(STACK_DUMP_ARG_PREFIX) + TYPE_INT_STR_SIZE(int)];
513 @@ -4867,10 +4759,6 @@ static void stackdumpframe(DataValue *ar
514 sprintf(pos = buffer, STACK_DUMP_ARG_PREFIX "%d",
515 offset + FP_TO_ARGS_DIST + nArgs + 1);
517 - else if (0 <= offset && offset < nSyms) {
518 - sprintf(pos = buffer, offset ? "[%d]" : "FP[%d]", offset);
521 else if (offset == 0) {
524 @@ -4878,17 +4766,6 @@ static void stackdumpframe(DataValue *ar
528 - /* local symbol names? */
529 - if (0 <= offset && offset < nSyms) {
530 - for (sym = syms; sym != NULL; sym = sym->next) {
531 - if (sym->value.val.n == offset) {
532 - symName = sym->name;
537 - printd(" %-*.*s", symLen, symLen, symName);
539 if (dv == fnNm && dv->tag == STRING_TAG && dv->val.str.rep)
540 printd(" %s", dv->val.str.rep);
542 diff --quilt old/source/interpret.h new/source/interpret.h
543 --- old/source/interpret.h
544 +++ new/source/interpret.h
545 @@ -70,7 +70,6 @@ typedef struct InstTag {
549 - struct SymbolRec *sym;
553 @@ -114,7 +113,6 @@ typedef struct SymbolRec {
555 typedef struct ProgramTag {
557 - Symbol *localSymList;
561 @@ -132,7 +130,6 @@ typedef struct {
563 /* state of the accumulator (aka compiler) */
564 typedef struct AccumulatorDataTag {
565 - Symbol *localSymList;
566 Inst prog[PROGRAM_SIZE];
568 Inst *loopStack[LOOP_STACK_SIZE];
569 @@ -157,13 +154,13 @@ int ArrayCopy(DataValue *dstArray, DataV
570 AccumulatorData *BeginCreatingProgram(const char *name);
571 Program *FinishCreatingProgram(AccumulatorData *old);
572 int AddOp(int op, char **msg);
573 -int AddSym(Symbol *sym, char **msg);
574 +int AddSym(const char *str, char **msg);
575 int AddImmediate(int immed, char **msg);
576 int AddString(const char *str, char **msg);
577 int AddBranchOffset(Inst *to, char **msg);
578 int SetBranchOffset(Inst *from, Inst *to, char **msg);
580 -Symbol *LookupSymbol(const char *name);
581 +Symbol *LookupSymbol(const char *name, int create);
582 Symbol *InstallSymbol(const char *name, enum symTypes type, DataValue value);
583 const char *LookupString(const char *str, int create);
584 Inst *SwapCode(Inst *start, Inst *boundary, Inst *end);
585 @@ -194,7 +191,6 @@ int AllocNStringNCpy(NString *string, co
586 int AllocNStringCpy(NString *string, const char *s);
587 void GarbageCollectStrings(void);
588 void FreeRestartData(RestartData *context);
589 -Symbol *PromoteToGlobal(Symbol *sym);
590 void FreeProgram(Program *prog);
591 void ModifyReturnedValue(RestartData *context, DataValue dv);
592 WindowInfo *MacroRunWindow(void);
593 diff --quilt old/source/parse.y new/source/parse.y
594 --- old/source/parse.y
595 +++ new/source/parse.y
596 @@ -111,7 +111,6 @@ static int nextSymIsField = 0;
604 @@ -121,14 +120,13 @@ static int nextSymIsField = 0;
609 -%token <str> STRING FIELD
610 +%token <str> SYMBOL STRING FIELD
612 %token DELETE ARG_LOOKUP
613 %token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN DEFINE TYPEOF KEYVAL
614 %type <num> arglistopt arglist catlist fnarglsopt fnarglist fnarg
615 %type <inst> cond comastmts comastmtlst for while do else and or arrayexpr mark
618 %type <define> definesym
619 %type <oper> operassign incrdecr
620 %token <oper> '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
621 @@ -199,31 +197,24 @@ definekw: DEFINE {
625 - /* we can't really be sure, that we not overwrite any
628 - ** we should only overwrite installed MACRO_FUNCTION_SYM
629 - ** and this is questionable.
631 - if ($1->type == MACRO_FUNCTION_SYM) {
632 - FreeProgram($1->value.val.prog);
633 + $$.sym = LookupSymbol($1, False);
635 + if ($$.sym->type != MACRO_FUNCTION_SYM) {
636 + yyerror("try to override built-in subroutine"); YYERROR;
639 - else if ($1->type == LOCAL_SYM ||
640 - $1->type == GLOBAL_SYM) {
641 - /* newly created sym, or we overwrite a local sym */;
643 - yyerror("try to override built-in subroutine"); YYERROR;
646 + subrPtr.tag = NO_TAG;
647 + subrPtr.val.prog = NULL;
648 + $$.sym = InstallSymbol($1, MACRO_FUNCTION_SYM, subrPtr);
650 - $$.sym = PromoteToGlobal($1);
651 $$.acc = BeginCreatingProgram($$.sym->name);
654 define: definekw blank definesym blank blockwb {
655 ADD_OP(OP_RETURN_NO_VAL);
656 - Program *prog = FinishCreatingProgram($3.acc);
657 - $3.sym->type = MACRO_FUNCTION_SYM;
658 - $3.sym->value.tag = NO_TAG;
659 - $3.sym->value.val.prog = prog;
660 + $3.sym->value.val.prog = FinishCreatingProgram($3.acc);
664 @@ -532,18 +523,18 @@ funccall: TYPEOF '(' {
666 | SYMBOL '(' fnarglsopt ')' {
667 ADD_OP(OP_SUBR_CALL);
668 - ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
669 + ADD_SYM($1); ADD_IMMED($3);
671 | SYMBOL '(' blank '=' blank expr blank ')' {
672 /* a single array replaces the argument list */
673 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
674 - ADD_SYM(PromoteToGlobal($1));
676 ADD_IMMED(0); /* zero arguments */
678 | SYMBOL '(' fnarglist ARGSEP blank '=' blank expr blank ')' {
679 /* a single array replaces the argument list */
680 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
681 - ADD_SYM(PromoteToGlobal($1));
686 @@ -931,19 +922,17 @@ static int yylex(void)
687 if (!strcmp(symName, "delete") && follow_non_whitespace('(', SYMBOL, DELETE) == DELETE) return DELETE;
688 if (!strcmp(symName, "define") && follow_non_whitespace('(', SYMBOL, DEFINE) == DEFINE) return DEFINE;
689 if (!strcmp(symName, "typeof")) return TYPEOF;
691 + yylval.str = LookupString(symName, True);
692 if (nextSymIsField) {
694 - yylval.str = LookupString(symName, True);
697 - if ((s=LookupSymbol(symName)) == NULL) {
698 - s = InstallSymbol(symName, symName[0]=='$' ?
699 - (((symName[1] > '0' && symName[1] <= '9') && symName[2] == 0) ?
700 - ARG_SYM : GLOBAL_SYM) : LOCAL_SYM, value);
701 - s->value.tag = NO_TAG;
707 + yylval.str = LookupString(s->name, True);
711 @@ -1105,7 +1094,7 @@ static Symbol *matchesActionRoutine(char
715 - s = LookupSymbol(symbolName);
716 + s = LookupSymbol(symbolName, False);
720 diff --quilt old/source/macro.c new/source/macro.c
721 --- old/source/macro.c
722 +++ new/source/macro.c
723 @@ -3826,7 +3826,7 @@ static int callMS(WindowInfo *window, Da
724 if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
727 - sym = LookupSymbol(fnname);
728 + sym = LookupSymbol(fnname, False);
730 *errMsg = "subroutine name invalid";
732 @@ -3902,7 +3902,7 @@ static int defineMS(WindowInfo *window,
736 - sym = LookupSymbol(name);
737 + sym = LookupSymbol(name, False);
741 @@ -7313,7 +7313,7 @@ Boolean MacroApplyHook(WindowInfo *docum
743 Boolean succ = False;
745 - hookSymbol = LookupSymbol(hook);
746 + hookSymbol = LookupSymbol(hook, False);
747 if (NULL != hookSymbol && MACRO_FUNCTION_SYM == hookSymbol->type) {
748 Program *hookProg = hookSymbol->value.val.prog;
749 RestartData *restartData;