Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/GAP/src/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 18.9.2025 mit Größe 25 kB image not shown  

Quelle  funcs.c   Sprache: C

 
/****************************************************************************
**
**  This file is part of GAP, a system for computational discrete algebra.
**
**  Copyright of GAP belongs to its developers, whose names are too numerous
**  to list here. Please refer to the COPYRIGHT file for details.
**
**  SPDX-License-Identifier: GPL-2.0-or-later
**
**  This file contains the functions of the function interpreter package.
**
**  The function interpreter package   contains the executors  for  procedure
**  calls, the  evaluators  for function calls,  the   evaluator for function
**  expressions, and the handlers for the execution of function bodies.
**
**  It uses the function call mechanism defined by the calls package.
*/


#include "funcs.h"

#include "calls.h"
#include "code.h"
#include "error.h"
#include "exprs.h"
#include "gapstate.h"
#include "hookintrprtr.h"
#include "io.h"
#include "lists.h"
#include "modules.h"
#include "opers.h"
#include "plist.h"
#include "stats.h"
#include "stringobj.h"
#include "trycatch.h"
#include "vars.h"

#ifdef HPCGAP
#include "hpc/guards.h"
#include "hpc/thread.h"
#include <stdlib.h>     // for alloca
#endif


static ModuleStateOffset FuncsStateOffset = -1;

struct FuncsModuleState {
    Int RecursionDepth;
};

extern inline struct FuncsModuleState *FuncsState(void)
{
    return (struct FuncsModuleState *)StateSlotsAtOffset(FuncsStateOffset);
}

Int IncRecursionDepth(void)
{
    int depth = ++(FuncsState()->RecursionDepth);
    return depth;
}

void DecRecursionDepth(void)
{
    FuncsState()->RecursionDepth--;
    /* FIXME: According to a comment in the function
              RecursionDepthTrap below, RecursionDepth
              can become "slightly" negative. This
              needs some investigation.
    GAP_ASSERT(FuncsState()->RecursionDepth >= 0);
    */

}

Int GetRecursionDepth(void)
{
    return FuncsState()->RecursionDepth;
}

void SetRecursionDepth(Int depth)
{
    GAP_ASSERT(depth >= 0);
    FuncsState()->RecursionDepth = depth;
}

/****************************************************************************
**
*F  ExecProccall0args(<call>)  .  execute a procedure call with 0    arguments
*F  ExecProccall1args(<call>)  .  execute a procedure call with 1    arguments
*F  ExecProccall2args(<call>)  .  execute a procedure call with 2    arguments
*F  ExecProccall3args(<call>)  .  execute a procedure call with 3    arguments
*F  ExecProccall4args(<call>)  .  execute a procedure call with 4    arguments
*F  ExecProccall5args(<call>)  .  execute a procedure call with 5    arguments
*F  ExecProccall6args(<call>)  .  execute a procedure call with 6    arguments
*F  ExecProccallXargs(<call>)  .  execute a procedure call with more arguments
**
**  'ExecProccall<i>args'  executes  a  procedure   call   to the    function
**  'FUNC_CALL(<call>)'   with   the   arguments   'ARGI_CALL(<call>,1)'   to
**  'ARGI_CALL(<call>,<i>)'.  It discards the value returned by the function
**  and returns the statement execution status (as per EXEC_STAT, q.v.)
**  resulting from the procedure call, which in fact is always 0.
*/


static Obj PushOptions;
static Obj PopOptions;

