Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Assign a value to a field
        /// </summary>
        /// <param name="tree">Tree to be executed</param>
        /// <param name="value">Value to be set</param>
        private void FieldAssign(KermitAST tree, KObject value)
        {
            KermitAST leftExpr = (KermitAST)tree.GetChild(0);
            KermitAST field    = (KermitAST)tree.GetChild(1);
            KObject   obj      = Execute(leftExpr);
            bool      isTree   = tree.Type == KermitParser.INDEX || field.Type == KermitParser.INDEX;

            if (field.Type == KermitParser.INDEX)
            {
                obj   = obj.GetInnerField(field.GetChild(0).Text);
                field = (KermitAST)field.GetChild(1);
            }

            if (isTree)
            {
                object fieldValue = Execute(field).Value;
                if (obj is KArray)
                {
                    ((KArray)obj)[(int)fieldValue] = value;
                }
                else
                {
                    object     real    = obj.Value;
                    Type       objType = real.GetType();
                    MethodInfo info    = objType.GetMethod("set_Item");
                    if (info != null)
                    {
                        info.Invoke(real, new[] { fieldValue, value.Value });
                    }
                    else
                    {
                        ThrowHelper.AttributeError($"{leftExpr.Text} is not asignable", StackTrace);
                    }
                }
            }
            else if (tree.Type == KermitParser.DOT)
            {
                string name = field.Text;
                if (!obj.SetInnerField(name, value))
                {
                    ThrowHelper.NoFieldError(obj.Value.GetType().Name, name, StackTrace);
                }
            }
        }