Example #1
0
        /// <summary>
        /// Called when the item is a function definition item.
        /// </summary>
        /// <param name="target">The object that was passed to IParseItem.Visit.</param>
        /// <returns>The passed target or a modification of it.</returns>
        /// <exception cref="System.ArgumentNullException">If target is null.</exception>
        public IParseItem Visit(FuncDefItem target)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            var gen = compiler.CurrentGenerator;

            ChunkBuilder.VarDefinition field = null;
            string name  = null;
            bool   store = false;

            if (target.Local)
            {
                // local function definition.
                if (target.InstanceName != null)
                {
                    throw new SyntaxException(Resources.InstanceLocalMethod, target.Debug);
                }
                if (!(target.Prefix is NameItem))
                {
                    throw new SyntaxException(Resources.IndexerLocalMethod, target.Debug);
                }

                NameItem namei = (NameItem)target.Prefix;
                name  = namei.Name;
                field = compiler.DefineLocal(namei);
                field.StartSet();
            }
            else if (target.Prefix != null)
            {
                if (target.InstanceName != null)
                {
                    // instance function definition.
                    name = null;
                    if (target.Prefix is NameItem)
                    {
                        name = ((NameItem)target.Prefix).Name;
                    }
                    else
                    {
                        name = (string)((LiteralItem)((IndexerItem)target.Prefix).Expression).Value;
                    }
                    name += ":" + target.InstanceName;

                    // {Prefix}.SetIndex({InstanceName}, {ImplementFunction(..)})
                    target.Prefix.Accept(this);
                    gen.Emit(OpCodes.Ldarg_1);
                    gen.Emit(OpCodes.Callvirt, typeof(ILuaEnvironment).GetProperty(nameof(ILuaEnvironment.Runtime)).GetGetMethod());
                    gen.Emit(OpCodes.Ldstr, target.InstanceName);
                    gen.Emit(OpCodes.Callvirt, typeof(ILuaRuntime).GetMethod(nameof(ILuaRuntime.CreateValue)));
                    store = true;
                }
                else if (target.Prefix is IndexerItem)
                {
                    // global function definition with indexer
                    // {Prefix}.SetIndex({Expression}, {ImplementFunction(..)})
                    IndexerItem index = (IndexerItem)target.Prefix;
                    name = (string)((LiteralItem)index.Expression).Value;
                    index.Prefix.Accept(this);
                    index.Expression.Accept(this);
                    store = true;
                }
                else
                {
                    // global function definition with name
                    name  = ((NameItem)target.Prefix).Name;
                    field = compiler.FindVariable((NameItem)target.Prefix);
                    field.StartSet();
                }
            }

            compiler.ImplementFunction(this, target, name);

            if (field != null)
            {
                field.EndSet();
            }
            else if (store)
            {
                gen.Emit(OpCodes.Callvirt, typeof(ILuaValue).GetMethod(nameof(ILuaValue.SetIndex)));
            }

            return(target);
        }