static ALWAYS_INLINE Obj EvalOrExecCall(Int ignoreResult, UInt nr, Stat call, Stat opts)
{
    Obj func;
    Obj a[6] = { 0 };
    Obj args = 0;
    Obj result;

    // evaluate the function
    func = EVAL_EXPR( FUNC_CALL( call ) );

    // evaluate the arguments
    if (nr <= 6 && TNUM_OBJ(func) == T_FUNCTION) {
        for (UInt i = 1; i <= nr; i++) {
            a[i - 1] = EVAL_EXPR(ARGI_CALL(call, i));
        }
    }
    else {
        UInt realNr = NARG_SIZE_CALL(SIZE_STAT(call));
        args = NEW_PLIST(T_PLIST, realNr);
        SET_LEN_PLIST(args, realNr);
        for (UInt i = 1; i <= realNr; i++) {
            Obj argi = EVAL_EXPR(ARGI_CALL(call, i));
            SET_ELM_PLIST(args, i, argi);
            CHANGED_BAG(args);
        }
    }

    if (opts) {
        CALL_1ARGS(PushOptions, EVAL_EXPR(opts));
    }

    // call the function
    SET_BRK_CALL_TO( call );
    if (TNUM_OBJ(func) != T_FUNCTION) {
        result = DoOperation2Args(CallFuncListOper, func, args);
    }
    else {
        switch (nr) {
        case 0:
            result = CALL_0ARGS(func);
            break;
        case 1:
            result = CALL_1ARGS(func, a[0]);
            break;
        case 2:
            result = CALL_2ARGS(func, a[0], a[1]);
            break;
        case 3:
            result = CALL_3ARGS(func, a[0], a[1], a[2]);
            break;
        case 4:
            result = CALL_4ARGS(func, a[0], a[1], a[2], a[3]);
            break;
        case 5:
            result = CALL_5ARGS(func, a[0], a[1], a[2], a[3], a[4]);
            break;
        case 6:
            result = CALL_6ARGS(func, a[0], a[1], a[2], a[3], a[4], a[5]);
            break;
        default:
            result = CALL_XARGS(func, args);
        }
    }
    if (STATE(UserHasQuit) || STATE(UserHasQUIT)) {
        // the function must have called READ() and the user quit from a break loop
        // inside it; or a file containing a `QUIT` statement was read at the top
        // execution level (e.g. in init.g, before the primary REPL starts) after
        // which the function was called, and now we are returning from that
        GAP_THROW();
    }

    if (!ignoreResult && result == 0) {
        ErrorMayQuit("Function Calls: must return a value", 0, 0);
    }

    if (opts) {
        CALL_0ARGS(PopOptions);
    }

    return result;
}


/****************************************************************************
**
*F  ExecProccallOpts( <call> ). . execute a procedure call with options
**
**  Calls with options are wrapped in an outer statement, which is
**  handled here
*/


static ExecStatus ExecProccallOpts(Stat call)
{
    Expr opts = READ_STAT(call, 0);
    Expr real_call = READ_STAT(call, 1);
    UInt type = TNUM_STAT(real_call);
    GAP_ASSERT(/*STAT_PROCCALL_0ARGS <= type && */type <= STAT_PROCCALL_XARGS);
    UInt narg = (type - STAT_PROCCALL_0ARGS);

    EvalOrExecCall(1, narg, real_call, opts);

    return STATUS_END;
}


static ExecStatus ExecProccall0args(Stat call)
{
    EvalOrExecCall(1, 0, call, 0);
    return STATUS_END;
}

static ExecStatus ExecProccall1args(Stat call)
{
    EvalOrExecCall(1, 1, call, 0);
    return STATUS_END;
}

static ExecStatus ExecProccall2args(Stat call)
{
    EvalOrExecCall(1, 2, call, 0);
    return STATUS_END;
}

static ExecStatus ExecProccall3args(Stat call)
{
    EvalOrExecCall(1, 3, call, 0);
    return STATUS_END;
}

static ExecStatus ExecProccall4args(Stat call)
{
    EvalOrExecCall(1, 4, call, 0);
    return STATUS_END;
}

static ExecStatus ExecProccall5args(Stat call)
{
    EvalOrExecCall(1, 5, call, 0);
    return STATUS_END;
}

static ExecStatus ExecProccall6args(Stat call)
{
    EvalOrExecCall(1, 6, call, 0);
    return STATUS_END;
}

