コード例 #1
0
        /// <summary>
        /// Loads a LuaChunk from a pre-loaded string.
        /// </summary>
        /// <param name="chunk">The Lua script to load from.</param>
        /// <param name="name">The name to give the chunk.</param>
        /// <param name="override">True to load the file even if it is in the cache, otherwise false.</param>
        /// <param name="index">Stores the index of the loaded module.</param>
        /// <returns>The loaded chunk.</returns>
        /// <exception cref="System.ArgumentNullException">If chunk is null.</exception>
        /// <exception cref="ModMaker.Lua.Parser.SyntaxException">If there is
        /// syntax errors in the file.</exception>
        public ILuaValue LoadText(string chunk, string name, bool @override, out int index)
        {
            if (chunk == null)
            {
                throw new ArgumentNullException(nameof(chunk));
            }

            lock (this)
            {
                var temp = Environment.Parser.UseCache;
                Environment.Parser.UseCache = !@override;
                var ret = Environment.CodeCompiler.Compile(
                    Environment,
                    PlainParser.Parse(Environment.Parser, chunk, name),
                    name);
                Environment.Parser.UseCache = temp;

                if (!_chunks.Contains(ret))
                {
                    _chunks.Add(ret);
                }
                index = _chunks.IndexOf(ret);
                return(ret);
            }
        }
コード例 #2
0
        /// <summary>
        /// Gets a variables from a given Lua file using the given environment.
        /// </summary>
        /// <param name="env">The environment used to load the chunk.</param>
        /// <param name="path">The path to the Lua file.</param>
        /// <param name="names">The names of the variable to get.</param>
        /// <returns>The values of the variables or null if not found.  The array is
        /// never null.</returns>
        /// <exception cref="System.ArgumentException">If path is not in the
        /// correct format -or- if names contains a null string.</exception>
        /// <exception cref="System.ArgumentNullException">If any arguments are null.</exception>
        /// <exception cref="System.IO.FileNotFoundException">If the given file
        /// could not be found.</exception>
        /// <exception cref="System.InvalidCastException">If one of the variables
        /// could not be converted to the given type.</exception>
        /// <exception cref="ModMaker.Lua.Parser.SyntaxException">If there are
        /// syntax errors in the file.</exception>
        public static T[] GetVariables <T>(ILuaEnvironment env, string path, params string[] names)
        {
            if (names == null)
            {
                throw new ArgumentNullException(nameof(names));
            }

            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (env == null)
            {
                throw new ArgumentNullException(nameof(env));
            }

            if (names.Contains(null))
            {
                throw new ArgumentException(string.Format(Resources.CannotContainNull, nameof(names)));
            }

            path = Path.GetFullPath(path);
            if (!File.Exists(path))
            {
                throw new FileNotFoundException();
            }

            var parsed = PlainParser.Parse(
                env.Parser, File.ReadAllText(path), Path.GetFileNameWithoutExtension(path));
            var ret = env.CodeCompiler.Compile(env, parsed, Path.GetFileNameWithoutExtension(path));

            ret.Invoke(LuaNil.Nil, false, -1, LuaMultiValue.Empty);
            return(names.Select(s => env[s].As <T>()).ToArray());
        }
コード例 #3
0
        /// <summary>
        /// Loads a LuaChunk from a specified stream.
        /// </summary>
        /// <param name="stream">The stream to load the script from.</param>
        /// <param name="name">The name to give the chunk.</param>
        /// <param name="override">True to load the file even if it is in the
        /// cache, otherwise false.</param>
        /// <param name="index">Stores the index of the loaded module.</param>
        /// <returns>The loaded chunk.</returns>
        /// <exception cref="System.ArgumentNullException">If stream is null.</exception>
        /// <exception cref="ModMaker.Lua.Parser.SyntaxException">If there is
        /// syntax errors in the file.</exception>
        public ILuaValue Load(Stream stream, string name, bool @override, out int index)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            using (TextReader c = new StreamReader(stream))
            {
                lock (this)
                {
                    var temp = Environment.Parser.UseCache;
                    Environment.Parser.UseCache = !@override;
                    var ret = Environment.CodeCompiler.Compile(
                        Environment,
                        PlainParser.Parse(Environment.Parser, c.ReadToEnd(), name),
                        name);
                    Environment.Parser.UseCache = temp;

                    if (!_chunks.Contains(ret))
                    {
                        _chunks.Add(ret);
                    }
                    index = _chunks.IndexOf(ret);
                    return(ret);
                }
            }
        }
