Beispiel #1
0
 public override PExpr Visit(IAccessorFrame frame)
 {
     if (frame.Expr is AccessorCallExpr cE)
     {
     }
     else if (frame.Expr is AccessorMemberExpr mE)
     {
         bool funcRequired = frame.NextAccessor != null && frame.NextAccessor.Expr is AccessorCallExpr;
         if (funcRequired)
         {
             ExternalTypeHandler.IHandler handler;
             PExpr m = FindOrCreateMethod(frame, mE.Name, out handler);
             if (m.IsUnknown)
             {
                 m = frame.SetError($"Member {mE.Name} on '{_o.GetType().FullName}' is not a function.");
             }
             return(m);
         }
         else
         {
             return(FindOrCreatePropertyOrMethod(frame, mE.Name));
         }
     }
     return(frame.SetError());
 }
Beispiel #2
0
        private PExpr FindOrCreateMethod(IAccessorFrame frame, string name, out ExternalTypeHandler.IHandler handler)
        {
            handler = null;
            foreach (var m in _methods)
            {
                if (m.Name == name)
                {
                    return(frame.SetResult(m));
                }
            }
            ExternalTypeHandler type = _context.FindType(_o.GetType());

            if (type == null)
            {
                return(frame.SetError($"Unhandled type '{_o.GetType().FullName}'."));
            }
            handler = type.GetHandler(name);
            if (handler == null)
            {
                return(frame.SetError($"Missing member {name} on '{_o.GetType().FullName}'."));
            }
            if (handler.PropertyGetter == null)
            {
                var meth = new Method(this, handler);
                _methods.Add(meth);
                return(frame.SetResult(meth));
            }
            return(new PExpr());
        }
        /// <summary>
        /// Default implementation of <see cref="IAccessorVisitor.Visit"/> that supports evaluation of intrinsic
        /// functions Number(), String(), Boolean().
        /// By overriding this any binding to to external objects can be achieved (recall to call this base
        /// method when overriding).
        /// </summary>
        /// <param name="frame">The current frame (gives access to the next frame if any).</param>
        public virtual PExpr Visit(IAccessorFrame frame)
        {
            IAccessorMemberFrame head = frame as IAccessorMemberFrame;

            // We can only handle member access at the root level:
            if (head == null)
            {
                return(frame.SetError());
            }

            // Lookup from the longest path to the head in registered objects:
            // more "precise" objects mask root ones.
            var deepestMemberFrame = frame.NextAccessors(true)
                                     .Select(f => f as IAccessorMemberFrame)
                                     .TakeWhile(f => f != null)
                                     .LastOrDefault();

            // We obtain at least the head, hence the do...while.
            do
            {
                RuntimeObj obj;
                if (_objects.TryGetValue(deepestMemberFrame.Expr.MemberFullName, out obj))
                {
                    return(deepestMemberFrame.SetResult(obj));
                }
                deepestMemberFrame = deepestMemberFrame.PrevMemberAccessor;
            }while(deepestMemberFrame != null);
            var s = frame.GetImplementationState(c =>
                                                 c.On("Number").OnCall((f, args) =>
            {
                if (args.Count == 0)
                {
                    return(f.SetResult(DoubleObj.Zero));
                }
                return(f.SetResult(args[0] as DoubleObj ?? DoubleObj.Create(args[0].ToDouble())));
            }
                                                                       )
                                                 .On("String").OnCall((f, args) =>
            {
                if (args.Count == 0)
                {
                    return(f.SetResult(StringObj.EmptyString));
                }
                return(f.SetResult(StringObj.Create(args[0].ToString())));
            })
                                                 .On("Boolean").OnCall((f, args) =>
            {
                return(f.SetResult(args.Count == 1 && args[0].ToBoolean() ? BooleanObj.True : BooleanObj.False));
            })
                                                 );

            return(s != null?s.Visit() : frame.SetError());
        }
 public override PExpr Visit(IAccessorFrame frame)
 {
     if (frame.Expr.IsMember("Message"))
     {
         return(frame.SetResult(StringObj.Create(Message)));
     }
     return(frame.SetError());
 }
Beispiel #5
0
 public override PExpr Visit(IAccessorFrame frame)
 {
     if (frame.Expr is AccessorCallExpr)
     {
         EvalVisitor.AccessorFrame f = (EvalVisitor.AccessorFrame)frame;
         return(f._visitor.Run(new EvalVisitor.FunctionExprFrame(f, _expr, _closures)));
     }
     return(frame.SetError());
 }
Beispiel #6
0
 PExpr DoCall(IAccessorFrame frame, IReadOnlyList <RuntimeObj> parameters)
 {
     try
     {
         var m = _handler.FindMethod(_eo._context, parameters);
         if (m.Method == null)
         {
             return(frame.SetError($"Method {_handler.Name} can not be called with {parameters.Count} parameters."));
         }
         object result = m.Method.Invoke(_eo._o, m.Parameters);
         return(m.Method.ReturnType == typeof(void)
                 ? frame.SetResult(RuntimeObj.Undefined)
                 : frame.SetResult(_eo._context.Create(result)));
     }
     catch (Exception ex)
     {
         return(frame.SetError(ex.Message));
     }
 }
Beispiel #7
0
        public override PExpr Visit(IAccessorFrame frame)
        {
            var s = frame.GetState(c =>
                                   c.On("toString").OnCall((f, args) =>
            {
                return(f.SetResult(f.Global.CreateString(JSSupport.ToString(_value))));
            }
                                                           ));

            return(s != null?s.Visit() : frame.SetError());
        }
Beispiel #8
0
            public override PExpr Visit(IAccessorFrame frame)
            {
                AccessorCallExpr cE = frame.Expr as AccessorCallExpr;

                if (cE != null)
                {
                    var s = frame.GetCallState(cE.Arguments, DoCall);
                    if (s != null)
                    {
                        return(s.Visit());
                    }
                }
                return(frame.SetError());
            }
Beispiel #9
0
 PExpr DoCall(IAccessorFrame frame, IReadOnlyList <RuntimeObj> parameters)
 {
     try
     {
         object[] p      = MapCallParameters(frame.Global, parameters, _parameters);
         object   result = _function.DynamicInvoke(p);
         return(_function.GetMethodInfo().ReturnType == typeof(void)
                 ? frame.SetResult(RuntimeObj.Undefined)
                 : frame.SetResult(frame.Global.Create(result)));
     }
     catch (Exception ex)
     {
         return(frame.SetError(ex.Message));
     }
 }
Beispiel #10
0
 internal PExpr Read(IAccessorFrame frame)
 {
     try
     {
         object[]   index = null;
         object     val   = _handler.PropertyGetter(_eo._o, index);
         RuntimeObj obj   = val == _eo ? _eo : frame.Global.Create(val);
         if (_handler.PropertySetter != null)
         {
             base.SetValue(frame.Expr, obj);
             return(frame.SetResult(this));
         }
         return(frame.SetResult(obj));
     }
     catch (Exception ex)
     {
         return(frame.SetError(ex.Message));
     }
 }
Beispiel #11
0
        public override PExpr Visit(IAccessorFrame frame)
        {
            var s = frame.GetState(c =>
                                   c.On("charAt").OnCall((f, args) =>
            {
                int idx = args.Count > 0 ? JSSupport.ToInt32(args[0].ToDouble()) : 0;
                if (idx < 0 || idx >= _value.Length)
                {
                    return(f.SetResult(JSEvalString.EmptyString));
                }
                return(f.SetResult(f.Global.CreateString(new String(_value[idx], 1))));
            })
                                   .On("toString").OnCall((f, args) =>
            {
                return(f.SetResult(this));
            }
                                                          ));

            return(s != null?s.Visit() : frame.SetError());
        }
Beispiel #12
0
        public override PExpr Visit(IAccessorFrame frame)
        {
            var s = frame.GetState(c =>
                                   c.On("toString").OnCall((f, args) =>
            {
                int radix = 10;
                if (args.Count == 1)
                {
                    radix = JSSupport.ToInt32(args[0].ToDouble());
                }
                if (radix < 2 || radix > 36)
                {
                    return(f.SetError("Radix must be between 2 and 36."));
                }
                return(f.SetResult(f.Global.CreateString(JSSupport.ToString(_value, radix))));
            }
                                                           ));

            return(s != null?s.Visit() : frame.SetError());
        }
Beispiel #13
0
        public override PExpr Visit(IAccessorFrame frame)
        {
            var s = frame.GetImplementationState(c =>
                                                 c.OnIndex((f, arg) =>
            {
                int idx = JSSupport.ToInt32(arg.ToDouble());
                if (idx < 0 || idx >= _value.Length)
                {
                    return(f.SetResult(EmptyString));
                }
                return(f.SetResult(Create(new string( _value[idx], 1 ))));
            })
                                                 .On("ToString").OnCall((f, args) =>
            {
                return(f.SetResult(this));
            }
                                                                        ));

            return(s != null?s.Visit() : frame.SetError());
        }
Beispiel #14
0
 public virtual PExpr Visit( IAccessorFrame frame )
 {
     return frame.SetError();
 }
Beispiel #15
0
 public override PExpr Visit( IAccessorFrame frame )
 {
     return frame.SetError();
 }
Beispiel #16
0
        /// <summary>
        /// Default implementation of <see cref="IAccessorVisitor.Visit"/> that supports evaluation of intrinsic 
        /// functions Number(), String(), Boolean() and Date().
        /// By overriding this any binding to to external objects can be achieved (recall to call this base
        /// method when overriding).
        /// </summary>
        /// <param name="frame">The current frame (gives access to the next frame if any).</param>
        public virtual PExpr Visit( IAccessorFrame frame )
        {
            var s = frame.GetState( c =>
                c.On( "Number" ).OnCall( ( f, args ) =>
                {
                    if( args.Count == 0 ) return f.SetResult( JSEvalNumber.Zero );
                    return f.SetResult( CreateNumber( args[0] ) );
                }
                )
                .On( "String" ).OnCall( ( f, args ) =>
                {
                    if( args.Count == 0 ) return f.SetResult( JSEvalString.EmptyString );
                    return f.SetResult( CreateString( args[0] ) );

                } )
                .On( "Boolean" ).OnCall( ( f, args ) =>
                {
                    if( args.Count == 0 ) return f.SetResult( JSEvalBoolean.False );
                    return f.SetResult( CreateBoolean( args[0] ) );
                } )
                .On( "Date" ).OnCall( ( f, args ) =>
                {
                    try
                    {
                        int[] p = new int[7];
                        for( int i = 0; i < args.Count; ++i )
                        {
                            p[i] = (int)args[i].ToDouble();
                            if( p[i] < 0 ) p[i] = 0;
                        }
                        if( p[0] > 9999 ) p[0] = 9999;
                        if( p[1] < 1 ) p[1] = 1;
                        else if( p[1] > 12 ) p[1] = 12;
                        if( p[2] < 1 ) p[2] = 1;
                        else if( p[2] > 31 ) p[2] = 31;
                        DateTime d = new DateTime( p[0], p[1], p[2], p[3], p[4], p[5], p[6], DateTimeKind.Utc );
                        return f.SetResult( CreateDateTime( d ) );
                    }
                    catch( Exception ex )
                    {
                        return f.SetError( ex.Message );
                    }
                } )
            );
            return s != null ? s.Visit() : frame.SetError();
        }
Beispiel #17
0
 public override PExpr Visit( IAccessorFrame frame )
 {
     if( frame.Expr.IsMember( "message" ) ) return frame.SetResult( frame.Global.CreateString( Message ) );
     return frame.SetError();
 }