static ExecStatus ExecProccallXargs(Stat call)
{
    // pass in 7 (instead of NARG_SIZE_CALL(SIZE_STAT(call)))
    // to allow the compiler to perform better optimizations
    // (as we know that the number of arguments is >= 7 here)
    EvalOrExecCall(1, 7, call, 0);
    return STATUS_END;
}

/****************************************************************************
**
*F  EvalFunccallOpts( <call> ). . evaluate a function call with options
**
**  Calls with options are wrapped in an outer statement, which is
**  handled here
*/


static Obj EvalFunccallOpts(Expr call)
{
    Expr opts = READ_STAT(call, 0);
    Expr real_call = READ_STAT(call, 1);
    UInt type = TNUM_STAT(real_call);
    GAP_ASSERT(EXPR_FUNCCALL_0ARGS <= type && type <= EXPR_FUNCCALL_XARGS);
    UInt narg = (type - EXPR_FUNCCALL_0ARGS);
    return EvalOrExecCall(0, narg, real_call, opts);
}


/****************************************************************************
**
*F  EvalFunccall0args(<call>)  . . execute a function call with 0    arguments
*F  EvalFunccall1args(<call>)  . . execute a function call with 1    arguments
*F  EvalFunccall2args(<call>)  . . execute a function call with 2    arguments
*F  EvalFunccall3args(<call>)  . . execute a function call with 3    arguments
*F  EvalFunccall4args(<call>)  . . execute a function call with 4    arguments
*F  EvalFunccall5args(<call>)  . . execute a function call with 5    arguments
*F  EvalFunccall6args(<call>)  . . execute a function call with 6    arguments
*F  EvalFunccallXargs(<call>)  . . execute a function call with more arguments
**
**  'EvalFunccall<i>args'  executes  a     function call   to   the  function
**  'FUNC_CALL(<call>)'    with  the   arguments    'ARGI_CALL(<call>,1)'  to
**  'ARGI_CALL(<call>,<i>)'.  It returns the value returned by the function.
*/


static Obj EvalFunccall0args(Expr call)
{
    return EvalOrExecCall(0, 0, call, 0);
}

static Obj EvalFunccall1args(Expr call)
{
    return EvalOrExecCall(0, 1, call, 0);
}

static Obj EvalFunccall2args(Expr call)
{
    return EvalOrExecCall(0, 2, call, 0);
}

static Obj EvalFunccall3args(Expr call)
{
    return EvalOrExecCall(0, 3, call, 0);
}

static Obj EvalFunccall4args(Expr call)
{
    return EvalOrExecCall(0, 4, call, 0);
}

static Obj EvalFunccall5args(Expr call)
{
    return EvalOrExecCall(0, 5, call, 0);
}

static Obj EvalFunccall6args(Expr call)
{
    return EvalOrExecCall(0, 6, call, 0);
}

static Obj EvalFunccallXargs(Expr call)
{
    // pass in 7 (instead of NARG_SIZE_CALL(SIZE_EXPR(call)))
    // to allow the compiler to perform better optimizations
    // (as we know that the number of arguments is >= 7 here)
    return EvalOrExecCall(0, 7, call, 0);
}



/****************************************************************************
**
*F  DoExecFunc0args(<func>)  . . . .  interpret a function with 0    arguments
*F  DoExecFunc1args(<func>,<arg1>) .  interpret a function with 1    arguments
*F  DoExecFunc2args(<func>,<arg1>...) interpret a function with 2    arguments
*F  DoExecFunc3args(<func>,<arg1>...) interpret a function with 3    arguments
*F  DoExecFunc4args(<func>,<arg1>...) interpret a function with 4    arguments
*F  DoExecFunc5args(<func>,<arg1>...) interpret a function with 5    arguments
*F  DoExecFunc6args(<func>,<arg1>...) interpret a function with 6    arguments
*F  DoExecFuncXargs(<func>,<args>) .  interpret a function with more arguments
**
**  'DoExecFunc<i>args' interprets   the function  <func>  that  expects  <i>
**  arguments with the <i> actual argument <arg1>, <arg2>, and so on.  If the
**  function expects more than 4 arguments the actual arguments are passed in
**  the plain list <args>.
**
**  'DoExecFunc<i>args'  is the  handler  for interpreted functions expecting
**  <i> arguments.
**
**  'DoExecFunc<i>args' first switches  to a new  values bag.  Then it enters
**  the arguments <arg1>, <arg2>, and so on in this new  values bag.  Then it
**  executes  the function body.   After  that it  switches back  to  the old
**  values bag.
**
**  Note that these functions are never called directly, they are only called
**  through the function call mechanism.
**
**  The following functions implement the recursion depth control.
**
*/