コード例 #4
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                    {
                        throw new ArgumentException("Expecting one argument to function 'dofile'.");
                    }

                    string file = args[0].GetValue() as string;

                    if (string.IsNullOrEmpty(file))
                    {
                        throw new ArgumentException("First argument to 'loadfile' must be a file path.");
                    }

                    if (!File.Exists(file))
                    {
                        throw new FileNotFoundException("Unable to locate file at '" + file + "'.");
                    }

                    string chunk  = File.ReadAllText(file);
                    var    parsed = PlainParser.Parse(_environment.Parser, chunk,
                                                      Path.GetFileNameWithoutExtension(file));
                    var r = _environment.CodeCompiler.Compile(_environment, parsed, null);

                    return(r.Invoke(LuaNil.Nil, false, -1, LuaMultiValue.Empty));
                }
コード例 #5
0
        IParseItem _parseBlock(string input)
        {
            PlainParser target   = new PlainParser();
            var         encoding = Encoding.UTF8;
            var         stream   = new MemoryStream(encoding.GetBytes(input));

            return(target.Parse(stream, encoding, null));
        }
コード例 #6
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                    {
                        throw new ArgumentException("Expecting at least one argument to function 'load'.");
                    }

                    ILuaValue ld = args[0];
                    string    chunk;

                    if (ld.ValueType == LuaValueType.Function)
                    {
                        chunk = "";
                        while (true)
                        {
                            var ret = ld.Invoke(LuaNil.Nil, false, -1, _environment.Runtime.CreateMultiValue());
                            if (ret[0].ValueType == LuaValueType.String)
                            {
                                if (string.IsNullOrEmpty(ret[0].GetValue() as string))
                                {
                                    break;
                                }
                                else
                                {
                                    chunk += ret[0].GetValue() as string;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    else if (ld.ValueType == LuaValueType.String)
                    {
                        chunk = ld.GetValue() as string;
                    }
                    else
                    {
                        throw new ArgumentException("First argument to 'load' must be a string or a method.");
                    }

                    try {
                        var parsed = PlainParser.Parse(_environment.Parser, chunk, null);
                        return(_environment.Runtime.CreateMultiValue(
                                   _environment.CodeCompiler.Compile(_environment, parsed, null)));
                    } catch (Exception e) {
                        return(_environment.Runtime.CreateMultiValueFromObj(null, e.Message));
                    }
                }
コード例 #7
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                    {
                        throw new ArgumentException("Expecting at least one argument to function 'loadfile'.");
                    }

                    string file = args[0].GetValue() as string;
                    string mode = args[1].GetValue() as string;

                    if (string.IsNullOrEmpty(file))
                    {
                        throw new ArgumentException("First argument to 'loadfile' must be a file path.");
                    }

                    if (!File.Exists(file))
                    {
                        throw new FileNotFoundException("Unable to locate file at '" + file + "'.");
                    }

                    if (string.IsNullOrEmpty(mode) && args.Count > 1)
                    {
                        throw new ArgumentException("Second argument to 'loadfile' must be a string mode.");
                    }

                    if (mode != "type")
                    {
                        throw new ArgumentException("The only mode supported by loadfile is 'type'.");
                    }

                    string chunk = File.ReadAllText(file);

                    try {
                        var parsed = PlainParser.Parse(_environment.Parser, chunk,
                                                       Path.GetFileNameWithoutExtension(file));
                        return(_environment.Runtime.CreateMultiValue(
                                   _environment.CodeCompiler.Compile(_environment, parsed, null)));
                    } catch (Exception e) {
                        return(_environment.Runtime.CreateMultiValueFromObj(null, e.Message));
                    }
                }
コード例 #8
0
        ILuaValue _processFile(string path, string name, string partname, ILuaEnvironment env,
                               List <Exception> exceptions)
        {
            if (path.EndsWith(".lua", StringComparison.OrdinalIgnoreCase))
            {
                if (!this.AllowLua)
                {
                    exceptions.Add(new InvalidOperationException(
                                       $"Cannot load file '{path}' because ModuleBinder.AllowLua is set to false."));
                    return(null);
                }

                var item = PlainParser.Parse(
                    env.Parser, File.ReadAllText(path), System.IO.Path.GetFileNameWithoutExtension(path));
                var chunk = env.CodeCompiler.Compile(env, item, null);
                return(chunk.Invoke(LuaNil.Nil, false, -1, LuaMultiValue.Empty).Single());
            }
            else if (path.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
            {
                var aname = AssemblyName.GetAssemblyName(path);

                if (WhitelistPublicKeys != null)
                {
                    bool valid = false;
                    foreach (var key in WhitelistPublicKeys)
                    {
                        if (key == null)
                        {
                            if (aname.GetPublicKey() == null)
                            {
                                valid = true;
                            }
                        }
                        else
                        {
                            if (aname.GetPublicKey().ToStringBase16().ToLowerInvariant() ==
                                key.ToLowerInvariant())
                            {
                                valid = true;
                            }
                        }
                    }
                    if (!valid)
                    {
                        exceptions.Add(new InvalidOperationException(
                                           "Cannot load file '" + path +
                                           "' because the assembly's public key is not in the white-list."));
                        return(null);
                    }
                }

                // Process the assembly
                if (AllowAssemblies)
                {
                    var a     = Assembly.LoadFrom(path);
                    var types = a.GetTypes();
                    if (types == null || types.Length == 0)
                    {
                        exceptions.Add(new InvalidOperationException(
                                           "Cannot load file '" + path + "' because it does not define any types."));
                        return(null);
                    }
                    else if (types.Length > 1)
                    {
                        HashSet <Type> validTypes = new HashSet <Type>();
                        bool matchesName(Type t) => t.Name == name || t.Name == partname ||
                        t.FullName == name || t.FullName == partname;

                        foreach (var item in types.Where(t => matchesName(t) && _validType(t)))
                        {
                            validTypes.Add(item);
                        }

                        if (validTypes.Count > 1)
                        {
                            exceptions.Add(new InvalidOperationException(
                                               $"Cannot load file '{path}' because more than one type matches the given name."));
                            return(null);
                        }
                        else if (validTypes.Count == 0)
                        {
                            exceptions.Add(new InvalidOperationException(
                                               $"Cannot load file '{path}' because no types match the given name."));
                            return(null);
                        }
                        else
                        {
                            return(_processType(validTypes.First(), env));
                        }
                    }
                    else
                    {
                        return(_processType(types[0], env));
                    }
                }
            }
            return(null);
        }
コード例 #9
0
        public void GenralParse()
        {
            PlainParser           target = new PlainParser();
            TextElementEnumerator input1 = StringInfo.GetTextElementEnumerator(
                @"local a = 12 
t = { [34]= function() print(i) end } 
function Some(a, ...) 
    a, b, c = ... 
    for i= 12, 23 do 
        print(i) 
    end 
end"
                );
            IParseItem actual;

            actual = target.Parse(new Tokenizer(input1, null), null, null);

            // check the main block
            BlockItem block = actual as BlockItem;

            Assert.IsInstanceOf <BlockItem>(actual);
            Assert.IsNotNull(block.Children);
            Assert.AreEqual(3, block.Children.Count, "Block.Children.Count");
            ValidateDebug(block.Debug, "Block", "local a = 12 t = { [ 34 ] = function ( ) print ( i ) end } function Some ( a , ... ) a , b , c = ... for i = 12 , 23 do print ( i ) end end", 1, 1, 8, 4);

            // check the return statement of the main block
            {
                ReturnItem ret = block.Return;
                Assert.IsInstanceOf <ReturnItem>(block.Return);
                ValidateDebug(ret.Debug, "Block.Return", null, 0, 0, 0, 0);
                Assert.IsNotNull(ret.Expressions);
                Assert.AreEqual(0, ret.Expressions.Count);
            }

            // local a = 12
            {
                AssignmentItem init = block.Children[0] as AssignmentItem;
                Assert.IsNotNull(init, "Block.Children[0]");
                Assert.AreEqual(true, init.Local);
                ValidateDebug(init.Debug, "Block.Children[0]", "local a = 12", 1, 1, 1, 13);

                // check the names
                {
                    Assert.IsNotNull(init.Names, "Block.Children[0].Names");
                    Assert.AreEqual(1, init.Names.Count, "Block.Children[0].Names.Count");

                    NameItem name = init.Names[0] as NameItem;
                    Assert.IsNotNull(name, "Block.Children[0].Names[0]");
                    Assert.AreEqual("a", name.Name, "Block.Children[0].Names[0].Name");
                    ValidateDebug(name.Debug, "Block.Children[0].Names[0]", "a", 1, 7, 1, 8);
                }

                // check the expressions
                {
                    Assert.IsNotNull(init.Expressions, "Block.Children[0].Expressions");
                    Assert.AreEqual(1, init.Expressions.Count, "Block.Children[0].Expressions.Count");

                    LiteralItem literal = init.Expressions[0] as LiteralItem;
                    Assert.IsNotNull(literal, "Block.Children[0].Expressions[0]");
                    Assert.AreEqual(12.0, literal.Value, "Block.Children[0].Expressions[0].Value");
                    ValidateDebug(literal.Debug, "Block.Children[0].Expressions[0]", "12", 1, 11, 1, 13);
                }
            }

            // t = { [34]= function() print(i) end }
            {
                AssignmentItem init = block.Children[1] as AssignmentItem;
                Assert.IsNotNull(init, "Block.Children[1]");
                Assert.AreEqual(false, init.Local);
                ValidateDebug(init.Debug, "Block.Children[1]", "t = { [ 34 ] = function ( ) print ( i ) end }", 2, 1, 2, 38);

                // check the names
                {
                    Assert.IsNotNull(init.Names, "Block.Children[1].Names");
                    Assert.AreEqual(1, init.Names.Count, "Block.Children[1].Names.Count");

                    NameItem name = init.Names[0] as NameItem;
                    Assert.IsNotNull(name, "Block.Children[1].Names[0]");
                    Assert.AreEqual("t", name.Name, "Block.Children[1].Names[0].Name");
                    ValidateDebug(name.Debug, "Block.Children[1].Names[0]", "t", 2, 1, 2, 2);
                }

                // check the expressions
                {
                    Assert.IsNotNull(init.Expressions, "Block.Children[1].Expressions");
                    Assert.AreEqual(1, init.Expressions.Count, "Block.Children[1].Expressions.Count");

                    TableItem table = init.Expressions[0] as TableItem;
                    Assert.IsNotNull(table, "Block.Children[1].Expressions[0]");
                    ValidateDebug(table.Debug, "Block.Children[1].Expressions[0]", "{ [ 34 ] = function ( ) print ( i ) end }", 2, 5, 2, 38);

                    Assert.IsNotNull(table.Fields, "Block.Children[1].Expressions[0].Fields");
                    Assert.AreEqual(1, table.Fields.Count, "Block.Children[1].Expressions[0].Fields.Count");

                    var field = table.Fields[0];
                    {
                        LiteralItem literal = field.Key as LiteralItem;
                        Assert.IsNotNull(literal, "Block.Children[1].Expressions[0].Fields[0].Item1");
                        Assert.AreEqual(34.0, literal.Value, "Block.Children[1].Expressions[0].Fields[0].Item1.Value");
                        ValidateDebug(literal.Debug, "Block.Children[1].Expressions[0].Fields[0].Item1", "34", 2, 8, 2, 10);
                    }
                    {
                        FuncDefItem func = field.Value as FuncDefItem;
                        Assert.IsNotNull(func, "Block.Children[1].Expressions[0].Fields[0].Item2");
                        Assert.IsNull(func.InstanceName, "Block.Children[1].Expressions[0].Fields[0].Item2.InstanceName");
                        Assert.IsNull(func.Prefix, "Block.Children[1].Expressions[0].Fields[0].Item2.Prefix");
                        Assert.AreEqual(false, func.Local, "Block.Children[1].Expressions[0].Fields[0].Item2.Local");
                        Assert.IsNull(func.FunctionInformation, "Block.Children[1].Expressions[0].Fields[0].Item2.FunctionInformation");
                        ValidateDebug(func.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2", "function ( ) print ( i ) end", 2, 13, 2, 36);

                        // validate the block
                        {
                            BlockItem funcBlock = func.Block;
                            Assert.IsNotNull(funcBlock, "Block.Children[1].Expressions[0].Fields[0].Item2.Block");
                            ValidateDebug(funcBlock.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block", "print ( i )", 2, 24, 2, 32);


                            // validate the return
                            {
                                ReturnItem ret = funcBlock.Return;
                                Assert.IsNotNull(ret, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Return");
                                ValidateDebug(ret.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Return", null, 0, 0, 0, 0);
                                Assert.IsNotNull(ret.Expressions, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Return.Expressions");
                                Assert.AreEqual(0, ret.Expressions.Count, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Return.Expressions.Count");
                            }

                            // validate the statement
                            {
                                Assert.IsNotNull(funcBlock.Children, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children");
                                Assert.AreEqual(1, funcBlock.Children.Count, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children.Count");

                                // print ( i )
                                {
                                    FuncCallItem call = funcBlock.Children[0] as FuncCallItem;
                                    Assert.IsNotNull(call, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0]");
                                    Assert.AreEqual(true, call.Statement, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Statement");
                                    Assert.IsNull(call.InstanceName, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].InstanceName");
                                    ValidateDebug(call.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0]", "print ( i )", 2, 24, 2, 32);

                                    // validate the prefix
                                    {
                                        NameItem name = call.Prefix as NameItem;
                                        Assert.IsNotNull(call.Prefix, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Prefix");
                                        Assert.AreEqual("print", name.Name, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Prefix.Name");
                                        ValidateDebug(name.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Prefix.Name", "print", 2, 24, 2, 29);
                                    }

                                    // validate the arguments
                                    {
                                        Assert.IsNotNull(call.Arguments, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments");
                                        Assert.AreEqual(1, call.Arguments.Count, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments.Count");

                                        NameItem name = call.Arguments[0].Expression as NameItem;
                                        Assert.IsNotNull(name, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments[0]");
                                        Assert.AreEqual("i", name.Name, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments[0].Name");
                                        ValidateDebug(name.Debug, "Block.Children[1].Expressions[0].Fields[0].Item2.Block.Children[0].Arguments[0]", "i", 2, 30, 2, 31);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // function Some(a, ...)
            {
                FuncDefItem func = block.Children[2] as FuncDefItem;
                Assert.IsNotNull(func, "Block.Children[2]");
                Assert.AreEqual(false, func.Local, "Block.Children[2].Local");
                Assert.IsNull(func.InstanceName, "Block.Children[2].InstanceName");
                ValidateDebug(func.Debug, "Block.Children[2]", "function Some ( a , ... ) a , b , c = ... for i = 12 , 23 do print ( i ) end end", 3, 1, 8, 4);

                // validate the block
                {
                    BlockItem someBlock = func.Block;
                    ValidateDebug(someBlock.Debug, "Block.Children[2].Block", "a , b , c = ... for i = 12 , 23 do print ( i ) end", 4, 5, 7, 8);

                    // validate the return
                    {
                        ReturnItem ret = someBlock.Return;
                        Assert.IsNotNull(ret, "Block.Children[2].Block.Return");
                        ValidateDebug(ret.Debug, "Block.Children[2].Block.Return", null, 0, 0, 0, 0);
                        Assert.IsNotNull(ret.Expressions, "Block.Children[2].Block.Return.Expressions");
                        Assert.AreEqual(0, ret.Expressions.Count, "Block.Children[2].Block.Return.Expressions.Count");
                    }

                    // check the children
                    {
                        Assert.IsNotNull(someBlock.Children, "Block.Children[2].Block.Children");
                        Assert.AreEqual(2, someBlock.Children.Count, "Block.Children[2].Block.Children.Count");

                        // a , b , c = ...
                        {
                            AssignmentItem varInit = someBlock.Children[0] as AssignmentItem;
                            Assert.IsNotNull(varInit, "Block.Children[2].Block.Children[0]");
                            Assert.AreEqual(false, varInit.Local, "Block.Children[2].Block.Children[0].Local");
                            ValidateDebug(varInit.Debug, "Block.Children[2].Block.Children[0]", "a , b , c = ...", 4, 5, 4, 18);

                            // validate the names
                            {
                                Assert.IsNotNull(varInit.Names, "Block.Children[2].Block.Children[0].Names");
                                Assert.AreEqual(3, varInit.Names.Count, "Block.Children[2].Block.Children[0].Names.Count");

                                NameItem name = varInit.Names[0] as NameItem;
                                Assert.IsNotNull(name, "Block.Children[2].Block.Children[0].Names[0]");
                                Assert.AreEqual(name.Name, "a", "Block.Children[2].Block.Children[0].Names[0].Name");
                                ValidateDebug(name.Debug, "Block.Children[2].Block.Children[0].Names[0]", "a", 4, 5, 4, 6);

                                name = varInit.Names[1] as NameItem;
                                Assert.IsNotNull(name, "Block.Children[2].Block.Children[0].Names[1]");
                                Assert.AreEqual(name.Name, "b", "Block.Children[2].Block.Children[0].Names[1].Name");
                                ValidateDebug(name.Debug, "Block.Children[2].Block.Children[0].Names[1]", "b", 4, 8, 4, 9);

                                name = varInit.Names[2] as NameItem;
                                Assert.IsNotNull(name, "Block.Children[2].Block.Children[0].Names[2]");
                                Assert.AreEqual(name.Name, "c", "Block.Children[2].Block.Children[0].Names[2].Name");
                                ValidateDebug(name.Debug, "Block.Children[2].Block.Children[0].Names[2]", "c", 4, 11, 4, 12);
                            }
                            // validate the expressions
                            {
                                Assert.IsNotNull(varInit.Expressions, "Block.Children[2].Block.Children[0].Expressions");
                                Assert.AreEqual(1, varInit.Expressions.Count, "Block.Children[2].Block.Children[0].Expressions.Count");

                                NameItem name = varInit.Expressions[0] as NameItem;
                                Assert.IsNotNull(name, "Block.Children[2].Block.Children[0].Expressions[0]");
                                Assert.AreEqual(name.Name, "...", "Block.Children[2].Block.Children[0].Expressions[0].Name");
                                ValidateDebug(name.Debug, "Block.Children[2].Block.Children[0].Expressions[0]", "...", 4, 15, 4, 18);
                            }
                        }
                        // for i= 12, 23 do print ( i ) end
                        {
                            ForNumItem forLoop = someBlock.Children[1] as ForNumItem;
                            Assert.IsNotNull(forLoop, "Block.Children[2].Block.Children[1]");
                            ValidateDebug(forLoop.Debug, "Block.Children[2].Block.Children[1]", "for i = 12 , 23 do print ( i ) end", 5, 5, 7, 8);

                            // validate the name
                            {
                                NameItem name = forLoop.Name;
                                Assert.IsNotNull(name, "Block.Children[2].Block.Children[1].Name");
                                ValidateDebug(name.Debug, "Block.Children[2].Block.Children[1].Name", "i", 5, 9, 5, 10);
                                Assert.AreEqual(name.Name, "i", "Block.Children[2].Block.Children[1].Name.Name");
                            }

                            // validate the start
                            {
                                LiteralItem lit = forLoop.Start as LiteralItem;
                                Assert.IsNotNull(lit, "Block.Children[2].Block.Children[1].Start");
                                Assert.AreEqual(12.0, lit.Value, "Block.Children[2].Block.Children[1].Start.Value");
                                ValidateDebug(lit.Debug, "Block.Children[2].Block.Children[1].Start", "12", 5, 12, 5, 14);
                            }

                            // validate the limit
                            {
                                LiteralItem lit = forLoop.Limit as LiteralItem;
                                Assert.IsNotNull(lit, "Block.Children[2].Block.Children[1].Limit");
                                Assert.AreEqual(23.0, lit.Value, "Block.Children[2].Block.Children[1].Limit.Value");
                                ValidateDebug(lit.Debug, "Block.Children[2].Block.Children[1].Limit", "23", 5, 16, 5, 18);
                            }

                            // validate the step
                            {
                                Assert.IsNull(forLoop.Step, "Block.Children[2].Block.Children[1].Step");
                            }

                            // validate the block
                            {
                                BlockItem forBlock = forLoop.Block;
                                ValidateDebug(forBlock.Debug, "Block.Children[2].Block.Children[1].Block", "print ( i )", 6, 9, 6, 17);
                                Assert.IsNull(forBlock.Return, "Block.Children[2].Block.Children[1].Block.Return");

                                // validate the statement
                                {
                                    Assert.IsNotNull(forBlock.Children, "Block.Children[2].Block.Children[1].Block.Children");
                                    Assert.AreEqual(1, forBlock.Children.Count, "Block.Children[2].Block.Children[1].Block.Children.Count");

                                    // print ( i )
                                    {
                                        FuncCallItem call = forBlock.Children[0] as FuncCallItem;
                                        Assert.IsNotNull(call, "Block.Children[2].Block.Children[1].Block.Children[0]");
                                        Assert.AreEqual(true, call.Statement, "Block.Children[2].Block.Children[1].Block.Children[0].Statement");
                                        Assert.IsNull(call.InstanceName, "Block.Children[2].Block.Children[1].Block.Children[0].InstanceName");
                                        ValidateDebug(call.Debug, "Block.Children[2].Block.Children[1].Block.Children[0]", "print ( i )", 6, 9, 6, 17);

                                        // validate the prefix
                                        {
                                            NameItem name = call.Prefix as NameItem;
                                            Assert.IsNotNull(call.Prefix, "Block.Children[2].Block.Children[1].Block.Children[0].Prefix");
                                            Assert.AreEqual("print", name.Name, "Block.Children[2].Block.Children[1].Block.Children[0].Prefix.Name");
                                            ValidateDebug(name.Debug, "Block.Children[2].Block.Children[1].Block.Children[0].Prefix.Name", "print", 6, 9, 6, 14);
                                        }

                                        // validate the arguments
                                        {
                                            Assert.IsNotNull(call.Arguments, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments");
                                            Assert.AreEqual(1, call.Arguments.Count, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments.Count");

                                            NameItem name = call.Arguments[0].Expression as NameItem;
                                            Assert.IsNotNull(name, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments[0]");
                                            Assert.AreEqual("i", name.Name, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments[0].Name");
                                            ValidateDebug(name.Debug, "Block.Children[2].Block.Children[1].Block.Children[0].Arguments[0]", "i", 6, 15, 6, 16);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }