/// <summary> /// Run any remaining steps in the chain, otherwise run the continuation. /// </summary> /// <returns>True if all steps in the chain, and the continuation are all successful. False means we're backtracking</returns> protected bool Continue(TextBuffer p, BindingEnvironment e, Continuation k, MethodCallFrame predecessor) { if (Next != null) { return(Next.Try(p, e, k, predecessor)); } return(k == null || k(p, e.Unifications, e.State, predecessor)); }
public static string Expand(this Step.Interpreter.Step step, Module g) { string result = null; step.Try(TextBuffer.NewEmpty(), new BindingEnvironment(g, new MethodCallFrame(null, null, new LogicVariable[0], null, null)), (o, u, s, p) => { result = o.AsString; return(true); }, null); return(result); }
/// <summary> /// Attempt to run this method /// </summary> /// <param name="args">Arguments from the call to the method's task</param> /// <param name="output">Output buffer to write to</param> /// <param name="env">Variable binding information</param> /// <param name="k">Continuation to call if method succeeds</param> /// <param name="pre">Predecessor frame</param> /// <returns>True if the method and its continuation succeeded</returns> public bool Try(object[] args, TextBuffer output, BindingEnvironment env, MethodCallFrame pre, Step.Continuation k) { // Make stack frame for locals var locals = new LogicVariable[LocalVariableNames.Length]; for (var i = 0; i < LocalVariableNames.Length; i++) { locals[i] = new LogicVariable(LocalVariableNames[i]); } var newFrame = new MethodCallFrame(this, env.Unifications, locals, env.Frame, pre); MethodCallFrame.CurrentFrame = newFrame; var newEnv = new BindingEnvironment(env, newFrame); if (newEnv.UnifyArrays(args, ArgumentPattern, out BindingEnvironment finalEnv)) { env.Module.TraceMethod(Module.MethodTraceEvent.Enter, this, args, output, finalEnv); newFrame.BindingsAtCallTime = finalEnv.Unifications; var traceK = env.Module.Trace == null ? k : (newO, newU, newState, predecessor) => { MethodCallFrame.CurrentFrame = newFrame; env.Module.TraceMethod(Module.MethodTraceEvent.Succeed, this, args, newO, new BindingEnvironment(finalEnv, newU, newState)); MethodCallFrame.CurrentFrame = newFrame.Caller; return(k(newO, newU, newState, predecessor)); }; if (StepChain?.Try(output, finalEnv, traceK, newFrame) ?? traceK(output, finalEnv.Unifications, finalEnv.State, newFrame)) { return(true); } } MethodCallFrame.CurrentFrame = newFrame; env.Module.TraceMethod(Module.MethodTraceEvent.MethodFail, this, args, output, finalEnv); return(false); }
bool Succeeds(Step.Interpreter.Step s) { return(s.Try(TextBuffer.NewEmpty(), BindingEnvironment.NewEmpty(), (o, e, ds, p) => true, null)); }