From be652c204f5fb6faf3f64127bf6512c163fba78f Mon Sep 17 00:00:00 2001 From: xypwn <54681180+xypwn@users.noreply.github.com> Date: Sat, 27 Jul 2024 01:44:51 +0200 Subject: [PATCH] Add CallFunctionArgsN Allows calling funcs with more than 4 and exactly 3 args. Also unifies CallFunctionXX funcs. --- evaldo/evaldo.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/evaldo/evaldo.go b/evaldo/evaldo.go index 8cca6e47..7c9fa5d5 100644 --- a/evaldo/evaldo.go +++ b/evaldo/evaldo.go @@ -806,6 +806,65 @@ func CallFunctionArgs4(fn env.Function, ps *env.ProgramState, arg0 env.Object, a return ps } +func CallFunctionArgsN(fn env.Function, ps *env.ProgramState, ctx *env.RyeCtx, args ...env.Object) *env.ProgramState { + var fnCtx *env.RyeCtx + env0 := ps.Ctx // store reference to current env in local + if ctx != nil { // called via contextpath and this is the context + if fn.Pure { + fnCtx = env.NewEnv(ps.PCtx) + } else { + if fn.Ctx != nil { // if context was defined at definition time, pass it as parent. + fn.Ctx.Parent = ctx + fnCtx = env.NewEnv(fn.Ctx) + } else { + fnCtx = env.NewEnv(ctx) + } + } + } else { + if fn.Pure { + fnCtx = env.NewEnv(ps.PCtx) + } else { + if fn.Ctx != nil { // if context was defined at definition time, pass it as parent. + // Q: Would we want to pass it directly at any point? + // Maybe to remove need of creating new contexts, for reuse, of to be able to modify it? + fnCtx = env.NewEnv(fn.Ctx) + } else { + fnCtx = env.NewEnv(env0) + } + } + } + if checkErrorReturnFlag(ps) { + return ps + } + for i, arg := range args { + index := fn.Spec.Series.Get(i).(env.Word).Index + fnCtx.Set(index, arg) + } + // TRY + psX := env.NewProgramState(fn.Body.Series, ps.Idx) + psX.Ctx = fnCtx + psX.PCtx = ps.PCtx + psX.Gen = ps.Gen + + // END TRY + var result *env.ProgramState + ps.Ser.SetPos(0) + if len(args) > 0 { + result = EvalBlockInj(psX, args[0], true) + } else { + result = EvalBlock(psX) + } + MaybeDisplayFailureOrError(result, result.Idx) + if result.ForcedResult != nil { + ps.Res = result.ForcedResult + result.ForcedResult = nil + } else { + ps.Res = result.Res + } + ps.ReturnFlag = false + return ps +} + func CallBuiltin(bi env.Builtin, ps *env.ProgramState, arg0_ env.Object, toLeft bool, pipeSecond bool, firstVal env.Object) *env.ProgramState { ////args := make([]env.Object, bi.Argsn) /*pospos := ps.Ser.GetPos()