public EarleStackFrameExecutor(EarleFunction function, EarleStackFrame parentFrame, int callerIp,
     EarleValue target,
     IEarleRuntimeScope superScope, EarleDictionary locals)
     : base(target)
 {
     Frame = parentFrame.SpawnChild(function, this, callerIp);
     Scopes.Push(new EarleRuntimeScope(superScope, locals));
 }
Пример #2
0
        public virtual bool SetValue(string name, EarleValue value)
        {
            if ((_superScope?.GetValue(name) ?? EarleValue.Undefined).HasValue)
            {
                return _superScope.SetValue(name, value);
            }

            if (CanAssignVariableInScope(name))
            {
                _locals[name] = value;
                return true;
            }

            return false;
        }
Пример #3
0
        public virtual IEarleStackFrameExecutor CreateFrameExecutor(EarleStackFrame parentFrame, int callerIp,
            EarleValue target, EarleValue[] arguments)
        {
            if (arguments == null) throw new ArgumentNullException(nameof(arguments));
            var locals = new EarleDictionary();

            var index = 0;

            if (Parameters == null)
            {
                throw new Exception("Parameters cannot be null in order for a EarleStackFrameExecutor to be created.");
            }
            foreach (var parameter in Parameters)
            {
                locals[parameter] = index >= arguments.Length ? EarleValue.Undefined : arguments[index];
                index++;
            }

            return new EarleStackFrameExecutor(this, parentFrame, callerIp, target, File, locals);
        }
Пример #4
0
        /// <summary>
        ///     Creates the frame executor this instruction will invoke.
        /// </summary>
        /// <param name="superFrame">The super frame.</param>
        /// <param name="callerIp">The caller ip.</param>
        /// <returns>The newly created stack frame executor.</returns>
        protected virtual IEarleStackFrameExecutor CreateFrameExecutor(EarleStackFrame superFrame, int callerIp)
        {
            var argumentCount = GetInt32();

            var funcValue = Pop();

            // Pop the arguments of the stack.
            var args = new EarleValue[argumentCount];
            for (var i = 0; i < argumentCount; i++)
                args[argumentCount - 1 - i] = Pop();

            // Pop the call target of the stack.
            var target = HasTarget ? Pop() : EarleValue.Undefined;

            // Find the function to call.
            var function = funcValue.As<EarleFunctionCollection>()?.GetBestOverload(argumentCount)
                           ?? funcValue.As<EarleFunction>();

            // If no function was specified, show an error and push NULL onto the stack instead of the result.
            if (function == null)
            {
                // Throw a tailored warning.
                if (funcValue.As<EarleFunctionCollection>()?.Any() ?? false)
                    Frame.Runtime.HandleWarning(
                        $"No suitable overload can be found of `{funcValue.As<EarleFunctionCollection>().FirstOrDefault()?.Name}`.");
                else if (funcValue.As<EarleFunctionCollection>()?.Any() ?? false)
                    Frame.Runtime.HandleWarning("No suitable overload can be found.");
                else if (!funcValue.HasValue)
                    Frame.Runtime.HandleWarning("A null pointer cannot be invoked.");
                else
                    Frame.Runtime.HandleWarning($"{funcValue.Value?.GetType()} cannot be invoked.");

                // Push NULL onto the stack to as the result.
                Push(EarleValue.Undefined);
                return null;
            }

            // Create the frame executor of the function.
            return function.CreateFrameExecutor(superFrame, callerIp, target, args);
        }
Пример #5
0
        public EarleValue? Invoke(EarleCompletionHandler completionHandler, EarleValue target, params EarleValue[] args)
        {
            var thread = new EarleThread(completionHandler);
            var rootFrame = new EarleStackFrame(File.Runtime, null, null, EarleStackFrame.RootFrameIP, null, thread);
            var frame = CreateFrameExecutor(rootFrame, EarleStackFrame.RootCallIP, target,
                args?.ToArray() ?? new EarleValue[0]);
            thread.AttachExecutor(frame);

            return thread.Run();
        }
