Exemple #1
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);
            }
        }
Exemple #2
0
 public static void DoFormat(RCOperator op,
                             StringBuilder builder,
                             RCFormat args,
                             RCColmap
                             colmap,
                             int level)
 {
     if (op.Left != null)
     {
         if (op.Left.IsOperator)
         {
             builder.Append("(");
             op.Left.Format(builder, args, colmap, level);
             builder.Append(")");
         }
         else
         {
             op.Left.Format(builder, args, colmap, level);
         }
         builder.Append(" ");
     }
     op.BodyToString(builder, args, level);
     builder.Append(" ");
     // Note Right is not allowed to be null.
     op.Right.Format(builder, args, colmap, level);
 }
Exemple #3
0
 // Kicks off evaluation for an operator and its arguments.
 public static void DoEval(RCRunner runner, RCClosure closure, RCOperator op)
 {
     if (op.Left == null)
     {
         if (closure.Index == 0)
         {
             EvalArgument(runner, closure, op.Right);
         }
         else
         {
             op.EvalOperator(runner, closure);
         }
     }
     else
     {
         if (closure.Index == 0)
         {
             EvalArgument(runner, closure, op.Left);
         }
         else if (closure.Index == 1)
         {
             EvalArgument(runner, closure, op.Right);
         }
         else
         {
             op.EvalOperator(runner, closure);
         }
     }
 }
Exemple #4
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);
 }
Exemple #5
0
        public void EvalEval(RCRunner runner, RCClosure closure, RCOperator right)
        {
            RCClosure parent = new RCClosure(closure.Parent,
                                             closure.Bot,
                                             right,
                                             closure.Left,
                                             RCBlock.Empty,
                                             0);

            DoEval(runner, parent, right);
        }
Exemple #6
0
        public static RCException Overload(RCClosure closure,
                                           RCOperator op,
                                           RCValue left,
                                           RCValue
                                           right)
        {
            string message = string.Format(DYADIC_OVERLOAD_FORMAT,
                                           op.Name,
                                           left.TypeName,
                                           right.TypeName);

            return(new RCException(closure, RCErrors.Type, message));
        }
Exemple #7
0
 public static bool DoIsLastCall(RCClosure closure,
                                 RCClosure arg,
                                 RCOperator op)
 {
     if (closure.Index == 1)
     {
         return(op.Left == null);
     }
     else
     {
         return(closure.Index == 2);
     }
 }
Exemple #8
0
        public static void WriteOperator(RCArray <byte> result, RCOperator op)
        {
            // Pre-order traversal of the expression tree.
            result.Write((byte)'o');
            int count = op.Left == null ? 2 : 3;

            WriteScalarInt(result, count);
            if (op.Left != null)
            {
                op.Left.ToByte(result);
            }
            Binary.WriteScalarString(op.Name, result);
            op.Right.ToByte(result);
        }
Exemple #9
0
        protected static RCClosure OwnerOpOf(RCOperator op,
                                             RCClosure closure,
                                             out RCClosure child)
        {
            child = closure;
            RCClosure current = closure.Parent;

            while (current != null && !current.Code.ArgumentEval)
            {
                child   = current;
                current = current.Parent;
            }
            return(current);
        }
Exemple #10
0
        protected static RCClosure NextParentOf(RCOperator op,
                                                RCClosure previous,
                                                out RCValue userop,
                                                out RCArray <RCBlock> useropContext)
        {
            // The only operator with IsHigherOrder set is switch.
            // Why is switch magical, why not each, take, fiber, etc...
            // Am I just missing tests for those?
            userop        = null;
            useropContext = previous.UserOpContext;
            RCClosure argument0, argument1;
            bool      recursion = false;

            if (previous.Parent == null)
            {
                return(previous.Parent);
            }
            recursion = CheckForRecursion(op, previous, ref userop, ref useropContext);
            if (!recursion)
            {
                return(previous.Parent);
            }
            RCClosure parent0 = OwnerOpOf(op, previous, out argument0);

            if (parent0 == null)
            {
                return(previous.Parent);
            }
            if (!parent0.Code.IsLastCall(parent0, argument0))
            {
                if (!recursion)
                {
                    return(previous.Parent);
                }
            }
            RCClosure parent1 = OwnerOpOf(op, parent0, out argument1);

            if (parent1 == null)
            {
                // parent1 is null when there is no switch in the last line.
                return(previous.Parent);
            }
            if (!parent1.Code.IsLastCall(parent1, argument1))
            {
                return(previous.Parent);
            }
            return(parent1.Parent);
        }
