CVS update
[nedit-bw.git] / SUBR_TAG.patch
blob41ffe14329423c826b480316d9cf351b811bee48
1 Subject: new variable type 'subroutine', as pointer to functions
3 You can get the variable holding a pointer to a function simpley by assignment:
5 my_t_print = t_print
7 and use this like a normal function name:
9 my_t_print("hello world\n")
11 or with the call() macro:
13 call(my_t_print, "hello world\n")
15 The define() macro returns also a pointer to the just created function:
17 my_t_print = define("bla", 't_print(=$args)' "\n")
18 my_t_print("hello world\n")
20 ---
22 source/interpret.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++--
23 source/interpret.h | 3 +-
24 source/macro.c | 25 ++++++++++++++++------
25 3 files changed, 77 insertions(+), 10 deletions(-)
27 diff --quilt old/source/interpret.c new/source/interpret.c
28 --- old/source/interpret.c
29 +++ new/source/interpret.c
30 @@ -109,6 +109,7 @@ static SparseArrayEntry *allocateSparseA
31 static int inTypeOfMode;
33 static const char *tagToStr(enum typeTags tag);
34 +static const char *typeToStr(enum symTypes type);
36 /*#define DEBUG_ASSEMBLY*/
37 /*#define DEBUG_STACK*/
38 @@ -130,7 +131,7 @@ static void disasmInternal(Inst *inst, i
39 #ifdef DEBUG_STACK /* for run-time instruction and stack trace */
40 static void stackdump(int n, int extra);
41 static void stackdumpInternal(int n, int extra);
42 -#define STACKDUMP(n, x) stackdump(n, x)
43 +#define STACKDUMP(n, x) stackdump(n, (x) + 10)
44 #define DISASM_RT(i, n) disasm(NULL, i, n)
45 #else /* #ifndef DEBUG_STACK */
46 #define STACKDUMP(n, x)
47 @@ -343,6 +344,7 @@ int AddSym(Symbol *sym, char **msg)
48 *msg = "macro too large";
49 return 0;
51 + sym->added = 1;
52 ProgP->sym = sym;
53 ProgP++;
54 return 1;
55 @@ -837,6 +839,7 @@ Symbol *InstallSymbol(const char *name,
56 strcpy(s->name, name);
57 s->type = type;
58 s->value = value;
59 + s->added = 0;
60 if (type == LOCAL_SYM) {
61 s->next = LocalSymList;
62 LocalSymList = s;
63 @@ -861,7 +864,7 @@ Symbol *PromoteToGlobal(Symbol *sym)
65 Symbol *s;
67 - if (sym->type != LOCAL_SYM)
68 + if (sym->type != LOCAL_SYM || sym->added)
69 return sym;
71 /* Remove sym from the local symbol list */
72 @@ -1418,6 +1421,11 @@ static int pushSymVal(void)
73 &symVal, &errMsg)) {
74 return execError(errMsg, s->name);
76 + } else if (s->type == C_FUNCTION_SYM
77 + || s->type == MACRO_FUNCTION_SYM
78 + || s->type == ACTION_ROUTINE_SYM) {
79 + symVal.tag = SUBR_TAG;
80 + symVal.val.sym = s;
81 } else
82 return execError("reading non-variable: %s", s->name);
83 if (symVal.tag == NO_TAG && !inTypeOfMode) {
84 @@ -2548,12 +2556,26 @@ static int callSubroutineFromSymbol(Symb
85 Program *prog;
86 char *errMsg;
87 int haveNamedArgs = (nArgs < 0);
88 + DataValue *symValPtr = NULL;
90 if (haveNamedArgs) {
91 nArgs = -nArgs - 1;
92 POP(argArray);
95 + if (sym->type == LOCAL_SYM) {
96 + symValPtr = &FP_GET_SYM_VAL(FrameP, sym);
97 + } else if (sym->type == GLOBAL_SYM) {
98 + symValPtr = &sym->value;
99 + }
100 + if (symValPtr) {
101 + if (symValPtr->tag == SUBR_TAG) {
102 + sym = symValPtr->val.sym;
103 + } else {
104 + return execError("%s is not a variable holding a subroutine pointer", sym->name);
109 ** If the subroutine is built-in, call the built-in routine
111 @@ -3952,6 +3974,9 @@ static int typeOfOut(void)
112 case ARRAY_TAG:
113 retVal.val.str.rep = PERM_ALLOC_STR("ARRAY");
114 break;
115 + case SUBR_TAG:
116 + retVal.val.str.rep = PERM_ALLOC_STR("SUBROUTINE");
117 + break;
119 retVal.val.str.len = strlen(retVal.val.str.rep);
121 @@ -4181,12 +4206,39 @@ static const char *tagToStr(enum typeTag
122 return "<string>";
123 case ARRAY_TAG:
124 return "<array>";
125 + case SUBR_TAG:
126 + return "<subroutine>";
127 case NO_TAG:
128 default:
129 return "<no value>";
133 +static const char *typeToStr(enum symTypes type)
135 + switch (type) {
136 + case CONST_SYM:
137 + return "<const>";
138 + case GLOBAL_SYM:
139 + return "<global>";
140 + case LOCAL_SYM:
141 + return "<local>";
142 + case ARG_SYM:
143 + return "<arg>";
144 + case PROC_VALUE_SYM:
145 + return "<proc value>";
146 + case C_FUNCTION_SYM:
147 + return "<C function>";
148 + case MACRO_FUNCTION_SYM:
149 + return "<macro function>";
150 + case ACTION_ROUTINE_SYM:
151 + return "<action routine>";
154 + return "";
158 #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */
159 static char *printdBuffer = NULL;
160 static int printdPos = 0;
161 @@ -4305,6 +4357,9 @@ static void dumpVal(DataValue dv)
162 case ARRAY_TAG:
163 printd("<array> %8p[%d]", dv.val.arrayPtr, ArraySize(&dv));
164 break;
165 + case SUBR_TAG:
166 + printd("<subroutine> %s", dv.val.sym->name);
167 + break;
168 case NO_TAG:
169 if (!dv.val.inst) {
170 printd("<no value>");
171 diff --quilt old/source/interpret.h new/source/interpret.h
172 --- old/source/interpret.h
173 +++ new/source/interpret.h
174 @@ -50,7 +50,7 @@ enum operations {
175 N_OPS
178 -enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG};
179 +enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG, SUBR_TAG};
181 enum execReturnCodes {MACRO_TIME_LIMIT, MACRO_PREEMPT, MACRO_DONE, MACRO_ERROR};
183 @@ -102,6 +102,7 @@ typedef struct SymbolRec {
184 enum symTypes type;
185 DataValue value;
186 struct SymbolRec *next; /* to link to another */
187 + int added;
188 } Symbol;
190 typedef struct ProgramTag {
191 diff --quilt old/source/macro.c new/source/macro.c
192 --- old/source/macro.c
193 +++ new/source/macro.c
194 @@ -3809,27 +3809,35 @@ static int filenameDialogMS(WindowInfo*
195 static int callMS(WindowInfo *window, DataValue *argList,
196 int nArgs, DataValue *result, char **errMsg)
198 - char stringStorage[TYPE_INT_STR_SIZE(int)];
199 Symbol *sym;
200 - char *fnname;
202 if (nArgs < 1) {
203 *errMsg = "subroutine %s called without arguments";
204 return False;
206 - if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
207 - return False;
208 + if (argList[0].tag == SUBR_TAG) {
209 + sym = argList[0].val.sym;
210 + } else {
211 + char stringStorage[TYPE_INT_STR_SIZE(int)];
212 + char *fnname;
214 + if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
215 + return False;
218 + sym = LookupSymbol(fnname);
220 - sym = LookupSymbol(fnname);
222 if (!sym) {
223 *errMsg = "subroutine name invalid";
224 return False;
227 return OverlayRoutineFromSymbol(sym, nArgs, 1);
231 - * define(func_name, func_body[, "override"])
232 + * subr = define(func_name, func_body[, "override"])
234 static int defineMS(WindowInfo *window, DataValue *argList, int nArgs,
235 DataValue *result, char **errMsg)
236 @@ -3843,7 +3851,6 @@ static int defineMS(WindowInfo *window,
237 char *override = NULL;
238 Program *prog;
239 Symbol *sym;
240 - DataValue subrPtr;
242 if (nArgs < 2 || nArgs > 3) {
243 return wrongNArgsErr(errMsg);
244 @@ -3913,11 +3920,15 @@ static int defineMS(WindowInfo *window,
245 sym->value.val.prog = prog;
247 } else {
248 + DataValue subrPtr;
249 subrPtr.tag = NO_TAG;
250 subrPtr.val.prog = prog;
251 sym = InstallSymbol(name, MACRO_FUNCTION_SYM, subrPtr);
254 + result->tag = SUBR_TAG;
255 + result->val.sym = sym;
257 return True;