Пример #6
0
 private static bool IsDefined(EarleValue value)
 {
     return value.Value != null;
 }
        public virtual bool SetValue(string name, EarleValue value)
        {
            if (name == "self" || name == "thread")
            {
                Frame.Runtime.HandleWarning($"'{name}' cannot be set!");
                return false;
            }

            return Scopes.Peek().SetValue(name, value);
        }
 public EarleBaseStackFrameExecutor(EarleValue target)
 {
     Target = target;
 }
Пример #9
0
 public void SetField(string name, EarleValue value)
 {
     // Values cannot be set.
 }
 /// <summary>
 ///     Runs the specified unary operator.
 /// </summary>
 /// <param name="operator">The operator to run.</param>
 /// <param name="value">The value.</param>
 /// <returns>The result of the operation.</returns>
 public EarleValue RunUnaryOperator(OpCode @operator, EarleValue value)
 {
     Func<EarleValue, EarleValue> func;
     return _unaryOperators.TryGetValue(new Tuple<OpCode, Type>(@operator, value.Value?.GetType()), out func)
         ? func(value)
         : EarleValue.Undefined;
 }
        /// <summary>
        ///     Runs the specified binary operator.
        /// </summary>
        /// <param name="operator">The operator to run.</param>
        /// <param name="left">The left value.</param>
        /// <param name="right">The right value.</param>
        /// <returns>The result of the operation.</returns>
        public EarleValue RunBinaryOperator(OpCode @operator, EarleValue left, EarleValue right)
        {
            Tuple<bool, Func<EarleValue, EarleValue, EarleValue>> op;
            if (
                !_binaryOperators.TryGetValue(
                    new Tuple<OpCode, Type, Type>(@operator, left.Value?.GetType(), right.Value?.GetType()), out op) &&
                !_binaryOperators.TryGetValue(new Tuple<OpCode, Type, Type>(@operator, null, right.Value?.GetType()),
                    out op) &&
                !_binaryOperators.TryGetValue(new Tuple<OpCode, Type, Type>(@operator, left.Value?.GetType(), null),
                    out op))
                return EarleValue.Undefined;

            if (op.Item1)
            {
                var tmp = left;
                left = right;
                right = tmp;
            }
            return op.Item2(left, right);
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="EarleEventNotifyEventArgs" /> class.
 /// </summary>
 /// <param name="eventName">Name of the event.</param>
 /// <param name="firer">The firer of the event.</param>
 public EarleEventNotifyEventArgs(string eventName, EarleValue firer)
 {
     EventName = eventName;
     Firer = firer;
 }
 private static void Notify(EarleStackFrame frame, string eventName, EarleValue[] optionals)
 {
     GetManager(frame, "notify")
         ?.Notify(eventName, optionals?.FirstOrDefault() ?? EarleValue.Undefined);
 }
 /// <summary>
 ///     Called when an event is fired.
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="e">The <see cref="EarleEventNotifyEventArgs" /> instance containing the event data.</param>
 private void OnEventFired(object sender, EarleEventNotifyEventArgs e)
 {
     if (e.EventName == _eventName)
     {
         _hasFired = true;
         _firer = e.Firer;
     }
 }
            /// <summary>
            ///     Initializes a new instance of the <see cref="WaitTillStackFrameExecutor" /> class.
            /// </summary>
            /// <param name="parentFrame">The parent frame.</param>
            /// <param name="target">The target.</param>
            /// <param name="eventManager">The event manager.</param>
            /// <param name="eventName">Name of the event.</param>
            /// <exception cref="System.ArgumentNullException">
            ///     Thrown if <see cref="eventManager" /> or <see cref="eventName" /> is
            ///     null.
            /// </exception>
            public WaitTillStackFrameExecutor(EarleStackFrame parentFrame, EarleValue target,
                IEarleEventManager eventManager,
                string eventName)
                : base(target)
            {
                if (eventManager == null)
                    throw new ArgumentNullException(nameof(eventManager));
                if (eventName == null)
                    throw new ArgumentNullException(nameof(eventName));

                Frame = parentFrame.SpawnChild(null, this, EarleStackFrame.SleepCallIP);

                _eventName = eventName;
                eventManager.EventFired += OnEventFired;
            }