Exemple #11
0
        public RCOperator New(string op, RCValue left, RCValue right)
        {
            string     key    = op;
            RCOperator result = null;

            if (!_operator.ContainsKey(key))
            {
                result = new RCUserOperator(new RCReference(op));
                result.Init(op, left, right);
            }
            else
            {
                Type type = _operator[op];
                // This is a tiny optimization, avoids using reflection
                // if we are only going to call the base class RCOperator ctor.
                // But I would like to note that I am ok with New on operators being
                // slightly expensive because it will generally only happen during
                // parsing or macro expansion which are both expensive anyhow.
                if (type == typeof(RCOperator))
                {
                    result = new RCOperator();
                    result.Init(op, left, right);
                }
                else if (type.IsSubclassOf(typeof(RCOperator)))
                {
                    ConstructorInfo ctor = type.GetConstructor(_ctor);
                    if (ctor == null)
                    {
                        throw new Exception("No zero argument constructor found on type " + type);
                    }
                    result = (RCOperator)ctor.Invoke(null);
                    result.Init(op, left, right);
                }
            }
            return(result);
        }
Exemple #12
0
        public static bool DoIsBeforeLastCall(RCClosure closure, RCOperator op)
        {
            return(false);
            // We now check explicitly for the tail recursive case
            // This means less need to worry about "last call" status
            // RCUserOperator is the only place where this operation might return true now.
            // There is never a need to eliminate the tail stack frame in the case of a
            // built-in.
            // Still I don't feel quite ready to excise all of this "last call" code.
            // We will save that until the production system is ready.
            // So that we can do a full and proper regression.
            // It's possible there is something I'm missing.

            /*
             * if (closure.Index == 0)
             * {
             * return op.Left == null;
             * }
             * else
             * {
             * return closure.Index == 1;
             * }
             */
        }
Exemple #13
0
        public static void DoEvalOperator(RCRunner runner, RCClosure closure, RCOperator op)
        {
            RCValue left   = closure.Result.Get("0");
            RCValue right  = closure.Result.Get("1");
            RCValue virtop = Resolve(null, closure, new RCArray <string> (op.Name), null, true);

            if (virtop != null)
            {
                RCClosure parent = UserOpClosure(closure, virtop, null, noClimb: false);
                virtop.Eval(runner, parent);
                return;
            }
            if (left == null)
            {
                RCSystem.Activator.Invoke(runner, closure, op.Name, right);
            }
            else
            {
                RCSystem.Activator.Invoke(runner, closure, op.Name, left, right);
            }
            // A lot of good men died to bring us this one line of code...
            // Let's keep this around as a memorial.
            // right.BindRight (runner, closure, this, left);
        }