UInt RecursionTrapInterval;

void RecursionDepthTrap( void )
{
    Int recursionDepth;
    /* in interactive work the RecursionDepth could become slightly negative
     * when quit-ting a higher level brk-loop to a lower level one.
     * Therefore we don't do anything if  RecursionDepth <= 0
    */

    if (GetRecursionDepth() > 0) {
        recursionDepth = GetRecursionDepth();
        SetRecursionDepth(0);
        ErrorReturnVoid("recursion depth trap (%d)", (Int)recursionDepth, 0,
                        "you may 'return;'");
        SetRecursionDepth(recursionDepth);
    }
}

#define CHECK_RECURSION_BEFORE \
            HookedLineIntoFunction(func); \
            CheckRecursionBefore();

#define CHECK_RECURSION_AFTER \
            DecRecursionDepth(); \
            HookedLineOutFunction(func);

#ifdef HPCGAP

#define REMEMBER_LOCKSTACK() \
    int lockSP = TLS(lockStackPointer)

#define CLEAR_LOCK_STACK() \
    if (lockSP != TLS(lockStackPointer)) \
      PopRegionLocks(lockSP)

#endif

#ifdef HPCGAP

static void LockFuncArgs(Obj func, Int narg, const Obj * args)
{
    Int i;
    int count = 0;
    LockMode * mode = alloca(narg * sizeof(int));
    UChar *locks = CHARS_STRING(LCKS_FUNC(func));
    Obj *objects = alloca(narg * sizeof(Obj));
    for (i=0; i<narg; i++) {
      Obj obj = args[i];
      switch (locks[i]) {
      case LOCK_QUAL_READONLY:
          if (CheckReadAccess(obj))
            break;
          mode[count] = LOCK_MODE_READONLY;
          objects[count] = obj;
          count++;
          break;
      case LOCK_QUAL_READWRITE:
          if (CheckWriteAccess(obj))
            break;
          mode[count] = LOCK_MODE_READWRITE;
          objects[count] = obj;
          count++;
          break;
      }
    }
    if (count && LockObjects(count, objects, mode) < 0)
      ErrorMayQuit("Cannot lock arguments of atomic function", 0, 0);
    /* Push at least one region so that we can tell that we are inside
     * an atomic function. */

    if (!count)
      PushRegionLock((Region *) 0);
}

#endif

static ALWAYS_INLINE Obj DoExecFunc(Obj func, Int narg, const Obj *arg)
{
    Bag oldLvars; // old values bag
    Obj result;
    CHECK_RECURSION_BEFORE

#ifdef HPCGAP
    REMEMBER_LOCKSTACK();
    if (LCKS_FUNC(func))
        LockFuncArgs(func, narg, arg);
#endif

    // switch to a new values bag
    oldLvars = SWITCH_TO_NEW_LVARS(func, narg, NLOC_FUNC(func));

    // enter the arguments
    for (Int i = 0; i < narg; i++)
        ASS_LVAR( i+1, arg[i] );

    // execute the statement sequence
    result = EXEC_CURR_FUNC();
#ifdef HPCGAP
    CLEAR_LOCK_STACK();
#endif

    // switch back to the old values bag
    SWITCH_TO_OLD_LVARS_AND_FREE( oldLvars );

    CHECK_RECURSION_AFTER

    return result;
}

static Obj DoExecFunc0args(Obj func)
{
    return DoExecFunc(func, 0, 0);
}

