3 source/interpret.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++---
4 source/interpret.h | 3 +-
5 source/macro.c | 25 +++++++++++++++-------
6 3 files changed, 77 insertions(+), 11 deletions(-)
8 diff --quilt old/source/interpret.c new/source/interpret.c
9 --- old/source/interpret.c
10 +++ new/source/interpret.c
11 @@ -184,11 +184,11 @@ static void disasmInternal(Inst *inst, i
12 #endif /* #ifndef DEBUG_ASSEMBLY */
14 #ifdef DEBUG_STACK /* for run-time instruction and stack trace */
15 static void stackdump(int n, int extra);
16 static void stackdumpInternal(int n, int extra);
17 -#define STACKDUMP(n, x) stackdump(n, x)
18 +#define STACKDUMP(n, x) stackdump(n, (x) + 10)
19 #define DISASM_RT(i, n) disasm(NULL, i, n)
20 #else /* #ifndef DEBUG_STACK */
21 #define STACKDUMP(n, x)
22 #define DISASM_RT(i, n)
23 #endif /* #ifndef DEBUG_STACK */
24 @@ -304,10 +304,11 @@ static int (*OpFns[N_OPS])() = {returnNo
25 return execError(StackOverflowMsg, ""); \
29 static const char *tagToStr(enum typeTags tag);
30 +static const char *typeToStr(enum symTypes type);
33 ** Initialize macro language global variables. Must be called before
34 ** any macros are even parsed, because the parser uses action routine
35 ** symbols to comprehend hyphenated names.
36 @@ -425,10 +426,11 @@ int AddSym(Symbol *sym, char **msg)
38 if (ProgP >= &Prog[PROGRAM_SIZE]) {
39 *msg = "macro too large";
48 @@ -863,10 +865,11 @@ Symbol *InstallSymbol(const char *name,
49 s = (Symbol *)malloc(sizeof(Symbol));
50 s->name = (char *)malloc(strlen(name)+1); /* +1 for '\0' */
51 strcpy(s->name, name);
55 if (type == LOCAL_SYM) {
56 s->next = LocalSymList;
59 s->next = GlobalSymList;
60 @@ -880,13 +883,12 @@ Symbol *InstallSymbol(const char *name,
63 Symbol *PromoteToGlobal(Symbol *sym)
66 - static DataValue noValue = {NO_TAG, {0}};
68 - if (sym->type != LOCAL_SYM)
69 + if (sym->type != LOCAL_SYM || sym->added)
72 /* Remove sym from the local symbol list */
73 if (sym == LocalSymList)
74 LocalSymList = sym->next;
75 @@ -1384,10 +1386,15 @@ static int pushSymVal(void)
77 if (!(s->value.val.subr)(FocusWindow, NULL, 0,
79 return execError(errMsg, s->name);
81 + } else if (s->type == C_FUNCTION_SYM
82 + || s->type == MACRO_FUNCTION_SYM
83 + || s->type == ACTION_ROUTINE_SYM) {
84 + symVal.tag = SUBR_TAG;
87 return execError("reading non-variable: %s", s->name);
88 if (symVal.tag == NO_TAG && !inTypeOfMode) {
89 return execError("variable not set: %s", s->name);
91 @@ -2470,14 +2477,28 @@ static int callSubroutineFromSymbol(Symb
93 static DataValue noValue = {NO_TAG, {0}};
96 int haveNamedArgs = (nArgs < 0);
97 + DataValue *symValPtr = NULL;
102 + if (sym->type == LOCAL_SYM) {
103 + symValPtr = &FP_GET_SYM_VAL(FrameP, sym);
104 + } else if (sym->type == GLOBAL_SYM) {
105 + symValPtr = &sym->value;
108 + if (symValPtr->tag == SUBR_TAG) {
109 + sym = symValPtr->val.sym;
111 + return execError("%s is not a variable holding a subroutine pointer", sym->name);
116 ** If the subroutine is built-in, call the built-in routine
118 if (sym->type == C_FUNCTION_SYM) {
120 @@ -3978,10 +3999,13 @@ static int typeOfOut(void)
121 retVal.val.str.rep = PERM_ALLOC_STR("STRING");
124 retVal.val.str.rep = PERM_ALLOC_STR("ARRAY");
127 + retVal.val.str.rep = PERM_ALLOC_STR("SUBROUTINE");
130 retVal.val.str.len = strlen(retVal.val.str.rep);
132 if (PC->func == fetchRetVal) {
134 @@ -4129,16 +4153,43 @@ static const char *tagToStr(enum typeTag
141 + return "<subroutine>";
148 +static const char *typeToStr(enum symTypes type)
159 + case PROC_VALUE_SYM:
160 + return "<proc value>";
161 + case C_FUNCTION_SYM:
162 + return "<C function>";
163 + case MACRO_FUNCTION_SYM:
164 + return "<macro function>";
165 + case ACTION_ROUTINE_SYM:
166 + return "<action routine>";
173 #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */
174 static char *printdBuffer = NULL;
175 static int printdPos = 0;
176 static int printdSize = 0;
178 @@ -4253,10 +4304,13 @@ static void dumpVal(DataValue dv)
182 printd("<array> %8p[%d]", dv.val.arrayPtr, ArraySize(&dv));
185 + printd("<subroutine> %s", dv.val.sym->name);
189 printd("<no value>");
192 diff --quilt old/source/interpret.h new/source/interpret.h
193 --- old/source/interpret.h
194 +++ new/source/interpret.h
195 @@ -58,11 +58,11 @@ enum operations {OP_RETURN_NO_VAL, OP_RE
198 OP_BEGIN_ARRAY_MULTI_ITER_ARRAY, OP_ARRAY_MULTI_ITER_ARRAY, OP_POP,
201 -enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG};
202 +enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG, SUBR_TAG};
204 enum execReturnCodes {MACRO_TIME_LIMIT, MACRO_PREEMPT, MACRO_DONE, MACRO_ERROR};
206 #define ARRAY_DIM_SEP "\034"
208 @@ -110,10 +110,11 @@ typedef struct SparseArrayEntryTag {
209 typedef struct SymbolRec {
213 struct SymbolRec *next; /* to link to another */
217 typedef struct ProgramTag {
218 Symbol *localSymList;
220 diff --quilt old/source/macro.c new/source/macro.c
221 --- old/source/macro.c
222 +++ new/source/macro.c
223 @@ -3842,31 +3842,39 @@ static int filenameDialogMS(WindowInfo*
224 * call(fnname, arg, ...)
226 static int callMS(WindowInfo *window, DataValue *argList,
227 int nArgs, DataValue *result, char **errMsg)
229 - char stringStorage[TYPE_INT_STR_SIZE(int)];
234 *errMsg = "subroutine %s called without arguments";
237 - if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
239 + if (argList[0].tag == SUBR_TAG) {
240 + sym = argList[0].val.sym;
242 + char stringStorage[TYPE_INT_STR_SIZE(int)];
245 + if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
249 + sym = LookupSymbol(fnname);
251 - sym = LookupSymbol(fnname);
254 *errMsg = "subroutine name invalid";
258 return OverlayRoutineFromSymbol(sym, nArgs, 1);
262 - * define(func_name, func_body[, "override"])
263 + * subr = define(func_name, func_body[, "override"])
265 static int defineMS(WindowInfo *window, DataValue *argList, int nArgs,
266 DataValue *result, char **errMsg)
268 char stringStorage[3][TYPE_INT_STR_SIZE(int)];
269 @@ -3876,11 +3884,10 @@ static int defineMS(WindowInfo *window,
270 char *stoppedAt = NULL;
272 char *override = NULL;
277 if (nArgs < 2 || nArgs > 3) {
278 return wrongNArgsErr(errMsg);
280 if (!readStringArg(argList[0], &name, stringStorage[0], errMsg)) {
281 @@ -3944,15 +3951,19 @@ static int defineMS(WindowInfo *window,
283 FreeProgram(sym->value.val.prog);
284 sym->value.val.prog = prog;
288 subrPtr.val.prog = prog;
289 subrPtr.tag = NO_TAG;
290 sym = InstallSymbol(name, MACRO_FUNCTION_SYM, subrPtr);
293 + result->tag = SUBR_TAG;
294 + result->val.sym = sym;
300 * set_window_title(format[, ("text"|"format")])