public override RCClosure Next(RCRunner runner, RCClosure tail, RCClosure previous, RCValue result) { return(RCL.Kernel.Eval.DoNext(this, runner, tail, previous, result)); }
public override RCValue Edit(RCRunner runner, RCValueDelegate editor) { RCOperator result = (RCOperator)base.Edit(runner, editor); if (result != null) { return(result); } RCValue left = null; if (_left != null) { left = _left.Edit(runner, editor); } RCValue right = _right.Edit(runner, editor); if (left != null || right != null) { if (left == null) { left = _left; } if (right == null) { right = _right; } result = runner.New(_name, left, right); return(result); } else { return(null); } }
public RCValue Get(RCArray <string> name, RCArray <RCBlock> @this) { RCRefable block = this; RCValue value = null; for (int i = 0; i < name.Count; ++i) { value = block.Get(name[i]); block = value as RCRefable; if (block == null) { // if it is the last value return it if (i == name.Count - 1) { return(value); } // if not, something is wrong else { return(null); } } if (@this != null && i < name.Count - 1) { @this.Write((RCBlock)block); } } return(value); }
/// <summary> /// This method creates an identical closure where the left and right /// arguments can be accessed in user space. /// This has to be done by operators that evaluate user provided code. /// </summary> public static RCClosure UserOpClosure(RCClosure previous, RCValue code, RCArray <RCBlock> @this, RCValue left, RCValue right, bool noClimb) { left = left != null ? left : previous.Result.Get("0"); right = right != null ? right : previous.Result.Get("1"); RCBlock result = null; if (@this != null && @this.Count > 0) { result = @this[0]; // This is only for when the this context contains more than one object. // I'm not even sure whether to support this, I guess I should. // But this is not going to be the fastest solution possible. for (int i = 1; i < @this.Count; ++i) { for (int j = 0; j < @this[i].Count; ++j) { RCBlock block = @this[i].GetName(j); result = new RCBlock(result, block.Name, ":", block.Value); } } } if (left == null) { result = new RCBlock(result, "R", ":", right); } else { result = new RCBlock(result, "L", ":", left); result = new RCBlock(result, "R", ":", right); } // Passing code and @this here is important. NextParentOf will look // for the body of the executing function in that variable to detect tail calls. RCClosure replacement = new RCClosure(previous.Bot, previous.Fiber, previous.Locks, previous.Parent, previous.Code, previous.Left, result, previous.Index, code, @this, noClimb, noResolve: false); RCClosure child = new RCClosure(replacement, previous.Bot, code, previous.Left, RCBlock.Empty, 0, code, @this); return(child); }
public override void AcceptEvaluator(RCToken token) { FinishValue(true); MakeExpression(); // When this applies there is no actual opening bracket defining the block. // This happens in the shell. // I call it an "implied" block. if (_block == null) { _block = RCBlock.Empty; } FinishBlock(); if (_maybeOperator != null) { // _maybeOp is not an operator, its a variable. _variable = _maybeOperator; _maybeOperator = null; } if (_variable == null) { // It is an unnamed block. _variable = ""; } // If anything was left over on the right, it doesn't belong here. // Should this be an invalid state for the parser? _result = null; _evaluator = RCEvaluator.For(token.Text); }
public static RCClosure UserOpClosure(RCClosure previous, RCValue code, RCArray <RCBlock> @this, bool noClimb) { return(UserOpClosure(previous, code, @this, null, null, noClimb)); }
public static bool CheckForRecursion(RCValue op, RCClosure previous, ref RCValue userop, ref RCArray <RCBlock> useropContext) { RCUserOperator name = op as RCUserOperator; if (name != null) { PreresolveUserOp(previous, op, ref userop, ref useropContext); RCClosure current = previous.Parent; while (current != null) { RCUserOperator code = current.Code as RCUserOperator; if (code != null) { if (userop == current.UserOp) { // Tail recursion detected return(true); } } current = current.Parent; } } // No tail recursion here return(false); }
public static RCValue DoFinish(RCRunner runner, RCClosure closure, RCValue result) { while (closure != null) { RCBlock obj = closure.Code as RCBlock; if (obj != null) { if (obj.Count > 0 && obj.Evaluator.FinishBlock && result != closure.Code) { result = NextBlock(runner, obj, closure, result); } } RCOperator op = closure.Code as RCOperator; if (op != null) { result = op.Finish(result); } if (closure.Parent != null && (closure.Parent.Bot != closure.Bot || closure.Parent.Fiber != closure.Fiber)) { break; } closure = closure.Parent; } return(result); }
public virtual RCOperator AsOperator(RCActivator activator, RCValue left, RCValue right) { RCOperator result = new RCInlineOperator(this); result.Init("", left, right); return(result); }
public void EvalParse(RCRunner runner, RCClosure closure, RCByte right) { int start = 0; RCValue result = DoParse(RCSystem.Activator, right.Data, ref start); runner.Yield(closure, result); }
public static RCOperator ReadOperator(RCActivator activator, RCArray <byte> data, ref int start) { int count = BitConverter.ToInt32(data._source, start); start += sizeof(int); RCValue left = null; RCValue right = null; string name = null; if (count == 2) { name = Binary.ReadScalarString(data, ref start); right = Binary.DoParse(activator, data, ref start); } else if (count == 3) { left = Binary.DoParse(activator, data, ref start); name = Binary.ReadScalarString(data, ref start); right = Binary.DoParse(activator, data, ref start); } else { throw new Exception("count of an operator must always be 2 or 3."); } return(activator.New(name, left, right)); }
public RCValue Run(RCValue program, bool restoreStateOnError) { // Shouldn't this be an exception? if (program == null) { return(null); } RCBlock wrapper = new RCBlock(RCBlock.Empty, "", "<-", program); RCClosure parent = new RCClosure(_bots[0].Id, 0, null, null, wrapper, null, _state, 0, null, null, noClimb: false, noResolve: false); RCClosure closure = new RCClosure(parent, _bots[0].Id, program, null, RCBlock.Empty, 0, null, null); RCValue result = Run(closure, restoreStateOnError); return(result); }
public RCInlineOperator(RCValue code) { if (code == null) { throw new ArgumentNullException("code"); } _code = code; }
public RCOperator New(string op, RCValue left, RCValue right) { if (right == null) { throw new ArgumentNullException("R"); } return(RCSystem.Activator.New(op, left, right)); }
public static RCClosure UserOpClosure(RCClosure previous, RCValue code, RCArray <RCBlock> @this, RCValue left, RCValue right) { return(UserOpClosure(previous, code, @this, left, right, noClimb: false)); }
public void EvalBinary(RCRunner runner, RCClosure closure, object right) { RCValue val = (RCValue)right; RCArray <byte> result = new RCArray <byte> (); val.ToByte(result); runner.Yield(closure, new RCByte(result)); }
protected void PushInlineDyadicOperator() { if (_left != null) { _lefts.Peek().Push(_left); _left = null; } }
public static RCException Overload(RCClosure closure, string op, object right) { string message = string.Format(MONADIC_OVERLOAD_FORMAT, op, RCValue.TypeNameForType(right.GetType())); return(new RCException(closure, RCErrors.Type, message)); }
public RCClosure(RCClosure parent, long bot, RCValue code, RCValue left, RCBlock result, int index) : this(parent, bot, code, left, result, index, null, null) { }
protected void AppendChild(RCValue scalar) { _value = new RCBlock(_value, _name, ":", scalar); if (_state == JSONState.Value) { _name = ""; _state = JSONState.Name; } }
protected void MakeExpression() { while (_operators.Peek().Count > 0) { RCValue op = _operators.Peek().Pop(); RCValue left = _lefts.Peek().Count > 0 ? _lefts.Peek().Pop() : null; _result = op.AsOperator(_activator, left, _result); } }
protected void PushInlineMonadicOperator() { if (_result != null && _maybeOperator == null && _result is RCBlock) { _operators.Peek().Push(_result); _maybeOperator = null; _left = null; } }
public void CheckName(string name) { RCValue val = Get(name); if (val == null) { throw new Exception(string.Format("The variable '{0}' was not found in this block.", name)); } }
public string RepString(string code) { RCValue result = Rep(code, restoreStateOnError: false); if (result == null) { return(""); } return(result.Format(RCFormat.DefaultNoT)); }
public virtual RCClosure Handle(RCRunner runner, RCClosure closure, Exception exception, long status, out RCValue handled) { handled = null; return(null); }
public virtual RCValue Edit(RCRunner runner, RCValueDelegate editor) { RCValue edit = editor(this); if (edit != null) { return(edit); } return(null); }
public RCValue Get(string name, RCValue @default) { RCValue actual = Get(name); if (actual == null) { actual = @default; } return(actual); }
protected void PushArgument() { // Any right argument that was already created must // actually be a left argument. if (_result != null) { _left = _result; _result = null; } }
public static RCValue Parse(string code, out bool fragment) { RCParser parser = new RCLParser(Activator); RCArray <RCToken> tokens = new RCArray <RCToken> (); parser.Lex(code, tokens); RCValue result = parser.Parse(tokens, out fragment, canonical: false); RCAssert.IsNotNull(result, "The result of parser.Parse() was null."); return(result); }
protected void PushExpression() { // Any symbol seen before this must be an operator. if (_maybeOperator != null) { _operators.Peek().Push(new RCReference(_maybeOperator)); _lefts.Peek().Push(_left); _maybeOperator = null; _left = null; } }