static Obj DoExecFunc1args(Obj func, Obj a1)
{
    Obj arg[] = { a1 };
    return DoExecFunc(func, 1, arg);
}

static Obj DoExecFunc2args(Obj func, Obj a1, Obj a2)
{
    Obj arg[] = { a1, a2 };
    return DoExecFunc(func, 2, arg);
}

static Obj DoExecFunc3args(Obj func, Obj a1, Obj a2, Obj a3)
{
    Obj arg[] = { a1, a2, a3 };
    return DoExecFunc(func, 3, arg);
}

static Obj DoExecFunc4args(Obj func, Obj a1, Obj a2, Obj a3, Obj a4)
{
    Obj arg[] = { a1, a2, a3, a4 };
    return DoExecFunc(func, 4, arg);
}

static Obj DoExecFunc5args(Obj func, Obj a1, Obj a2, Obj a3, Obj a4, Obj a5)
{
    Obj arg[] = { a1, a2, a3, a4, a5 };
    return DoExecFunc(func, 5, arg);
}

static Obj DoExecFunc6args(Obj func, Obj a1, Obj a2, Obj a3, Obj a4, Obj a5, Obj a6)
{
    Obj arg[] = { a1, a2, a3, a4, a5, a6 };
    return DoExecFunc(func, 6, arg);
}

static Obj DoExecFuncXargs(Obj func, Obj args)
{
    Bag  oldLvars; // old values bag
    UInt len;      // number of arguments
    UInt i;        // loop variable
    Obj  result;

    CHECK_RECURSION_BEFORE

    // check the number of arguments
    len = NARG_FUNC( func );
    if (len != LEN_PLIST(args)) {
        ErrorMayQuitNrArgs(len, LEN_PLIST(args));
    }

#ifdef HPCGAP
    REMEMBER_LOCKSTACK();
    if (LCKS_FUNC(func))
        LockFuncArgs(func, len, CONST_ADDR_OBJ(args) + 1);
#endif

    // switch to a new values bag
    oldLvars = SWITCH_TO_NEW_LVARS(func, len, NLOC_FUNC(func));

    // enter the arguments
    for ( i = 1; i <= len; i++ ) {
        ASS_LVAR( i, ELM_PLIST( args, i ) );
    }

    // execute the statement sequence
    result = EXEC_CURR_FUNC();
#ifdef HPCGAP
    CLEAR_LOCK_STACK();
#endif

    // switch back to the old values bag
    SWITCH_TO_OLD_LVARS_AND_FREE( oldLvars );

    CHECK_RECURSION_AFTER

    return result;
}


static Obj DoPartialUnWrapFunc(Obj func, Obj args)
{
    Bag  oldLvars; // old values bag
    UInt named;    // number of arguments
    UInt i;        // loop variable
    UInt len;
    Obj  result;

    CHECK_RECURSION_BEFORE

    named = ((UInt)-NARG_FUNC(func))-1;
    len = LEN_PLIST(args);

    if (named > len) { // Can happen for > 6 arguments
        ErrorMayQuitNrAtLeastArgs(named, len);
    }

#ifdef HPCGAP
    REMEMBER_LOCKSTACK();
    if (LCKS_FUNC(func))
        LockFuncArgs(func, len, CONST_ADDR_OBJ(args) + 1);
#endif

    // switch to a new values bag
    oldLvars = SWITCH_TO_NEW_LVARS(func, named + 1, NLOC_FUNC(func));

    // enter the arguments
    for (i = 1; i <= named; i++) {
      ASS_LVAR(i, ELM_PLIST(args,i));
    }
    for (i = named+1; i <= len; i++) {
      SET_ELM_PLIST(args, i-named, ELM_PLIST(args,i));
    }
    SET_LEN_PLIST(args, len-named);
    ASS_LVAR(named+1, args);

    // execute the statement sequence
    result = EXEC_CURR_FUNC();
#ifdef HPCGAP
    CLEAR_LOCK_STACK();
#endif

    // switch back to the old values bag
    SWITCH_TO_OLD_LVARS_AND_FREE( oldLvars );

    CHECK_RECURSION_AFTER

    return result;
}

