예제 #1
0
        /// <summary>
        /// Load a field of an object
        /// </summary>
        /// <param name="tree">Tree to be executed</param>
        /// <returns>The result of the field</returns>
        private KObject FieldLoad(KermitAST tree)
        {
            KermitAST leftExpr = (KermitAST)tree.GetChild(0);
            KermitAST field    = (KermitAST)tree.GetChild(1);
            KObject   obj      = Execute(leftExpr);
            KObject   val;
            string    name;

            if (field.Type == KermitParser.INDEX)
            {
                field = (KermitAST)field.GetChild(0);
            }

            if (field.Type == KermitParser.CALL)
            {
                name = field.GetChild(0).Text;
                FunctionSpace fSpace     = new FunctionSpace(new FunctionSymbol(leftExpr.Text + "." + name, GlobalScope));
                MemorySpace   savedSpace = _currentSpace;
                _stack.Push(fSpace);
                object[] args = new object[field.ChildCount - 1];
                for (int i = 0; i < args.Length; ++i)
                {
                    KObject ko = Execute((KermitAST)field.GetChild(i + 1));
                    args[i] = obj is KArray ? ko : ko.Value;
                }
                try
                {
                    _currentSpace = fSpace;
                    val           = obj.CallInnerFunction(name, args);
                }
                finally
                {
                    _stack.Pop();
                    _currentSpace = savedSpace;
                }
            }
            else
            {
                name = field.Text;
                val  = obj.GetInnerField(name);
            }

            field = (KermitAST)field.Parent;
            if (field.Type == KermitParser.INDEX)
            {
                KermitAST memberTree = (KermitAST)field.GetChild(1);
                val = LoadItem(val, Execute(memberTree));
                if (val == null)
                {
                    ThrowHelper.TypeError($"'{name}' is not enumerable", StackTrace);
                }
            }

            if (val == null)
            {
                ThrowHelper.NoFieldError(obj.Value.GetType().Name, name, StackTrace);
            }
            return(val);
        }
예제 #2
0
        /// <summary>
        /// Execute a function inside the interpreter
        /// </summary>
        /// <param name="function">Function to be executed</param>
        /// <param name="parameters">Parameters to be passed to a function</param>
        /// <returns>The result of the function</returns>
        public override KObject CallFunction(KFunction function, List <KLocal> parameters)
        {
            FunctionSymbol fSymbol = function.Value;

            FunctionSpace fSpace     = new FunctionSpace(fSymbol);
            MemorySpace   savedSpace = _currentSpace;

            _currentSpace = fSpace;

            if (!function.IsNative)
            {
                parameters.ForEach(x => fSpace[x.Name] = x);
            }

            KObject result = null;

            _stack.Push(fSpace);
            try
            {
                if (function.IsNative)
                {
                    FunctionCallbackInfo cInfo = new FunctionCallbackInfo(parameters, this);
                    ((NativeFunctionSymbol)fSymbol).NativeFunction.SafeExecute(cInfo);
                    result = cInfo.ReturnValue.Value;
                }
                else
                {
                    Execute(fSymbol.BlockAst);
                }
            }
            catch (ReturnValue returnValue)
            {
                result = returnValue.Value;
            }
            finally
            {
                _currentSpace = savedSpace;
            }
            _stack.Pop();
            return(result);
        }