fix apply errors
[nedit-bw.git] / callMacroFnByName2.diff
blobcefcf0e4635e0357259f74bf9794c698fd02ad2e
1 From: Tony Balinski <ajbj@free.fr>
2 Subject: Provide a call() macro function which calls another function given its name
4 The function invokes new code in interpret.c which calls the desired, named
5 function with any remaining arguments to call(). In this way, the function
6 is called using the same interpretation environment as call()'s invoker.
8 ---
10 source/interpret.c | 91 ++++++++++++++++++++++++++++++++++++++++++++---------
11 source/interpret.h | 4 ++
12 source/macro.c | 28 ++++++++++++++++
13 3 files changed, 109 insertions(+), 14 deletions(-)
15 diff --quilt old/source/interpret.c new/source/interpret.c
16 --- old/source/interpret.c
17 +++ new/source/interpret.c
18 @@ -89,6 +89,7 @@ static int returnValOrNone(int valOnStac
19 static int branchIf(Boolean trueOrFalse);
20 static int namedArg1orN(Boolean isFirst);
22 +static int callSubroutineFromSymbol(Symbol *sym, int nArgs);
23 static int concatenateNwithSep(int nVals, const char *sep, char **result,
24 int leaveParams);
25 static int makeArrayKeyFromArgs(int nArgs, char **keyString, int leaveParams);
26 @@ -2440,7 +2441,9 @@ static int concat(void)
27 ** arguments and space for local variables are added to the stack, and the
28 ** PC is set to point to the new function. For a built-in routine, the
29 ** arguments are popped off the stack, and the routine is just called.
30 -**
31 +*/
32 +/*
33 +** For callSubroutine:
34 ** Before: Prog-> [subrSym], nArgs, next, ...
35 ** TheStack-> argArray?, argN-arg1, next, ...
36 ** After: Prog-> next, ... -- (built-in called subr)
37 @@ -2448,30 +2451,21 @@ static int concat(void)
38 ** or: Prog-> (in called)next, ... -- (macro code called subr)
39 ** TheStack-> symN-sym1(FP), nArgs, oldFP, retPC, argArray, argN-arg1, next, ...
41 -static int callSubroutine(void)
42 +static int callSubroutineFromSymbol(Symbol *sym, int nArgs)
44 - Symbol *sym, *s;
45 - int i, nArgs;
46 + Symbol *s;
47 + int i;
48 static DataValue noValue = {NO_TAG, {0}};
49 DataValue argArray = noValue;
50 Program *prog;
51 char *errMsg;
52 - int haveNamedArgs;
54 - sym = PC->sym;
55 - PC++;
56 - nArgs = PC->value;
57 - PC++;
58 + int haveNamedArgs = (nArgs < 0);
60 - haveNamedArgs = (nArgs < 0);
61 if (haveNamedArgs) {
62 nArgs = -nArgs - 1;
63 POP(argArray);
66 - DISASM_RT(PC-3, 3);
67 - STACKDUMP(nArgs + haveNamedArgs, 3);
70 ** If the subroutine is built-in, call the built-in routine
72 @@ -2568,6 +2562,75 @@ static int callSubroutine(void)
76 +** Before: Prog-> [subrSym], nArgs, next, ...
77 +** Stack-> argN-arg1, next, ...
78 +**
79 +** After: Prog-> next, ... -- (built-in called subr)
80 +** Stack-> retVal?, next, ...
81 +** or: Prog-> (in called)next, ... -- (macro code called subr)
82 +** Stack-> symN-sym1(FP), argArray, nArgs, oldFP, retPC, argN-arg1, next, ...
83 +*/
84 +static int callSubroutine(void)
86 + Symbol *sym;
87 + int nArgs;
88 + int n;
90 + sym = PC++->sym;
91 + nArgs = PC++->value;
93 + DISASM_RT(PC-3, 3);
94 + STACKDUMP(nArgs, 3);
96 + return callSubroutineFromSymbol(sym, nArgs);
99 +/*
100 +** Assumes a valid symbol. Invokes callSubroutineFromSymbol(), correcting nArgs
101 +** to match that routine's expectations. This allows a callMS() function to be
102 +** written in macro.c. If the caller has already "consumed" stack elements,
103 +** removeArgs must indicate how many.
106 +int OverlayRoutineFromSymbol(Symbol *sym, int nArgs, int removeArgs)
108 + DataValue *stackTop = StackP + nArgs - removeArgs;
110 + if (removeArgs > 0) {
111 + DataValue *from = StackP + removeArgs;
112 + DataValue *to = StackP;
113 + int n = nArgs - removeArgs;
115 + nArgs = n;
116 + while (n--) {
117 + *to++ = *from++;
121 + StackP = stackTop;
122 + return callSubroutineFromSymbol(sym, nArgs);
126 +** Assumes a valid prog. Wraps the program in a dummy symbol then calls
127 +** OverlayRoutineFromSymbol(). In this way a piece of compiled code can be
128 +** executed in the caller's context from a function in macro.c.
131 +int OverlayRoutineFromProg(Program *prog, int nArgs, int removeArgs)
133 + Symbol sym;
135 + sym.type = MACRO_FUNCTION_SYM;
136 + sym.name = prog->name;
137 + sym.value.tag = NO_TAG;
138 + sym.value.val.prog = prog;
139 + sym.next = NULL;
141 + return OverlayRoutineFromSymbol(&sym, nArgs, removeArgs);
145 ** This should never be executed, returnVal checks for the presence of this
146 ** instruction at the PC to decide whether to push the function's return
147 ** value, then skips over it without executing.
148 diff --quilt old/source/interpret.h new/source/interpret.h
149 --- old/source/interpret.h
150 +++ new/source/interpret.h
151 @@ -171,6 +171,10 @@ int ExecuteMacro(WindowInfo *window, Pro
152 int ContinueMacro(RestartData *continuation, DataValue *result, char **msg);
153 void RunMacroAsSubrCall(Program *prog);
154 void PreemptMacro(void);
156 +int OverlayRoutineFromProg(Program *prog, int nArgs, int removeArgs);
157 +int OverlayRoutineFromSymbol(Symbol *sym, int nArgs, int removeArgs);
159 char *AllocString(int length);
160 char *AllocStringNCpy(const char *s, int length);
161 char *AllocStringCpy(const char *s);
162 diff --quilt old/source/macro.c new/source/macro.c
163 --- old/source/macro.c
164 +++ new/source/macro.c
165 @@ -416,6 +416,8 @@ static int getStyleAtPosMS(WindowInfo *w
166 DataValue *result, char **errMsg);
167 static int filenameDialogMS(WindowInfo* window, DataValue* argList, int nArgs,
168 DataValue* result, char** errMsg);
169 +static int callMS(WindowInfo *window, DataValue *argList,
170 + int nArgs, DataValue *result, char **errMsg);
172 /* Built-in subroutines and variables for the macro language */
173 static const BuiltInSubrName MacroSubrs[] = {
174 @@ -475,6 +477,7 @@ static const BuiltInSubrName MacroSubrs[
175 { "get_style_by_name", getStyleByNameMS },
176 { "get_style_at_pos", getStyleAtPosMS },
177 { "filename_dialog", filenameDialogMS },
178 + { "call", callMS },
179 { NULL, NULL } /* sentinel */
182 @@ -3493,6 +3496,31 @@ static int filenameDialogMS(WindowInfo*
183 return True;
187 + * call(fnname, arg, ...)
188 + */
189 +static int callMS(WindowInfo *window, DataValue *argList,
190 + int nArgs, DataValue *result, char **errMsg)
192 + char stringStorage[TYPE_INT_STR_SIZE(int)];
193 + Symbol *sym;
194 + char *fnname;
196 + if (nArgs < 1) {
197 + *errMsg = "subroutine %s called without arguments";
198 + return False;
200 + if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
201 + return False;
203 + sym = LookupSymbol(fnname);
204 + if (!sym) {
205 + *errMsg = "subroutine name invalid";
206 + return False;
208 + return OverlayRoutineFromSymbol(sym, nArgs, 1);
211 /* T Balinski */
212 static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs,
213 DataValue *result, char **errMsg)