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()); }
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()); }
public override PExpr Visit(IAccessorFrame frame) { if (frame.Expr.IsMember("Message")) { return(frame.SetResult(StringObj.Create(Message))); } return(frame.SetError()); }
public override PExpr Visit(IAccessorFrame frame) { if (frame.Expr.IsMember("$index")) { return(new PExpr(Index)); } return(base.Visit(frame)); }
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()); }
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(); }
public override PExpr SetResult(RuntimeObj result) { IAccessorFrame p = PrevAccessor; if (p != null && !p.IsResolved) { p.SetResult(result); } return(base.SetResult(result)); }
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()); }
/// <summary> /// Returns the next accessor frames in the chain, optionally starting with this frame. /// </summary> /// <param name="this">This frame.</param> /// <param name="withThis">True to start with this accessor.</param> /// <returns>The next accessors in the chain.</returns> public static IEnumerable <IAccessorFrame> NextAccessors(this IAccessorFrame @this, bool withThis = false) { IAccessorFrame n = withThis ? @this : @this.NextAccessor; while (n != null) { yield return(n); n = n.NextAccessor; } }
public override PExpr SetResult(RuntimeObj result) { // NextFrame is actually the PreviousAccessor IAccessorFrame p = NextFrame as IAccessorFrame; if (p != null && !p.IsResolved) { p.SetResult(result); } return(base.SetResult(result)); }
/// <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) { 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()); }
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)); } }
public PExpr SetError(string message = null) { if (message != null) { return(SetResult(new RuntimeError(Expr, message))); } if (NextAccessor != null) { IAccessorFrame deepest = NextAccessor; while (deepest.NextAccessor != null) { deepest = deepest.NextAccessor; } return(SetResult(new RuntimeError(Expr, "Accessor chain not found: " + deepest.Expr.ToString(), true))); } return(SetResult(new RuntimeError(Expr, GetAccessErrorMessage(), true))); }
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)); } }
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)); } }
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()); }
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()); }
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()); }
PExpr FindOrCreatePropertyOrMethod(IAccessorFrame frame, string name) { foreach (var p in _properties) { if (p.Name == name) { return(p.Read(frame)); } } ExternalTypeHandler.IHandler handler; PExpr m = FindOrCreateMethod(frame, name, out handler); if (m.IsUnknown) { Debug.Assert(handler != null && handler.PropertyGetter != null); var prop = new Property(this, handler); _properties.Add(prop); m = prop.Read(frame); } return(m); }
public override PExpr Visit(IAccessorFrame frame) { var s = frame.GetState(c => c .On("AnIntrinsicArray").OnIndex((f, idx) => { if (idx.Type != "number") { return(f.SetError("Number expected.")); } int i = JSSupport.ToInt32(idx.ToDouble()); if (i < 0 || i >= AnIntrinsicArray.Length) { return(f.SetError("Index out of range.")); } return(f.SetResult(CreateNumber(AnIntrinsicArray[i]))); }) .On("An").On("array").On("with").On("one").On("cell").OnIndex((f, idx) => { return(f.SetResult(CreateString("An.array.with.one.cell[] => " + idx.ToString()))); }) .On("array").OnIndex((f, idx) => { throw new CKException("Accessing XXX.array other than 'An.Array' must not be found."); }) .On("Ghost").On("M").OnCall((f, args) => { Console.WriteLine("Ghost.M() called with {0} arguments: {1} (=> returns {0}).", args.Count, String.Join(", ", args.Select(a => a.ToString()))); return(f.SetResult(f.Global.CreateNumber(args.Count))); }) .On("Ghost").On("M").OnIndex((f, idx) => { Console.WriteLine("Ghost.M[{0}] called (=> returns {0}).", JSSupport.ToInt32(idx.ToDouble())); return(f.SetResult(idx)); }) ); return(s == null?base.Visit(frame) : s.Visit()); }
public virtual PExpr Visit( IAccessorFrame frame ) { return frame.SetError(); }
public override PExpr Visit( IAccessorFrame frame ) { var s = frame.GetState( c => c .On( "AnIntrinsicArray" ).OnIndex( ( f, idx ) => { if( idx.Type != "number" ) return f.SetError( "Number expected." ); int i = JSSupport.ToInt32( idx.ToDouble() ); if( i < 0 || i >= AnIntrinsicArray.Length ) return f.SetError( "Index out of range." ); return f.SetResult( CreateNumber( AnIntrinsicArray[i] ) ); } ) .On( "An" ).On( "array" ).On( "with" ).On( "one" ).On( "cell" ).OnIndex( ( f, idx ) => { return f.SetResult( CreateString( "An.array.with.one.cell[] => " + idx.ToString() ) ); } ) .On( "array" ).OnIndex( ( f, idx ) => { throw new CKException( "Accessing XXX.array other than 'An.Array' must not be found." ); } ) .On( "Ghost" ).On( "M" ).OnCall( ( f, args ) => { Console.WriteLine( "Ghost.M() called with {0} arguments: {1} (=> returns {0}).", args.Count, String.Join( ", ", args.Select( a => a.ToString() )) ); return f.SetResult( f.Global.CreateNumber( args.Count ) ); } ) .On( "Ghost" ).On( "M" ).OnIndex( ( f, idx ) => { Console.WriteLine( "Ghost.M[{0}] called (=> returns {0}).", JSSupport.ToInt32( idx.ToDouble() ) ); return f.SetResult( idx ); } ) ); return s == null ? base.Visit( frame ) : s.Visit(); }
public override PExpr Visit(IAccessorFrame frame) => _value.Visit(frame);
/// <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 ) { 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(); }
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(); }
public override PExpr Visit(IAccessorFrame frame) { return(frame.SetError()); }
public virtual PExpr Visit(IAccessorFrame frame) => frame.SetError();
/// <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 virtual PExpr Visit(IAccessorFrame frame) { return(frame.SetError()); }
public override PExpr Visit( IAccessorFrame frame ) { if( frame.Expr.IsMember( "message" ) ) return frame.SetResult( frame.Global.CreateString( Message ) ); return frame.SetError(); }
public override PExpr Visit( IAccessorFrame frame ) { return frame.SetError(); }
public override PExpr Visit( IAccessorFrame frame ) { return _value.Visit( frame ); }
public override PExpr Visit(IAccessorFrame frame) { return(_value.Visit(frame)); }