// Kicks off evaluation for a block. public static void DoEval(RCRunner runner, RCClosure closure, RCBlock block) { if (block.Count == 0) { DoYield(runner, closure, block); } else { RCBlock current = block.GetName(closure.Index); if (current.Evaluator.Invoke) { string op = ((RCString)current.Value)[0]; RCSystem.Activator.Invoke(runner, closure, op, closure.Result); } else if (current.Evaluator.Template) { try { RCString result = ExpandTemplate(new StringBuilder(), (RCTemplate)current, closure.Result, 0, ""); runner.Yield(closure, result); } catch (Exception ex) { RCException rcex = new RCException(closure, ex, RCErrors.Native, "An exception was thrown by the template."); runner.Finish(closure, rcex, (int)RCErrors.Native); } } else if (current.Evaluator.Pass) { DoYield(runner, closure, current.Value); } // This means that Value is an operator or a reference. else if (current.Value.ArgumentEval) { current.Value.Eval(runner, new RCClosure(closure, closure.Bot, current.Value, closure.Left, closure.Result, 0)); } else if (current.Evaluator.Return) { DoYield(runner, closure, current.Value); } else { // I need something different to happen when we are at the top level already. // Or maybe I need to inject a wrapper closure when I do Rep this way? if ((closure.Index < block.Count - 1) || (closure.Parent != null)) { DoYield(runner, closure, current.Value); } else { DoYield(runner, closure, current); } } } }
public void Invoke(RCRunner runner, RCClosure closure, string name, object left, object right) { OverloadValue overload; Type ltype = left.GetType(); Type rtype = right.GetType(); Type ctype = right.GetType(); try { if (_dispatch.TryGetValue(new OverloadKey(name, ctype, ltype, rtype), out overload)) { RCBot bot = runner.GetBot(closure.Bot); object state = bot.GetModule(overload.Module); overload.Implementation.Invoke(state, new object[] { runner, closure, left, right }); } else if (_dispatch.TryGetValue(new OverloadKey(name, typeof(object), ltype, rtype), out overload)) { RCBot bot = runner.GetBot(closure.Bot); object state = bot.GetModule(overload.Module); overload.Implementation.Invoke(state, new object[] { runner, closure, left, right }); } else if (_dispatch.TryGetValue(new OverloadKey(name, typeof(object), typeof(object), rtype), out overload)) { RCBot bot = runner.GetBot(closure.Bot); object state = bot.GetModule(overload.Module); overload.Implementation.Invoke(state, new object[] { runner, closure, left, right }); } else if (_dispatch.TryGetValue(new OverloadKey(name, typeof(object), ltype, typeof(object)), out overload)) { RCBot bot = runner.GetBot(closure.Bot); object state = bot.GetModule(overload.Module); overload.Implementation.Invoke(state, new object[] { runner, closure, left, right }); } else if (_dispatch.TryGetValue(new OverloadKey(name, typeof(object), typeof(object), typeof(object)), out overload)) { RCBot bot = runner.GetBot(closure.Bot); object state = bot.GetModule(overload.Module); overload.Implementation.Invoke(state, new object[] { runner, closure, left, right }); } else if (_dispatch.TryGetValue(new OverloadKey(name, typeof(object), ltype, typeof(RCOperator)), out overload)) { RCBot bot = runner.GetBot(closure.Bot); object state = bot.GetModule(overload.Module); overload.Implementation.Invoke(state, new object[] { runner, closure, left, right }); } else { throw RCException.Overload(closure, name, left, right); } } catch (TargetInvocationException tiex) { Exception ex = tiex.GetBaseException(); if (ex is RCException) { throw ex; } else { // You have to pass the tiex, not ex here so that the interior stack trace will // be // preserved when/if it is rethrown. throw new RCException(closure, tiex, RCErrors.Native, ThrowMessage(name, ex)); } } }
public void Record(long bot, long fiber, string type, long instance, string state, object info, bool forceDoc) { if (!Filter(type, state)) { return; } if (_output == null) { return; } if (_level == RCOutput.Quiet) { return; } else if (bot == 0 && instance == 0 && type == "fiber" && (state == "start" || state == "done")) { return; } else if (_level == RCOutput.Single) { string time = DateTime.UtcNow.ToString(TimeFormat); if (info is Exception) { info = "<<Reported>>"; } _output.WriteLine("{0} {1} {2} {3} {4} {5} {6}", time, bot, fiber, type, instance, state, info.ToString()); Debug.WriteLine("{0} {1} {2} {3} {4} {5} {6}", time, bot, fiber, type, instance, state, info.ToString()); } else if (_level == RCOutput.Systemd) { // 0 Emergency: system is unusable // 1 Alert: action must be taken immediately // 2 Critical: critical conditions // 3 Error: error conditions // 4 Warning: warning conditions // 5 Notice: normal but significant condition // 6 Informational: informational messages // 7 Debug: debug-level messages int severity = 6; string message; if (info is Exception) { if (type == "fiber" && state == "killed") { // It's important to use an exception here because this is // a non-standard termination; it relies on the regular process // for non-standard terminations. // But we assume you are killing the fiber because you want it dead, // so it shouldn't be treated like an error. // An important use case is canceling read commands over http severity = 6; } else { severity = 3; } RCException ex = info as RCException; if (ex != null) { message = ex.ToSystemdString(); } else { // If you do it like this it shows more stack but it is hard to read // message = new RCString (info.ToString ()).ToString (); message = info.ToString(); } } else { bool singleLine; message = IndentMessage(CreateMessage(info), false, out singleLine); } _output.WriteLine("<{0}>{1} {2} {3} {4} {5} {6}", severity, bot, fiber, type, instance, state, message); Debug.WriteLine("<{0}>{1} {2} {3} {4} {5} {6}", severity, bot, fiber, type, instance, state, message); } else if (_level == RCOutput.Multi || _level == RCOutput.Full) { DateTime now = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, RCTime.DisplayTimeZone); string time = now.ToString(TimeFormat); bool singleLine; string message = IndentMessage(CreateMessage(info), forceDoc, out singleLine); string optionalSpace = (singleLine && message.Length > 0) ? " " : ""; _output.WriteLine("{0} {1} {2} {3} {4} {5}{6}{7}", time, bot, fiber, type, instance, state, optionalSpace, message); Debug.WriteLine("{0} {1} {2} {3} {4} {5}{6}{7}", time, bot, fiber, type, instance, state, optionalSpace, message); } else if (_level == RCOutput.Clean && type == "print") { string message = CreateMessage(info); _output.WriteLine(message); Debug.WriteLine(message); } else if (_level == RCOutput.Test) { bool singleLine; string message = IndentMessage(CreateMessage(info), forceDoc, out singleLine); string optionalSpace = (singleLine && message.Length > 0) ? " " : ""; _output.WriteLine("{0} {1} {2} {3} {4}{5}{6}", bot, fiber, type, instance, state, optionalSpace, message); Debug.WriteLine("{0} {1} {2} {3} {4}{5}{6}", bot, fiber, type, instance, state, optionalSpace, message); } else if (_level == RCOutput.Trace) { throw new NotImplementedException(); } }