/****************************************************************************
**
*F  MakeFunction(<fexp>)  . . . . . . . . . . . . . . . . . . make a function
**
**  'MakeFunction' makes a function from the function expression bag <fexp>.
*/

Obj             MakeFunction (
    Obj                 fexp )
{
    Obj                 func;           // function, result
    ObjFunc             hdlr;           // handler

    if      ( NARG_FUNC(fexp) ==  0 )  hdlr = DoExecFunc0args;
    else if ( NARG_FUNC(fexp) ==  1 )  hdlr = DoExecFunc1args;
    else if ( NARG_FUNC(fexp) ==  2 )  hdlr = DoExecFunc2args;
    else if ( NARG_FUNC(fexp) ==  3 )  hdlr = DoExecFunc3args;
    else if ( NARG_FUNC(fexp) ==  4 )  hdlr = DoExecFunc4args;
    else if ( NARG_FUNC(fexp) ==  5 )  hdlr = DoExecFunc5args;
    else if ( NARG_FUNC(fexp) ==  6 )  hdlr = DoExecFunc6args;
    else if ( NARG_FUNC(fexp) >=  7 )  hdlr = DoExecFuncXargs;
    else if ( NARG_FUNC(fexp) == -1 )  hdlr = DoExecFunc1args;
    else /* NARG_FUNC(fexp) < -1 */    hdlr = DoPartialUnWrapFunc;

    // make the function
    func = NewFunction( NAME_FUNC( fexp ),
                        NARG_FUNC( fexp ), NAMS_FUNC( fexp ),
                        hdlr );

    // install the things an interpreted function needs
    SET_NLOC_FUNC( func, NLOC_FUNC( fexp ) );
    SET_BODY_FUNC( func, BODY_FUNC( fexp ) );
    SET_ENVI_FUNC( func, STATE(CurrLVars) );
    MakeHighVars(STATE(CurrLVars));
#ifdef HPCGAP
    SET_LCKS_FUNC( func, LCKS_FUNC( fexp ) );
#endif

    // return the function
    return func;
}


/****************************************************************************
**
*F  EvalFuncExpr(<expr>)  . . .  evaluate a function expression to a function
**
**  'EvalFuncExpr' evaluates the function expression <expr> to a function.
*/

static Obj EvalFuncExpr(Expr expr)
{
    // get the function expression bag
    Obj fexp = GET_VALUE_FROM_CURRENT_BODY(READ_EXPR(expr, 0));

    // and make the function
    return MakeFunction( fexp );
}


/****************************************************************************
**
*F  PrintFuncExpr(<expr>) . . . . . . . . . . . . print a function expression
**
**  'PrintFuncExpr' prints a function expression.
*/

static void PrintFuncExpr(Expr expr)
{
    // get the function expression bag
    Obj fexp = GET_VALUE_FROM_CURRENT_BODY(READ_EXPR(expr, 0));
    PrintObj( fexp );
}


/****************************************************************************
**
*F  PrintProccall(<call>) . . . . . . . . . . . . . .  print a procedure call
**
**  'PrintProccall' prints a procedure call.
*/

static void PrintFunccall(Expr call);

static void PrintFunccallOpts(Expr call);

static void PrintProccall(Stat call)
{
    PrintFunccall( call );
    Pr(";", 0, 0);
}

static void PrintProccallOpts(Stat call)
{
    PrintFunccallOpts( call );
    Pr(";", 0, 0);
}


/****************************************************************************
**
*F  PrintFunccall(<call>) . . . . . . . . . . . . . . . print a function call
**
**  'PrintFunccall' prints a function call.
*/