Beispiel #18
0
        /// <summary>
        /// Default implementation of <see cref="IAccessorVisitor.Visit"/> that supports evaluation of intrinsic
        /// functions Number(), String(), Boolean() and Date().
        /// By overriding this any binding to to external objects can be achieved (recall to call this base
        /// method when overriding).
        /// </summary>
        /// <param name="frame">The current frame (gives access to the next frame if any).</param>
        public virtual PExpr Visit(IAccessorFrame frame)
        {
            var s = frame.GetState(c =>
                                   c.On("Number").OnCall((f, args) =>
            {
                if (args.Count == 0)
                {
                    return(f.SetResult(JSEvalNumber.Zero));
                }
                return(f.SetResult(CreateNumber(args[0])));
            }
                                                         )
                                   .On("String").OnCall((f, args) =>
            {
                if (args.Count == 0)
                {
                    return(f.SetResult(JSEvalString.EmptyString));
                }
                return(f.SetResult(CreateString(args[0])));
            })
                                   .On("Boolean").OnCall((f, args) =>
            {
                if (args.Count == 0)
                {
                    return(f.SetResult(JSEvalBoolean.False));
                }
                return(f.SetResult(CreateBoolean(args[0])));
            })
                                   .On("Date").OnCall((f, args) =>
            {
                try
                {
                    int[] p = new int[7];
                    for (int i = 0; i < args.Count; ++i)
                    {
                        p[i] = (int)args[i].ToDouble();
                        if (p[i] < 0)
                        {
                            p[i] = 0;
                        }
                    }
                    if (p[0] > 9999)
                    {
                        p[0] = 9999;
                    }
                    if (p[1] < 1)
                    {
                        p[1] = 1;
                    }
                    else if (p[1] > 12)
                    {
                        p[1] = 12;
                    }
                    if (p[2] < 1)
                    {
                        p[2] = 1;
                    }
                    else if (p[2] > 31)
                    {
                        p[2] = 31;
                    }
                    DateTime d = new DateTime(p[0], p[1], p[2], p[3], p[4], p[5], p[6], DateTimeKind.Utc);
                    return(f.SetResult(CreateDateTime(d)));
                }
                catch (Exception ex)
                {
                    return(f.SetError(ex.Message));
                }
            })
                                   );

            return(s != null?s.Visit() : frame.SetError());
        }
 public override PExpr Visit( IAccessorFrame frame )
 {
     if( frame.Expr is AccessorCallExpr )
     {
         EvalVisitor.AccessorFrame f = (EvalVisitor.AccessorFrame)frame;
         return f._visitor.Run( new EvalVisitor.FunctionExprFrame( f, _expr, _closures ) );
     }
     return frame.SetError();
 }
Beispiel #20
0
 public override PExpr Visit( IAccessorFrame frame )
 {
     var s = frame.GetState( c =>
         c.On("toString").OnCall( (f,args) =>
         {
             int radix = 10;
             if( args.Count == 1 ) radix = JSSupport.ToInt32( args[0].ToDouble() );
             if( radix < 2 || radix > 36 ) return f.SetError( "Radix must be between 2 and 36." );
             return f.SetResult( f.Global.CreateString( JSSupport.ToString( _value, radix ) ) );
         }
         ) );
     return s != null ? s.Visit() : frame.SetError();
 }
Beispiel #21
0
 public virtual PExpr Visit(IAccessorFrame frame) => frame.SetError();
 public override PExpr Visit(IAccessorFrame frame)
 {
     return(frame.SetError());
 }
Beispiel #23
0
 public virtual PExpr Visit(IAccessorFrame frame)
 {
     return(frame.SetError());
 }
Beispiel #24
0
 public override PExpr Visit( IAccessorFrame frame )
 {
     var s = frame.GetState( c =>
         c.On( "charAt" ).OnCall( ( f, args ) =>
         {
             int idx = args.Count > 0 ? JSSupport.ToInt32( args[0].ToDouble() ) : 0;
             if( idx < 0 || idx >= _value.Length ) return f.SetResult( JSEvalString.EmptyString );
             return f.SetResult( f.Global.CreateString( new String( _value[idx], 1 ) ) );
         } )
         .On( "toString" ).OnCall( ( f, args ) =>
         {
             return f.SetResult( this );
         }
         ) );
     return s != null ? s.Visit() : frame.SetError();
 }