#157 call_func() macro

open
nobody
None
5
2007-01-19
2007-01-19
Bert Wesarg
No

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...])

Discussion

  • Bert Wesarg
    Bert Wesarg
    2007-01-19

     
    Attachments
  • Bert Wesarg
    Bert Wesarg
    2007-01-20

    a multiplexer for the file_open_hook()

     
    Attachments
  • Bert Wesarg
    Bert Wesarg
    2007-01-20

    a generic hook multiplexer

     
    Attachments
  • Bert Wesarg
    Bert Wesarg
    2007-01-20

    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

     
  • Bert Wesarg
    Bert Wesarg
    2007-01-21

    a generic hook multiplexer, gen2

     
    Attachments
  • Bert Wesarg
    Bert Wesarg
    2007-01-21

    Logged In: YES
    user_id=122956
    Originator: YES

    fixing the generic multiplexer
    File Added: hook.nm

     
  • Bert Wesarg
    Bert Wesarg
    2007-01-21

    gen2

     
    Attachments
  • Bert Wesarg
    Bert Wesarg
    2007-01-21

    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

     
  • Bert Wesarg
    Bert Wesarg
    2007-01-21

    a generic hook multiplexer, gen3

     
    Attachments
  • Bert Wesarg
    Bert Wesarg
    2007-01-21

    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

     
  • Tony Balinski
    Tony Balinski
    2007-02-01

    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...

     
  • Bert Wesarg
    Bert Wesarg
    2007-02-01

    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;

     
  • Tony Balinski
    Tony Balinski
    2007-02-01

    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.