1.0.2 • Published 1 year ago
nv-facutil-recur-ctx v1.0.2
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