unlike most other interpreted language, the nedit macro language suffer from a function, that calls a named function with some arguments. so here is a rough copy'n'paste patch:
syntax:
ret = call_func(name[, arguments for named function...])
this new version adds a second function named "call_func_with_args". this function takes a array as second parameter, and calls the named function with the arguments from this array. this array is of the same form like the $args array.
This would be more useful if it could replace itself with the called function in the original macro context. That way limitations concerning pre-emption could be avoided where possible. It's not that difficult to do: break callSubroutine() in interpret.c into callSubroutineFromSymbol(sym,nArgs) and a wrapper called callSubroutine() which finds the values to pass to ...FromSymbol(), then calls it. Then create a macro built-in "call(name,...)" (callMS()) which does a symbol lookup to find the function for name, then calls a new function in interpret.c which adjusts the arguments in the stack (to remove the symbol name argument) then calls callSubroutineFromSymbol(). (I called this last function OverlayRoutineFromStack(sym,nArgs,nRemoveArgs).) I haven't tried an equivalent call_func_with_args() yet, but it shouldn't take much...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have no deeply knowledge of the nedit interpreter and i can't follow
your reason with the pre-emption, if you think it should be implemented
your way, than feel free to do so. I just naivly copy'n'paste code from
interpret.c into a new macro subroutine and figured out that it Just
Worked. But that reminds me of the following feature, you have bring to
disussion, and i do it here again:
a = "length"
len = a("string")
how about this (this doesn't adress the call_func_with_args() macro):
diff --quilt old/source/interpret.c new/source/interpret.c
--- old/source/interpret.c
+++ new/source/interpret.c
@@ -2038,10 +2038,22 @@ static int callSubroutine(void)
DISASM_RT(PC-3, 3);
STACKDUMP(nArgs, 3);
/*
+ ** If the symbol is a string, try to resolve the string to a symbol
+ */
+ if (sym->type == GLOBAL_SYM) {
+ if (sym->value.tag == STRING_TAG) {
+ Symbol *newsym = LookupSymbol(sym->value.val.str.rep);
+ if (newsym) {
+ sym = newsym;
+ }
+ }
+ }
+
+ /*
** If the subroutine is built-in, call the built-in routine
*/
if (sym->type == C_FUNCTION_SYM) {
DataValue result;
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, I think that's almost exactly what I did, except that I didn't force the symbol to be global. I must say that, though it works well, I don't much like it. (It makes me uneasy, it's so flexible!) The more explicit macro function call(name,...) provides the same functionality more explicitly.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
a multiplexer for the file_open_hook()
Logged In: YES
user_id=122956
Originator: YES
a natural use of the call_func() macro. only usable with the Patch Collection patch from Thorsten Haude (see: http://sourceforge.net/tracker/index.php?func=detail&aid=1058246&group_id=11005&atid=311005\)
File Added: hook.nm
a generic hook multiplexer
Logged In: YES
user_id=122956
Originator: YES
a more generic hook multiplexer, needs the define_func() patch (see: http://sourceforge.net/tracker/index.php?func=detail&aid=1640333&group_id=11005&atid=311005\):
defines two functions
callback_register(string hook, string function)
callback_deregister(string hook, string function)
if it's the first function for an hook, a new multiplexer function is generated with the define_func() routine
there is only one problem: hooks that gets a parameter, this case isn't handled at all
File Added: hook.nm
a generic hook multiplexer, gen2
Logged In: YES
user_id=122956
Originator: YES
fixing the generic multiplexer
File Added: hook.nm
gen2
Logged In: YES
user_id=122956
Originator: YES
this new version adds a second function named "call_func_with_args". this function takes a array as second parameter, and calls the named function with the arguments from this array. this array is of the same form like the $args array.
syntax:
[ret = ]call_func_with_args(string name, array args)
is equivalent to:
[ret = ]name(args[1], args[2], ...)
File Added: call_func.patch
a generic hook multiplexer, gen3
Logged In: YES
user_id=122956
Originator: YES
update the generic hook multiplexer to use the new call_func_with_args() macro. now the case where hooks get arguments are handled
File Added: hook.nm
Logged In: YES
user_id=618141
Originator: NO
This would be more useful if it could replace itself with the called function in the original macro context. That way limitations concerning pre-emption could be avoided where possible. It's not that difficult to do: break callSubroutine() in interpret.c into callSubroutineFromSymbol(sym,nArgs) and a wrapper called callSubroutine() which finds the values to pass to ...FromSymbol(), then calls it. Then create a macro built-in "call(name,...)" (callMS()) which does a symbol lookup to find the function for name, then calls a new function in interpret.c which adjusts the arguments in the stack (to remove the symbol name argument) then calls callSubroutineFromSymbol(). (I called this last function OverlayRoutineFromStack(sym,nArgs,nRemoveArgs).) I haven't tried an equivalent call_func_with_args() yet, but it shouldn't take much...
Logged In: YES
user_id=122956
Originator: YES
I have no deeply knowledge of the nedit interpreter and i can't follow
your reason with the pre-emption, if you think it should be implemented
your way, than feel free to do so. I just naivly copy'n'paste code from
interpret.c into a new macro subroutine and figured out that it Just
Worked. But that reminds me of the following feature, you have bring to
disussion, and i do it here again:
a = "length"
len = a("string")
how about this (this doesn't adress the call_func_with_args() macro):
diff --quilt old/source/interpret.c new/source/interpret.c
--- old/source/interpret.c
+++ new/source/interpret.c
@@ -2038,10 +2038,22 @@ static int callSubroutine(void)
DISASM_RT(PC-3, 3);
STACKDUMP(nArgs, 3);
/*
+ ** If the symbol is a string, try to resolve the string to a symbol
+ */
+ if (sym->type == GLOBAL_SYM) {
+ if (sym->value.tag == STRING_TAG) {
+ Symbol *newsym = LookupSymbol(sym->value.val.str.rep);
+ if (newsym) {
+ sym = newsym;
+ }
+ }
+ }
+
+ /*
** If the subroutine is built-in, call the built-in routine
*/
if (sym->type == C_FUNCTION_SYM) {
DataValue result;
Logged In: YES
user_id=618141
Originator: NO
Yes, I think that's almost exactly what I did, except that I didn't force the symbol to be global. I must say that, though it works well, I don't much like it. (It makes me uneasy, it's so flexible!) The more explicit macro function call(name,...) provides the same functionality more explicitly.