use StringToNumEnd() for check of numeric keys
[nedit-bw.git] / SUBR_TAG.patch
blobad7315917bab2a0dc15ccc6ec89918d8c6242ddd
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 | 31 ++++++++++++++++++++++++++++++-
23 source/interpret.h | 3 ++-
24 source/macro.c | 25 ++++++++++++++++++-------
25 3 files changed, 50 insertions(+), 9 deletions(-)
27 diff --quilt old/source/interpret.c new/source/interpret.c
28 --- old/source/interpret.c
29 +++ new/source/interpret.c
30 @@ -344,6 +344,7 @@ int AddSym(Symbol *sym, char **msg)
31 *msg = "macro too large";
32 return 0;
34 + sym->added = 1;
35 ProgP->sym = sym;
36 ProgP++;
37 return 1;
38 @@ -838,6 +839,7 @@ Symbol *InstallSymbol(const char *name,
39 strcpy(s->name, name);
40 s->type = type;
41 s->value = value;
42 + s->added = 0;
43 if (type == LOCAL_SYM) {
44 s->next = LocalSymList;
45 LocalSymList = s;
46 @@ -862,7 +864,7 @@ Symbol *PromoteToGlobal(Symbol *sym)
48 Symbol *s;
50 - if (sym->type != LOCAL_SYM)
51 + if (sym->type != LOCAL_SYM || sym->added)
52 return sym;
54 /* Remove sym from the local symbol list */
55 @@ -1419,6 +1421,11 @@ static int pushSymVal(void)
56 &symVal, &errMsg)) {
57 return execError(errMsg, s->name);
59 + } else if (s->type == C_FUNCTION_SYM
60 + || s->type == MACRO_FUNCTION_SYM
61 + || s->type == ACTION_ROUTINE_SYM) {
62 + symVal.tag = SUBR_TAG;
63 + symVal.val.sym = s;
64 } else
65 return execError("reading non-variable: %s", s->name);
66 if (symVal.tag == NO_TAG && !inTypeOfMode) {
67 @@ -2517,12 +2524,26 @@ static int callSubroutineFromSymbol(Symb
68 Program *prog;
69 char *errMsg;
70 int haveNamedArgs = (nArgs < 0);
71 + DataValue *symValPtr = NULL;
73 if (haveNamedArgs) {
74 nArgs = -nArgs - 1;
75 POP(argArray);
78 + if (sym->type == LOCAL_SYM) {
79 + symValPtr = &FP_GET_SYM_VAL(FrameP, sym);
80 + } else if (sym->type == GLOBAL_SYM) {
81 + symValPtr = &sym->value;
82 + }
83 + if (symValPtr) {
84 + if (symValPtr->tag == SUBR_TAG) {
85 + sym = symValPtr->val.sym;
86 + } else {
87 + return execError("%s is not a variable holding a subroutine pointer", sym->name);
88 + }
89 + }
92 ** If the subroutine is built-in, call the built-in routine
94 @@ -3893,6 +3914,9 @@ static int typeOfOut(void)
95 case ARRAY_TAG:
96 retVal.val.str.rep = PERM_ALLOC_STR("ARRAY");
97 break;
98 + case SUBR_TAG:
99 + retVal.val.str.rep = PERM_ALLOC_STR("SUBROUTINE");
100 + break;
102 retVal.val.str.len = strlen(retVal.val.str.rep);
104 @@ -4154,6 +4178,8 @@ static const char *tagToStr(enum typeTag
105 return "string";
106 case ARRAY_TAG:
107 return "array";
108 + case SUBR_TAG:
109 + return "subroutine";
110 case NO_TAG:
111 default:
112 return "no value";
113 @@ -4280,6 +4306,9 @@ static void dumpVal(DataValue dv)
114 printd("<%s %u:%8p>", tagToStr(ARRAY_TAG), ArraySize(&dv),
115 dv.val.arrayPtr);
116 break;
117 + case SUBR_TAG:
118 + printd("<%s %s>", tagToStr(SUBR_TAG), dv.val.sym->name);
119 + break;
120 case NO_TAG:
121 if (!dv.val.inst) {
122 printd("<%s>", tagToStr(NO_TAG));
123 diff --quilt old/source/interpret.h new/source/interpret.h
124 --- old/source/interpret.h
125 +++ new/source/interpret.h
126 @@ -50,7 +50,7 @@ enum operations {
127 N_OPS
130 -enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG};
131 +enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG, SUBR_TAG};
133 enum execReturnCodes {MACRO_TIME_LIMIT, MACRO_PREEMPT, MACRO_DONE, MACRO_ERROR};
135 @@ -102,6 +102,7 @@ typedef struct SymbolRec {
136 enum symTypes type;
137 DataValue value;
138 struct SymbolRec *next; /* to link to another */
139 + int added;
140 } Symbol;
142 typedef struct ProgramTag {
143 diff --quilt old/source/macro.c new/source/macro.c
144 --- old/source/macro.c
145 +++ new/source/macro.c
146 @@ -3805,27 +3805,35 @@ static int filenameDialogMS(WindowInfo*
147 static int callMS(WindowInfo *window, DataValue *argList,
148 int nArgs, DataValue *result, char **errMsg)
150 - char stringStorage[TYPE_INT_STR_SIZE(int)];
151 Symbol *sym;
152 - char *fnname;
154 if (nArgs < 1) {
155 *errMsg = "subroutine %s called without arguments";
156 return False;
158 - if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
159 - return False;
160 + if (argList[0].tag == SUBR_TAG) {
161 + sym = argList[0].val.sym;
162 + } else {
163 + char stringStorage[TYPE_INT_STR_SIZE(int)];
164 + char *fnname;
166 + if (!readStringArg(argList[0], &fnname, stringStorage, errMsg)) {
167 + return False;
170 + sym = LookupSymbol(fnname);
172 - sym = LookupSymbol(fnname);
174 if (!sym) {
175 *errMsg = "subroutine name invalid";
176 return False;
179 return OverlayRoutineFromSymbol(sym, nArgs, 1);
183 - * define(func_name, func_body[, "override"])
184 + * subr = define(func_name, func_body[, "override"])
186 static int defineMS(WindowInfo *window, DataValue *argList, int nArgs,
187 DataValue *result, char **errMsg)
188 @@ -3839,7 +3847,6 @@ static int defineMS(WindowInfo *window,
189 char *override = NULL;
190 Program *prog;
191 Symbol *sym;
192 - DataValue subrPtr;
194 if (nArgs < 2 || nArgs > 3) {
195 return wrongNArgsErr(errMsg);
196 @@ -3909,11 +3916,15 @@ static int defineMS(WindowInfo *window,
197 sym->value.val.prog = prog;
199 } else {
200 + DataValue subrPtr;
201 subrPtr.tag = NO_TAG;
202 subrPtr.val.prog = prog;
203 sym = InstallSymbol(name, MACRO_FUNCTION_SYM, subrPtr);
206 + result->tag = SUBR_TAG;
207 + result->val.sym = sym;
209 return True;