1.0.2 • Published 1 year ago

nv-facutil-recur-ctx v1.0.2

Weekly downloads
-
License
ISC
Repository
-
Last release
1 year ago

nv-facutil-recur-ctx

  • to avoid using recursive-function-call, coz consteval recursion-function in compile-time is hard(especially for indirect/non-tail )
  • nvlang has a compile-feature to convert recursive-function-call to while+ctx, this is to simulate/test that

install

  • npm install nv-facutil-recur-ctx

usage

  const {creat}   = require("nv-facutil-recur-ctx");
  const {run,gen} = require("nv-facutil-recur-ctx").sss;  

example

run

creat ctx

        > var ctx = creat();
        >

prepare 3 handles

    > var open_handle = (ctx) => {
            ctx.curr  = ctx.pprev + ctx.prev;
            ctx.pprev = ctx.prev;
            ctx.prev  = ctx.curr;
        }
    > 
    > var should_rtrn_handle = (ctx)=> {
           let cond = (ctx.c_ === ctx.max_depth);   //ctx.c_ is the current_depth ,readonly
           return(cond) 
        }
    > 
    > 
    > var clos_handle = (ctx) => {
            ctx.curr  = undefined;
        }
    >

init inputs

        > ctx.init({
               pprev       : 0,
               prev        : 1,
               curr        : undefined,
               max_depth   : 10
            });
        > 
        > ctx
        _Ctx { pprev: 0, prev: 1, curr: undefined, max_depth: 10 }
        > 

run to complete

            > ctx = run(
                   ctx,
                   open_handle,
                   should_rtrn_handle,
                   clos_handle
                )
            _Ctx { pprev: 55, prev: 89, curr: undefined, max_depth: 10 }
            >
             

return

    > ctx.rtrn()
    { pprev: 55, prev: 89, curr: undefined, max_depth: 10 }
    > 
    > ctx
    _Ctx {}
    > 

tail mode

    var clos_handle = (ctx) => {
        ctx.curr  = undefined;
        ctx._break();    //tail recur mode
                         //'_break can-only-be used in clos_handle
    }


    ctx.init({
       pprev       : 0,
       prev        : 1,
       curr        : undefined,
       max_depth   : 10
    });

    var g = gen(
       ctx,
       open_handle,
       should_rtrn_handle,
       clos_handle
    )

    > g.next().value
    _Ctx { pprev: 1, prev: 1, curr: 1, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 1, prev: 2, curr: 2, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 2, prev: 3, curr: 3, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 3, prev: 5, curr: 5, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 5, prev: 8, curr: 8, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 8, prev: 13, curr: 13, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 13, prev: 21, curr: 21, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 21, prev: 34, curr: 34, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 34, prev: 55, curr: 55, max_depth: 10 }
    > g.next().value
    _Ctx { pprev: 55, prev: 89, curr: 89, max_depth: 10 }
    > g.next().value
    undefined

    > ctx
    _Ctx { pprev: 55, prev: 89, curr: undefined, max_depth: 10 }
    > ctx.rtrn()
    { pprev: 55, prev: 89, curr: undefined, max_depth: 10 }
    >
    > ctx
    _Ctx {}
    >

METHODS

        ctx._break                  -- can ONLY be used in clos_handle, to simulate tail-recursion 
        ctx._is_breaked 
        
        
        ctx._is_opening             -- simulate push frame stack stage 
        ctx._is_closing             -- simulate pop  frame stack stage
         
        ctx.c_                      -- READONLY current recursion-depth
                      
          
          
        ctx.init                    -- input args         
        ctx.rtrn                    -- simulate ret 

APIS

    run(ctx,open_handle,should_rtrn_handle,clos_handle) -> Ctx
    gen(ctx,open_handle,should_rtrn_handle,clos_handle) -> Generator<
            #if<
                #anyof<*_handle>#is<async_t> 
            > <
                async_generator_t
            > #else <
                sync_generator_t
            >
    >
    


    {
      _dflt: {
        DFLT_OPEN_S_HANDLE: [Function: DFLT_OPEN_S_HANDLE],
        DFLT_SHOULD_RTRN_S_HANDLE: [Function: DFLT_SHOULD_RTRN_S_HANDLE],
        DFLT_CLOS_S_HANDLE: [Function: DFLT_CLOS_S_HANDLE],
        DFLT_OPEN_A_HANDLE: [AsyncFunction: DFLT_OPEN_A_HANDLE],
        DFLT_SHOULD_RTRN_A_HANDLE: [AsyncFunction: DFLT_SHOULD_RTRN_A_HANDLE],
        DFLT_CLOS_A_HANDLE: [AsyncFunction: DFLT_CLOS_A_HANDLE]
      },
      creat_ctx: [Function (anonymous)],
      sss: { run: [Function: run], gen: [GeneratorFunction: gen] },
      ssa: { run: [AsyncFunction: run], gen: [AsyncGeneratorFunction: gen] },
      sas: { run: [AsyncFunction: run], gen: [AsyncGeneratorFunction: gen] },
      saa: { run: [AsyncFunction: run], gen: [AsyncGeneratorFunction: gen] },
      ass: { run: [AsyncFunction: run], gen: [AsyncGeneratorFunction: gen] },
      asa: { run: [AsyncFunction: run], gen: [AsyncGeneratorFunction: gen] },
      aas: { run: [AsyncFunction: run], gen: [AsyncGeneratorFunction: gen] },
      aaa: { run: [AsyncFunction: run], gen: [AsyncGeneratorFunction: gen] }
    }

     sss means : [【Sync】open_handle, 【Sync】should_rtrn_handle, 【Sync】clos_handle ]
     ssa means : [【Sync】open_handle, 【Sync】should_rtrn_handle, 【Async】clos_handle ]
        ..

LICENSE

  • ISC
1.0.2

1 year ago