Exemple #14
0
        public void ToString(StringBuilder builder, int indent, bool firstOnTop)
        {
            RCClosure      closure = this;
            Stack <string> lines   = new Stack <string> ();

            // Do not include the global namespace in the stack trace.
            while (closure != null && closure.Parent != null)
            {
                if (closure.Code != null)
                {
                    RCOperator op = closure.Code as RCOperator;
                    if (op != null)
                    {
                        lines.Push(string.Format("-- {0}", op.ToString()));
                    }
                }
                RCBlock result = closure.Result;
                while (result != null)
                {
                    if (result.Value != null)
                    {
                        RCCube acube = result.Value as RCCube;
                        if (acube != null)
                        {
                            string value = acube.FlatPack().Format(RCFormat.Default);
                            lines.Push(value);
                        }
                        else
                        {
                            string value = result.Value.Format(RCFormat.Default);
                            value = string.Format("{0}:{1}", result.Name, value);
                            value = value.Substring(0, Math.Min(80, value.Length));
                            lines.Push(value);
                        }
                    }
                    result = result.Previous;
                }
                closure = closure.Parent;
            }
            if (firstOnTop)
            {
                builder.AppendFormat("--- BEGIN STACK (bot:{0},fiber:{1},lines:{2}) ---\n",
                                     closure.Bot,
                                     closure.Fiber,
                                     lines.Count);
                while (lines.Count > 0)
                {
                    builder.AppendLine(lines.Pop());
                }
                builder.AppendFormat("--- END STACK ---\n");
            }
            else
            {
                builder.AppendFormat("--- END STACK (bot:{0},fiber:{1},lines:{2}) ---\n",
                                     closure.Bot,
                                     closure.Fiber,
                                     lines.Count);
                string[] linesInOrder = lines.ToArray();
                for (int i = linesInOrder.Length - 1; i >= 0; --i)
                {
                    builder.AppendLine(linesInOrder[i]);
                }
                builder.AppendFormat("--- BEGIN STACK ---\n");
            }
        }
Exemple #15
0
 // Construct the next closure for an operator.
 public static RCClosure DoNext(RCOperator op,
                                RCRunner runner,
                                RCClosure head,
                                RCClosure previous,
                                RCValue result)
 {
     if (op.Left == null)
     {
         if (previous.Index == 0)
         {
             RCValue           userop;
             RCArray <RCBlock> useropContext;
             RCClosure         nextParentOf = NextParentOf(op, previous, out userop, out useropContext);
             RCClosure         next         = new RCClosure(nextParentOf,
                                                            head.Bot,
                                                            op,
                                                            previous.Left,
                                                            new RCBlock(null, "1", ":", result),
                                                            previous.Index + 1,
                                                            userop,
                                                            useropContext);
             return(next);
         }
         else if (previous.Index == 1 && previous.Parent != null)
         {
             return(previous.Parent.Code.Next(runner,
                                              head == null ? previous : head,
                                              previous.Parent,
                                              result));
         }
         else
         {
             return(null);
         }
     }
     else
     {
         if (previous.Index == 0)
         {
             return(new RCClosure(previous.Parent,
                                  head.Bot,
                                  op,
                                  result,
                                  previous.Result,
                                  previous.Index + 1,
                                  previous.UserOp,
                                  previous.UserOpContext));
         }
         else if (previous.Index == 1)
         {
             RCValue           userop;
             RCArray <RCBlock> useropContext;
             RCClosure         next = new RCClosure(NextParentOf(op,
                                                                 previous,
                                                                 out userop,
                                                                 out
                                                                 useropContext),
                                                    head.Bot,
                                                    op,
                                                    // reset "pocket" left to null.
                                                    null,
                                                    // fold it into the current context for the
                                                    // final eval.
                                                    new RCBlock(new RCBlock(null, "0", ":", previous.Left),
                                                                "1",
                                                                ":",
                                                                result),
                                                    previous.Index + 1,
                                                    userop,
                                                    useropContext);
             return(next);
         }
         else if (previous.Index == 2 && previous.Parent != null)
         {
             return(previous.Parent.Code.Next(runner,
                                              head == null ? previous : head,
                                              previous.Parent,
                                              result));
         }
         else if (previous.Parent != null && previous.Parent.Parent != null)
         {
             return(previous.Parent.Parent.Code.Next(runner,
                                                     head == null ? previous : head,
                                                     previous.Parent.Parent,
                                                     result));
         }
         else
         {
             return(null);
         }
     }
 }
Exemple #16
0
        public void EvalEval(RCRunner runner, RCClosure closure, RCBlock left, RCOperator right)
        {
            RCClosure parent = UserOpClosure(closure, right, new RCArray <RCBlock> (left), noClimb: true);

            DoEval(runner, parent, right);
        }
Exemple #17
0
        public void EvalApply(RCRunner runner, RCClosure closure, RCOperator left, object right)
        {
            RCClosure parent = UserOpClosure(closure, left, null, null, (RCValue)right);

            DoEval(runner, parent, left);
        }