コード例 #1
0
 public override RCClosure Next(RCRunner runner,
                                RCClosure tail,
                                RCClosure previous,
                                RCValue result)
 {
     return(RCL.Kernel.Eval.DoNext(this, runner, tail, previous, result));
 }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
 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);
 }
コード例 #6
0
 public static RCClosure UserOpClosure(RCClosure previous,
                                       RCValue code,
                                       RCArray <RCBlock> @this,
                                       bool noClimb)
 {
     return(UserOpClosure(previous, code, @this, null, null, noClimb));
 }
コード例 #7
0
        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);
        }
コード例 #8
0
 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);
 }
コード例 #9
0
        public virtual RCOperator AsOperator(RCActivator activator, RCValue left, RCValue right)
        {
            RCOperator result = new RCInlineOperator(this);

            result.Init("", left, right);
            return(result);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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));
        }
コード例 #12
0
        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);
        }
コード例 #13
0
 public RCInlineOperator(RCValue code)
 {
     if (code == null)
     {
         throw new ArgumentNullException("code");
     }
     _code = code;
 }
コード例 #14
0
 public RCOperator New(string op, RCValue left, RCValue right)
 {
     if (right == null)
     {
         throw new ArgumentNullException("R");
     }
     return(RCSystem.Activator.New(op, left, right));
 }
コード例 #15
0
 public static RCClosure UserOpClosure(RCClosure previous,
                                       RCValue code,
                                       RCArray <RCBlock> @this,
                                       RCValue left,
                                       RCValue right)
 {
     return(UserOpClosure(previous, code, @this, left, right, noClimb: false));
 }
コード例 #16
0
        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));
        }
コード例 #17
0
 protected void PushInlineDyadicOperator()
 {
     if (_left != null)
     {
         _lefts.Peek().Push(_left);
         _left = null;
     }
 }
コード例 #18
0
        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));
        }
コード例 #19
0
 public RCClosure(RCClosure parent,
                  long bot,
                  RCValue code,
                  RCValue left,
                  RCBlock result,
                  int index)
     : this(parent, bot, code, left, result, index, null, null)
 {
 }
コード例 #20
0
 protected void AppendChild(RCValue scalar)
 {
     _value = new RCBlock(_value, _name, ":", scalar);
     if (_state == JSONState.Value)
     {
         _name  = "";
         _state = JSONState.Name;
     }
 }
コード例 #21
0
 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);
     }
 }
コード例 #22
0
 protected void PushInlineMonadicOperator()
 {
     if (_result != null && _maybeOperator == null && _result is RCBlock)
     {
         _operators.Peek().Push(_result);
         _maybeOperator = null;
         _left          = null;
     }
 }
コード例 #23
0
        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));
            }
        }
コード例 #24
0
        public string RepString(string code)
        {
            RCValue result = Rep(code, restoreStateOnError: false);

            if (result == null)
            {
                return("");
            }
            return(result.Format(RCFormat.DefaultNoT));
        }
コード例 #25
0
 public virtual RCClosure Handle(RCRunner runner,
                                 RCClosure closure,
                                 Exception exception,
                                 long
                                 status,
                                 out RCValue handled)
 {
     handled = null;
     return(null);
 }
コード例 #26
0
        public virtual RCValue Edit(RCRunner runner, RCValueDelegate editor)
        {
            RCValue edit = editor(this);

            if (edit != null)
            {
                return(edit);
            }
            return(null);
        }
コード例 #27
0
        public RCValue Get(string name, RCValue @default)
        {
            RCValue actual = Get(name);

            if (actual == null)
            {
                actual = @default;
            }
            return(actual);
        }
コード例 #28
0
 protected void PushArgument()
 {
     // Any right argument that was already created must
     // actually be a left argument.
     if (_result != null)
     {
         _left   = _result;
         _result = null;
     }
 }
コード例 #29
0
        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);
        }
コード例 #30
0
 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;
     }
 }