static void            PrintFunccall1 (
    Expr                call )
{
    UInt                i;              // loop variable

    // print the expression that should evaluate to a function
    Pr("%2>", 0, 0);
    PrintExpr( FUNC_CALL(call) );

    // print the opening parenthesis
    Pr("%<( %>", 0, 0);

    // print the expressions that evaluate to the actual arguments
    for ( i = 1; i <= NARG_SIZE_CALL( SIZE_EXPR(call) ); i++ ) {
        PrintExpr( ARGI_CALL(call,i) );
        if ( i != NARG_SIZE_CALL( SIZE_EXPR(call) ) ) {
            Pr("%<, %>", 0, 0);
        }
    }
}

static void PrintFunccall(Expr call)
{
  PrintFunccall1( call );

  // print the closing parenthesis
  Pr(" %2<)", 0, 0);
}


static void PrintFunccallOpts(Expr call)
{
    PrintFunccall1(READ_STAT(call, 1));
    Pr(" :%2> ", 0, 0);
    PrintRecExpr1(READ_STAT(call, 0));
    Pr(" %4<)", 0, 0);
}


/****************************************************************************
**
*F  FuncSetRecursionTrapInterval( <self>, <interval> )
**
*/


static Obj FuncSetRecursionTrapInterval(Obj self, Obj interval)
{
    if (!IS_INTOBJ(interval) || INT_INTOBJ(interval) <= 5)
        RequireArgument(SELF_NAME, interval,
                        "must be a small integer greater than 5");
    RecursionTrapInterval = INT_INTOBJ(interval);
    return 0;
}

static Obj FuncGetRecursionDepth(Obj self)
{
    return INTOBJ_INT(GetRecursionDepth());
}

/****************************************************************************
**
*F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * *
*/


/****************************************************************************
**
*V  GVarFuncs . . . . . . . . . . . . . . . . . . list of functions to export
*/

static StructGVarFunc GVarFuncs [] = {

    GVAR_FUNC_1ARGS(SetRecursionTrapInterval, interval),
    GVAR_FUNC_0ARGS(GetRecursionDepth),
    { 0, 0, 0, 0, 0 }


};

/****************************************************************************
**
*F  InitLibrary( <module> ) . . . . . . .  initialise library data structures
*/

static Int InitLibrary (
    StructInitInfo *    module )
{
    // init filters and functions
    InitGVarFuncsFromTable( GVarFuncs );


    return 0;
}


/****************************************************************************
**
*F  InitKernel( <module> )  . . . . . . . . initialise kernel data structures
*/

static Int InitKernel (
    StructInitInfo *    module )
{
    RecursionTrapInterval = 5000;

    // Register the handler for our exported function
    InitHdlrFuncsFromTable( GVarFuncs );

    // Import some functions from the library
    ImportFuncFromLibrary( "PushOptions", &PushOptions );
    ImportFuncFromLibrary( "PopOptions",  &PopOptions  );

    // use short cookies to save space in saved workspace
    InitHandlerFunc( DoExecFunc0args, "i0");
    InitHandlerFunc( DoExecFunc1args, "i1");
    InitHandlerFunc( DoExecFunc2args, "i2");
    InitHandlerFunc( DoExecFunc3args, "i3");
    InitHandlerFunc( DoExecFunc4args, "i4");
    InitHandlerFunc( DoExecFunc5args, "i5");
    InitHandlerFunc( DoExecFunc6args, "i6");
    InitHandlerFunc( DoExecFuncXargs, "iX");
    InitHandlerFunc( DoPartialUnWrapFunc, "pUW");

    // install the evaluators and executors
    InstallExecStatFunc( STAT_PROCCALL_0ARGS , ExecProccall0args);
    InstallExecStatFunc( STAT_PROCCALL_1ARGS , ExecProccall1args);
    InstallExecStatFunc( STAT_PROCCALL_2ARGS , ExecProccall2args);
    InstallExecStatFunc( STAT_PROCCALL_3ARGS , ExecProccall3args);
    InstallExecStatFunc( STAT_PROCCALL_4ARGS , ExecProccall4args);
    InstallExecStatFunc( STAT_PROCCALL_5ARGS , ExecProccall5args);
    InstallExecStatFunc( STAT_PROCCALL_6ARGS , ExecProccall6args);
    InstallExecStatFunc( STAT_PROCCALL_XARGS , ExecProccallXargs);
    InstallExecStatFunc( STAT_PROCCALL_OPTS  , ExecProccallOpts);

    InstallEvalExprFunc( EXPR_FUNCCALL_0ARGS , EvalFunccall0args);
    InstallEvalExprFunc( EXPR_FUNCCALL_1ARGS , EvalFunccall1args);
    InstallEvalExprFunc( EXPR_FUNCCALL_2ARGS , EvalFunccall2args);
    InstallEvalExprFunc( EXPR_FUNCCALL_3ARGS , EvalFunccall3args);
    InstallEvalExprFunc( EXPR_FUNCCALL_4ARGS , EvalFunccall4args);
    InstallEvalExprFunc( EXPR_FUNCCALL_5ARGS , EvalFunccall5args);
    InstallEvalExprFunc( EXPR_FUNCCALL_6ARGS , EvalFunccall6args);
    InstallEvalExprFunc( EXPR_FUNCCALL_XARGS , EvalFunccallXargs);
    InstallEvalExprFunc( EXPR_FUNCCALL_OPTS  , EvalFunccallOpts);
    InstallEvalExprFunc( EXPR_FUNC      , EvalFuncExpr);

    // install the printers
    InstallPrintStatFunc( STAT_PROCCALL_0ARGS , PrintProccall);
    InstallPrintStatFunc( STAT_PROCCALL_1ARGS , PrintProccall);
    InstallPrintStatFunc( STAT_PROCCALL_2ARGS , PrintProccall);
    InstallPrintStatFunc( STAT_PROCCALL_3ARGS , PrintProccall);
    InstallPrintStatFunc( STAT_PROCCALL_4ARGS , PrintProccall);
    InstallPrintStatFunc( STAT_PROCCALL_5ARGS , PrintProccall);
    InstallPrintStatFunc( STAT_PROCCALL_6ARGS , PrintProccall);
    InstallPrintStatFunc( STAT_PROCCALL_XARGS , PrintProccall);
    InstallPrintStatFunc( STAT_PROCCALL_OPTS  , PrintProccallOpts);
    InstallPrintExprFunc( EXPR_FUNCCALL_0ARGS , PrintFunccall);
    InstallPrintExprFunc( EXPR_FUNCCALL_1ARGS , PrintFunccall);
    InstallPrintExprFunc( EXPR_FUNCCALL_2ARGS , PrintFunccall);
    InstallPrintExprFunc( EXPR_FUNCCALL_3ARGS , PrintFunccall);
    InstallPrintExprFunc( EXPR_FUNCCALL_4ARGS , PrintFunccall);
    InstallPrintExprFunc( EXPR_FUNCCALL_5ARGS , PrintFunccall);
    InstallPrintExprFunc( EXPR_FUNCCALL_6ARGS , PrintFunccall);
    InstallPrintExprFunc( EXPR_FUNCCALL_XARGS , PrintFunccall);
    InstallPrintExprFunc( EXPR_FUNCCALL_OPTS  , PrintFunccallOpts);
    InstallPrintExprFunc( EXPR_FUNC      , PrintFuncExpr);

    return 0;
}

static Int InitModuleState(void)
{
    FuncsState()->RecursionDepth = 0;

    return 0;
}

/****************************************************************************
**
*F  InitInfoFuncs() . . . . . . . . . . . . . . . . . table of init functions
*/

static StructInitInfo module = {
    // init struct using C99 designated initializers; for a full list of
    // fields, please refer to the definition of StructInitInfo
    .type = MODULE_BUILTIN,
    .name = "funcs",
    .initKernel = InitKernel,
    .initLibrary = InitLibrary,

    .moduleStateSize = sizeof(struct FuncsModuleState),
    .moduleStateOffsetPtr = &FuncsStateOffset,
    .initModuleState = InitModuleState,
};

StructInitInfo * InitInfoFuncs ( void )
{
    return &module;
}

92%


¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.