private static void build_dot(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, ASBinCode.rtti.ClassMember member)
        {
            ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
            eax._regMember       = member;
            eax._regMemberSrcObj = v1;

            eax.setEAXTypeWhenCompile(member.valueType);

            make_dotStep(env, member, step.token, eax, v1);

            //OpStep op = new OpStep(
            //    member.bindField is ClassMethodGetter?
            //    OpCode.access_method
            //    :
            //    OpCode.access_dot

            //    , new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
            //op.reg = eax;
            //op.regType = eax.valueType;
            //op.arg1 = v1;
            //op.arg1Type = v1.valueType;
            //op.arg2 = (IRightValue)member.bindField; //new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(member.index));
            //op.arg2Type = member.valueType; //RunTimeDataType.rt_int;

            //env.block.opSteps.Add(op);
        }
        private static void build_dot_name(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1)
        {
            ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
            eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void);

            OpStep op = new OpStep(OpCode.access_dot_byname, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));

            op.reg      = eax; eax._isDotAccessTarget = true;
            op.regType  = eax.valueType;
            op.arg1     = v1;
            op.arg1Type = v1.valueType;
            op.arg2     = new ASBinCode.rtData.RightValue(
                new ASBinCode.rtData.rtString(step.Arg3.Data.Value.ToString()));
            op.arg2Type = RunTimeDataType.rt_string;
            env.block.opSteps.Add(op);
        }
        private void jumpTo(CompileEnv env, ASTool.AS3.AS3Try as3try, Builder builder, string label)
        {
            ASTool.AS3.AS3StmtExpressions jumptofinally = new ASTool.AS3.AS3StmtExpressions(as3try.Token);
            jumptofinally.as3exprlist = new List <ASTool.AS3.AS3Expression>();

            ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3try.Token);
            expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

            ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3try.Token);
            step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
            step.OpCode = label;
            expression.exprStepList.Add(step);

            jumptofinally.as3exprlist.Add(expression);
            builder.buildStmt(env, jumptofinally);
        }
        private void build_void(CompileEnv env, RightValueBase cls, ASTool.AS3.Expr.AS3ExprStep step, Builder builder)
        {
            OpStep opnewclass = new OpStep(OpCode.new_instance_class,
                                           new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));

            opnewclass.arg1     = cls;
            opnewclass.arg1Type = RunTimeDataType.rt_void;
            StackSlotAccessor _eax = env.createASTRegister(step.Arg1.Reg);

            _eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void);
            opnewclass.reg     = _eax;
            opnewclass.regType = RunTimeDataType.rt_void;


            OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_class_argement, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));

            opMakeArgs.arg1     = cls;
            opMakeArgs.arg1Type = RunTimeDataType.rt_void;
            env.block.opSteps.Add(opMakeArgs);

            if (step.Arg3 != null)
            {
                List <ASTool.AS3.Expr.AS3DataStackElement> args
                    = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value;
                for (int i = 0; i < args.Count; i++)
                {
                    ASTool.AS3.Expr.AS3DataStackElement argData = args[i];
                    RightValueBase arg = builds.ExpressionBuilder.getRightValue(env, argData, step.token, builder);
                    //***参数准备***
                    OpStep opPushArgs = new OpStep(OpCode.push_parameter_class, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                    opPushArgs.arg1     = arg;
                    opPushArgs.arg1Type = arg.valueType;
                    opPushArgs.arg2     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(i));
                    opPushArgs.arg2Type = RunTimeDataType.rt_int;
                    env.block.opSteps.Add(opPushArgs);
                }
            }



            env.block.opSteps.Add(opnewclass);
        }
        private void build_class(CompileEnv env,
                                 ASBinCode.rtti.Class _class,
                                 ASTool.AS3.Expr.AS3ExprStep step, Builder builder)
        {
            //***参数检查***



            List <ASTool.AS3.Expr.AS3DataStackElement> args;

            if (!step.Arg2.IsReg && step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_vector)
            {
                ASTool.AS3.AS3Vector vector = (ASTool.AS3.AS3Vector)step.Arg2.Data.Value;



                if (vector.Constructor == null)
                {
                    args = new List <ASTool.AS3.Expr.AS3DataStackElement>();
                }
                else
                {
                    if (vector.isInitData)
                    {
                        args = new List <ASTool.AS3.Expr.AS3DataStackElement>();
                    }
                    else
                    {
                        args = (List <ASTool.AS3.Expr.AS3DataStackElement>)vector.Constructor.Data.Value;
                    }
                }
            }
            else
            {
                if (step.Arg3 != null)
                {
                    args = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value;
                }
                else
                {
                    args = new List <ASTool.AS3.Expr.AS3DataStackElement>();
                }
            }

            StackSlotAccessor insEax = env.createASTRegister(step.Arg1.Reg);

            build_class(env, _class, step.token, builder,
                        insEax,
                        args
                        );

            if (!step.Arg2.IsReg && step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_vector)
            {
                ASTool.AS3.AS3Vector vector = (ASTool.AS3.AS3Vector)step.Arg2.Data.Value;
                if (vector.Constructor != null && vector.isInitData)
                {
                    //***追加初始化Vector***
                    var initdata = (List <ASTool.AS3.Expr.AS3DataStackElement>)vector.Constructor.Data.Value;

                    var vt = builder.bin.dict_Vector_type[_class];

                    for (int i = 0; i < initdata.Count; i++)
                    {
                        var d = ExpressionBuilder.getRightValue(env, initdata[i], step.token, builder);

                        if (!ASRuntime.TypeConverter.testImplicitConvert(d.valueType, vt, builder))
                        {
                            throw(new BuildException(new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                                    "不能将[" + d.valueType + "]类型存入Vector.<" + vt + ">")));
                        }

                        if (d.valueType != vt)
                        {
                            d = ExpressionBuilder.addCastOpStep(env, d, vt,
                                                                new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                                , builder);
                        }

                        OpStep oppush = new OpStep(OpCode.vector_push, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                        oppush.reg      = null;
                        oppush.regType  = RunTimeDataType.unknown;
                        oppush.arg1     = insEax;
                        oppush.arg1Type = insEax.valueType;
                        oppush.arg2     = d;
                        oppush.arg2Type = d.valueType;

                        env.block.opSteps.Add(oppush);
                    }



                    //throw new NotImplementedException();
                }
            }


            ////***查找构造函数**
            //if (_class.constructor != null)
            //{
            //    ClassMethodGetter field = (ClassMethodGetter)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index];
            //    int blockid = field.refdefinedinblockid;

            //    var signature =
            //            builder.dictSignatures[blockid][field];
            //    //***参数检查***
            //    List<ASTool.AS3.Expr.AS3DataStackElement> args;
            //    if (step.Arg3 != null)
            //    {
            //        args = (List<ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value;
            //    }
            //    else
            //    {
            //        args = new List<ASTool.AS3.Expr.AS3DataStackElement>();
            //    }
            //    FuncCallBuilder funcbuilder = new FuncCallBuilder();
            //    funcbuilder.createParaOp(args, signature, step, env, field, builder, true, _class);
            //}
            //else
            //{
            //    OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement,
            //        new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
            //    opMakeArgs.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid));
            //    opMakeArgs.arg1Type = RunTimeDataType.rt_int;
            //    env.block.opSteps.Add(opMakeArgs);
            //}

            //OpStep op = new OpStep(OpCode.new_instance, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
            //op.arg1 = new RightValue(new rtInt(_class.classid));
            //op.arg1Type = _class.getRtType();
            //Register eax = env.createASTRegister(step.Arg1.Reg.ID);
            //eax.setEAXTypeWhenCompile(_class.getRtType());
            //op.reg = eax;
            //op.regType = _class.getRtType();

            //env.block.opSteps.Add(op);
        }
        public void buildConstructor(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, Builder builder)
        {
            if (step.OpCode == "new")
            {
                if (step.Arg1.IsReg)
                {
                    ASBinCode.rtti.Class _class = null;
                    if (step.Arg2.IsReg)
                    {
                        var cls = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder);
                        if (cls is ASBinCode.StaticClassDataGetter)
                        {
                            _class = builder.getClassByRunTimeDataType(cls.valueType).instanceClass;
                            build_class(env, _class, step, builder);
                            return;
                        }
                        else if (cls is MethodGetterBase)
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "Method cannot be used as a constructor."));
                        }
                        else if (cls.valueType == ASBinCode.RunTimeDataType.rt_void || cls.valueType == ASBinCode.RunTimeDataType.rt_function)
                        {
                            //从Class对象中new
                            build_void(env, cls, step, builder);
                            return;
                        }
                        else if (cls.valueType > ASBinCode.RunTimeDataType.unknown)
                        {
                            _class = builder.getClassByRunTimeDataType(cls.valueType);

                            if (_class.isInterface)
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         _class.name + " Interfaces cannot be instantiated with the new operator."));
                            }
                            else if (_class.staticClass != null)
                            {
                                build_class(env, _class, step, builder);
                            }
                            else if (cls is StackSlotAccessor && ((StackSlotAccessor)cls).isFindByPath && _class.staticClass == null)
                            {
                                build_class(env, _class.instanceClass, step, builder);
                            }
                            else
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "类型" + cls.valueType + "不能new"));
                            }
                            return;
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "类型" + cls.valueType + "不能new"));
                        }
                    }
                    else
                    {
                        //***查找对象类型
                        var find = TypeReader.findClassFromImports(step.Arg2.Data.Value.ToString(), builder, step.token);



                        if (find.Count == 1)
                        {
                            _class = find[0];

                            if (_class.isInterface)
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         _class.name + " Interfaces cannot be instantiated with the new operator."));
                            }
                            else if (_class.no_constructor)
                            {
                            }
                            build_class(env, _class, step, builder);
                            return;
                        }
                        else
                        {
                            var cls = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder);

                            if (cls is ASBinCode.StaticClassDataGetter)
                            {
                                _class = builder.getClassByRunTimeDataType(cls.valueType).instanceClass;
                                build_class(env, _class, step, builder);
                                return;
                            }
                            else if (cls is MethodGetterBase)
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "Method cannot be used as a constructor."));
                            }
                            else if (cls.valueType == ASBinCode.RunTimeDataType.rt_void || cls.valueType == ASBinCode.RunTimeDataType.rt_function)
                            {
                                //从Class对象中new
                                build_void(env, cls, step, builder);

                                return;
                            }
                            else if (cls.valueType > RunTimeDataType.unknown &&
                                     (builder.getClassByRunTimeDataType(cls.valueType).classid == 2
                                      ||
                                      builder.getClassByRunTimeDataType(cls.valueType).classid == 0
                                     ))
                            {
                                build_void(env, cls, step, builder);

                                return;
                            }
                            else
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "类型" + cls.valueType + "不能new"));
                            }
                        }
                    }
                }
                else
                {
                    throw new BuildException(
                              new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                             "编译异常 此处应该是个寄存器"));
                }
            }
            else
            {
                throw new BuildException(
                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                         "不支持的操作类型 " + step.Type + " " + step.OpCode));
            }
        }
        public void buildAS3IF(CompileEnv env, ASTool.AS3.AS3IF as3if, Builder builder)
        {
            if (!string.IsNullOrEmpty(as3if.label))
            {
                //**包装一个block**
                ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3if.Token);
                tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>();
                tempblock.CodeList.Add(as3if);
                tempblock.label = as3if.label;
                as3if.label     = null;
                builder.buildStmt(env, tempblock);
            }
            else
            {
                //***先编译条件***
                builder.buildStmt(env, as3if.Condition);
                //**取判断条件***
                ASTool.AS3.AS3Expression expr = as3if.Condition.as3exprlist[as3if.Condition.as3exprlist.Count - 1];

                //if true goto TRUE_LBL
                //***
                //goto IF_END_LBL
                //TRUE_LBL
                //***
                //IF_END_LBL


                string truelabel = env.makeLabel("IF_TRUE");
                string endlabel  = env.makeLabel("IF_END");

                {
                    ASTool.AS3.AS3StmtExpressions conditionsJump = new ASTool.AS3.AS3StmtExpressions(as3if.Condition.Token);
                    ASTool.AS3.AS3Expression      expression     = new ASTool.AS3.AS3Expression(as3if.Condition.Token);
                    expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();
                    ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3if.Token);
                    step.Type   = ASTool.AS3.Expr.OpType.IF_GotoFlag;
                    step.OpCode = truelabel;
                    step.Arg1   = expr.Value;
                    expression.exprStepList.Add(step);

                    conditionsJump.as3exprlist = new List <ASTool.AS3.AS3Expression>();
                    conditionsJump.as3exprlist.Add(expression);
                    builder.buildStmt(env, conditionsJump);
                }
                {
                    //false部分
                    if (as3if.FalsePass != null)
                    {
                        for (int i = 0; i < as3if.FalsePass.Count; i++)
                        {
                            builder.buildStmt(env, as3if.FalsePass[i]);
                        }
                    }

                    //跳转到end;
                    ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3if.Token);
                    jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>();

                    ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3if.Token);
                    expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

                    ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3if.Token);
                    step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
                    step.OpCode = endlabel;
                    expression.exprStepList.Add(step);

                    jumptoend.as3exprlist.Add(expression);
                    builder.buildStmt(env, jumptoend);

                    //**写入true标记
                    OpStep lbl_true = new OpStep(OpCode.flag, new SourceToken(as3if.Token.line, as3if.Token.ptr, as3if.Token.sourceFile));
                    lbl_true.flag = truelabel;
                    env.block.opSteps.Add(lbl_true);
                }
                {
                    //true部分
                    if (as3if.TruePass != null)
                    {
                        for (int i = 0; i < as3if.TruePass.Count; i++)
                        {
                            builder.buildStmt(env, as3if.TruePass[i]);
                        }
                    }

                    //**写入end标记
                    OpStep lbl_end = new OpStep(OpCode.flag, new SourceToken(as3if.Token.line, as3if.Token.ptr, as3if.Token.sourceFile));
                    lbl_end.flag = endlabel;
                    env.block.opSteps.Add(lbl_end);
                }
            }
        }
        public void buildAccess(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, Builder builder)
        {
            if (step.OpCode == ".")
            {
                if (step.Arg1.IsReg)
                {
                    ASBinCode.RightValueBase v1 = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder);
                    if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                    {
                        if (step.Arg3.Data.Value.ToString() == "null")
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "Syntax error: 'null' is not allowed here"));
                        }
                    }

                    //ASBinCode.IRightValue v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder);
                    if (v1 is ASBinCode.StaticClassDataGetter)
                    {
                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            ASBinCode.StaticClassDataGetter sd = (ASBinCode.StaticClassDataGetter)v1;
                            var cls = sd._class;

                            build_class(env, step, v1, cls, builder);
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1 is PackagePathGetter)
                    {
                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            PackagePathGetter pd   = (PackagePathGetter)v1;
                            string            path = pd.path + "." + step.Arg3.Data.Value.ToString();

                            //**尝试查找类***

                            var found = TypeReader.findClassFromProject(path, builder, step.token);
                            if (found.Count == 1)
                            {
                                var item = found[0];

                                OpStep stepInitClass = new OpStep(OpCode.init_staticclass,
                                                                  new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                                stepInitClass.arg1 = new ASBinCode.rtData.RightValue(
                                    new ASBinCode.rtData.rtInt(item.classid));
                                stepInitClass.arg1Type = item.staticClass.getRtType();
                                env.block.opSteps.Add(stepInitClass);

                                ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
                                eax.setEAXTypeWhenCompile(item.staticClass.getRtType());
                                eax.isFindByPath = true;
                                //eax._pathGetter = new PackagePathGetter(path);

                                OpStep op = new OpStep(OpCode.assigning, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                                op.reg      = eax;
                                op.arg1     = new StaticClassDataGetter(item.staticClass);
                                op.arg1Type = item.staticClass.getRtType();

                                env.block.opSteps.Add(op);
                            }
                            else if (found.Count > 1)
                            {
                                throw new BuildException(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "类型" + path + "不明确."
                                                         );
                            }
                            else
                            {
                                //没找到
                                PackagePathGetter           g   = new PackagePathGetter(path);
                                ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
                                eax.setEAXTypeWhenCompile(RunTimeDataType.unknown);
                                eax._pathGetter = g;
                            }
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1 is ThisPointer && v1.valueType == RunTimeDataType.rt_void)
                    {
                        //throw new BuildException(
                        //   new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                        //   "动态查找成员 还没弄"));

                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            build_dot_name(env, step, v1);
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1.valueType == RunTimeDataType.unknown)
                    {
                        throw new BuildException(
                                  new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                 "遇到了unknown类型"));
                    }
                    else if (v1.valueType > RunTimeDataType.unknown)
                    {
                        ASBinCode.rtti.Class cls = builder.getClassByRunTimeDataType(v1.valueType);

                        if (cls == null)
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "编译异常 类型" + v1.valueType + "未找到"));
                        }
                        else
                        {
                            build_class(env, step, v1, cls, builder);
                        }
                    }
                    else
                    {
                        if (v1.valueType != RunTimeDataType.rt_void && v1.valueType < RunTimeDataType.unknown)
                        {
                            if (
                                builder.bin != null &&
                                builder.bin.primitive_to_class_table[v1.valueType] != null)
                            {
                                var cls = builder.bin.primitive_to_class_table[v1.valueType];
                                v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(),
                                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                                     , builder
                                                                     );
                                build_class(env, step, v1, cls, builder);
                            }
                            else
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "基础类型" + v1.valueType + "无法转换为引用类型"));
                            }
                        }
                        else
                        {
                            if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                            {
                                build_dot_name(env, step, v1);
                            }
                            else
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "静态成员名期待一个identifier"));
                            }
                        }
                    }
                }
                else
                {
                    throw new BuildException(
                              new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                             "编译异常 此处应该是个寄存器"));
                }
            }
            else if (step.OpCode == "[")             //和.作用相同
            {
                if (step.Arg1.IsReg)
                {
                    ASBinCode.RightValueBase v1 = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder);
                    if (v1 is ASBinCode.StaticClassDataGetter)
                    {
                        build_bracket_access(env, step, v1, builder);
                    }
                    else if (v1 is PackagePathGetter)
                    {
                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            PackagePathGetter pd   = (PackagePathGetter)v1;
                            string            path = pd.path + "." + step.Arg3.Data.Value.ToString();

                            //**尝试查找类***

                            //查找导入的类
                            var found = TypeReader.findClassFromImports(path, builder, step.token);
                            if (found.Count == 1)
                            {
                                var item = found[0];

                                OpStep stepInitClass = new OpStep(OpCode.init_staticclass,
                                                                  new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                                stepInitClass.arg1 = new ASBinCode.rtData.RightValue(
                                    new ASBinCode.rtData.rtInt(item.classid));
                                stepInitClass.arg1Type = item.staticClass.getRtType();
                                env.block.opSteps.Add(stepInitClass);

                                ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
                                eax.setEAXTypeWhenCompile(item.getRtType());

                                OpStep op = new OpStep(OpCode.assigning, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                                op.reg      = eax;
                                op.arg1     = new StaticClassDataGetter(item.staticClass);
                                op.arg1Type = item.staticClass.getRtType();

                                env.block.opSteps.Add(op);

                                build_bracket_access(env, step, v1, builder);
                            }
                            else
                            {
                                throw new BuildException(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "类型" + path + "不明确."
                                                         );
                            }
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1 is ThisPointer && v1.valueType == RunTimeDataType.rt_void)
                    {
                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            build_bracket_access(env, step, v1, builder);
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1.valueType == RunTimeDataType.unknown)
                    {
                        throw new BuildException(
                                  new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                 "遇到了unknown类型"));
                    }
                    else if (v1.valueType > RunTimeDataType.unknown)
                    {
                        ASBinCode.rtti.Class cls = builder.getClassByRunTimeDataType(v1.valueType);

                        if (cls == null)
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "编译异常 类型" + v1.valueType + "未找到"));
                        }
                        else
                        {
                            //**todo**检查如果是数组的情况****

                            build_bracket_access(env, step, v1, builder);
                        }
                    }
                    else
                    {
                        if (v1.valueType == RunTimeDataType.rt_array)
                        {
                            var v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder);
                            if (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint)
                            {
                                build_bracket_access(env, step, v1, builder);
                            }
                            else
                            {
                                v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(),
                                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                                     , builder
                                                                     );
                                build_bracket_access(env, step, v1, builder);
                            }
                        }
                        else if (v1.valueType != RunTimeDataType.rt_void && v1.valueType < RunTimeDataType.unknown
                                 )
                        {
                            if (builder.bin.primitive_to_class_table[v1.valueType] != null)
                            {
                                v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(),
                                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                                     , builder
                                                                     );
                                build_bracket_access(env, step, v1, builder);
                            }
                            else
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "基础类型" + v1.valueType + "无法转换为引用类型"));
                            }
                        }
                        else
                        {
                            build_bracket_access(env, step, v1, builder);
                        }
                    }
                }
                else
                {
                    throw new BuildException(
                              new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                             "编译异常 此处应该是个寄存器"));
                }
            }
            else
            {
                throw new BuildException(
                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                         "不支持的操作类型 " + step.Type + " " + step.OpCode));
            }
        }
        private static void build_bracket_access(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, Builder builder)
        {
            ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
            eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void);

            var v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder);

            if (v1.valueType == RunTimeDataType.rt_void
                )
            {
                OpStep op = new OpStep(OpCode.bracket_access, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                op.reg      = eax; eax._isDotAccessTarget = true;
                op.regType  = eax.valueType;
                op.arg1     = v1;
                op.arg1Type = v1.valueType;
                op.arg2     = v2;
                op.arg2Type = v2.valueType;


                env.block.opSteps.Add(op);
            }
            else if (v1.valueType > RunTimeDataType.unknown
                     &&
                     builder.bin.dict_Vector_type.ContainsKey(builder.getClassByRunTimeDataType(v1.valueType))
                     )
            {
                ASBinCode.rtti.Class vector = builder.getClassByRunTimeDataType(v1.valueType);
                RunTimeDataType      vt     = builder.bin.dict_Vector_type[vector];

                if (v2.valueType > RunTimeDataType.unknown)
                {
                    v2 = ExpressionBuilder.addCastToPrimitive(env, v2, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile), builder);
                }

                if (v2.valueType == RunTimeDataType.rt_int ||
                    v2.valueType == RunTimeDataType.rt_number ||
                    v2.valueType == RunTimeDataType.rt_uint
                    )
                {
                    v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int,
                                                         new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                         , builder);
                    eax.setEAXTypeWhenCompile(vt);

                    {
                        OpStep op = new OpStep(OpCode.vectorAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                        op.reg      = eax; eax._isDotAccessTarget = true;
                        op.regType  = eax.valueType;
                        op.arg1     = v1;
                        op.arg1Type = v1.valueType;
                        op.arg2     = v2;
                        op.arg2Type = v2.valueType;
                        env.block.opSteps.Add(op);
                    }
                }
                else
                {
                    OpStep op = new OpStep(OpCode.vectorAccessor_convertidx, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                    op.reg      = eax; eax._isDotAccessTarget = true;
                    op.regType  = eax.valueType;
                    op.arg1     = v1;
                    op.arg1Type = v1.valueType;
                    op.arg2     = v2;
                    op.arg2Type = v2.valueType;
                    env.block.opSteps.Add(op);
                }

                //if (v2.valueType != RunTimeDataType.rt_int)
                //{
                //    v2=ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int,
                //        new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                //        , builder);
                //}

                //eax.setEAXTypeWhenCompile(vt);
                //eax._vector_Type = vt;
                //{

                //    OpStep op = new OpStep(OpCode.vectorAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                //    op.reg = eax;
                //    op.regType = eax.valueType;
                //    op.arg1 = v1;
                //    op.arg1Type = v1.valueType;
                //    op.arg2 = v2;
                //    op.arg2Type = v2.valueType;
                //    env.block.opSteps.Add(op);
                //}
            }
            else if (builder.bin.ArrayClass != null && builder.bin.ArrayClass.getRtType() == v1.valueType
                     &&
                     (v2.valueType == RunTimeDataType.rt_int ||
                      v2.valueType == RunTimeDataType.rt_number ||
                      v2.valueType == RunTimeDataType.rt_uint
                     )

                     )
            {
                v1 = builds.ExpressionBuilder.addCastToPrimitive(env, v1, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile), builder);
                v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int,
                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                     , builder);


                OpStep op = new OpStep(OpCode.arrayAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                op.reg      = eax; eax._isDotAccessTarget = true;
                op.regType  = eax.valueType;
                op.arg1     = v1;
                op.arg1Type = v1.valueType;
                op.arg2     = v2;
                op.arg2Type = v2.valueType;
                env.block.opSteps.Add(op);
            }
            else if (v1.valueType == RunTimeDataType.rt_array
                     &&
                     (v2.valueType == RunTimeDataType.rt_int ||
                      v2.valueType == RunTimeDataType.rt_number ||
                      v2.valueType == RunTimeDataType.rt_uint
                     )
                     )
            {
                v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int,
                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                     , builder);


                OpStep op = new OpStep(OpCode.arrayAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                op.reg      = eax; eax._isDotAccessTarget = true;
                op.regType  = eax.valueType;
                op.arg1     = v1;
                op.arg1Type = v1.valueType;
                op.arg2     = v2;
                op.arg2Type = v2.valueType;
                env.block.opSteps.Add(op);
            }
            else
            {
                OpStep op = new OpStep(OpCode.bracket_byname, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                op.reg      = eax; eax._isDotAccessTarget = true;
                op.regType  = eax.valueType;
                op.arg1     = v1;
                op.arg1Type = v1.valueType;
                op.arg2     = v2;
                op.arg2Type = v2.valueType;
                env.block.opSteps.Add(op);
            }
        }
        private static void build_class(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, ASBinCode.rtti.Class cls, Builder builder)
        {
            if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
            {
                ASBinCode.rtti.ClassMember member = null;



                //***查找对象成员***
                member = MemberFinder.findClassMember(cls, step.Arg3.Data.Value.ToString(), env, builder);

                if (member == null)
                {
                    if (cls.dynamic
                        &&
                        cls.staticClass != null                         //***编译时检查不能向Class动态加属性。
                        )
                    {
                        //***此处编译为动态属性***
                        build_dot_name(env, step, v1);
                        return;
                    }
                }

                if (member == null)
                {
                    if (step.Arg3.Data.Value.ToString() == "hasOwnProperty"
                        )                         //***这是Object原型链对象,特殊处理
                    {
                        //***此处编译为动态属性***
                        build_dot_name(env, step, v1);
                        return;
                    }

                    if (v1 is SuperPointer)
                    {
                        throw new BuildException(
                                  new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                 "Attempted access of inaccessible property " + step.Arg3.Data.Value + " through a reference with static type " + ((SuperPointer)v1).thisClass.name + "."));
                    }
                    else
                    {
                        throw new BuildException(
                                  new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                 cls.name + "对象成员" + step.Arg3.Data.Value + "未找到"));
                    }
                }
                if (!member.isConst && env.isEval)
                {
                    throw new BuildException(
                              new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                             "Eval时忽略非Const成员"));
                }

                build_dot(env, step, v1, member);
            }
            else
            {
                throw new BuildException(
                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                         "静态成员名期待一个identifier"));
            }
        }
        public void buildAS3Switch(CompileEnv env, ASTool.AS3.AS3Switch as3switch, Builder builder)
        {
            if (!string.IsNullOrEmpty(as3switch.label))
            {
                //**包装一个block**
                ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3switch.Token);
                tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>();
                tempblock.CodeList.Add(as3switch);
                tempblock.label = as3switch.label;
                as3switch.label = null;
                builder.buildStmt(env, tempblock);
            }
            else
            {
                //***先编译条件***

                ASTool.AS3.AS3StmtExpressions expressions = new ASTool.AS3.AS3StmtExpressions(as3switch.Token);
                expressions.as3exprlist = new List <ASTool.AS3.AS3Expression>();
                expressions.as3exprlist.Add(as3switch.Expr);
                builder.buildStmt(env, expressions);
                //**取判断条件***
                ASTool.AS3.AS3Expression expr = as3switch.Expr;

                int defaults = 0;
                for (int i = 0; i < as3switch.CaseList.Count; i++)
                {
                    ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i];
                    if (c.IsDefault)
                    {
                        defaults++;
                    }

                    if (defaults > 1)
                    {
                        throw new BuildException(c.token.line, c.token.ptr, c.token.sourceFile, "switch只能有1个default:");
                    }
                }



                List <string> switchlabels = new List <string>();
                for (int i = 0; i < as3switch.CaseList.Count; i++)
                {
                    ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i];
                    if (!c.IsDefault)
                    {
                        switchlabels.Add(env.makeLabel("SWITCH_CASE"));
                    }
                    else
                    {
                        switchlabels.Add(env.makeLabel("SWITCH_DEFAULT"));
                    }
                }

                for (int i = 0; i < as3switch.CaseList.Count; i++)
                {
                    ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i];
                    if (!c.IsDefault)
                    {
                        RunTimeValueBase v = ExpressionEval.Eval(c.Condition);
                        if (v != null && c.Condition.Value.IsReg)
                        {
                            OpStep op  = new OpStep(OpCode.assigning, new SourceToken(c.token.line, c.token.ptr, c.token.sourceFile));
                            var    eax = env.createASTRegister(c.Condition.Value.Reg);
                            eax.setEAXTypeWhenCompile(v.rtType);

                            op.reg      = eax;
                            op.regType  = eax.valueType;
                            op.arg1     = new ASBinCode.rtData.RightValue(v);
                            op.arg1Type = v.rtType;

                            env.block.opSteps.Add(op);
                        }
                        else
                        {
                            ASTool.AS3.AS3StmtExpressions caseExpr = new ASTool.AS3.AS3StmtExpressions(c.token);
                            caseExpr.as3exprlist = new List <ASTool.AS3.AS3Expression>();
                            caseExpr.as3exprlist.Add(c.Condition);
                            builder.buildStmt(env, caseExpr);
                        }
                        {
                            ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token);
                            step.Type   = ASTool.AS3.Expr.OpType.LogicEQ;
                            step.OpCode = "==";
                            step.Arg1   = c.holdreg;
                            step.Arg2   = expr.Value;
                            step.Arg3   = c.Condition.Value;

                            ASTool.AS3.AS3StmtExpressions compare    = new ASTool.AS3.AS3StmtExpressions(c.token);
                            ASTool.AS3.AS3Expression      expression = new ASTool.AS3.AS3Expression(c.token);
                            expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();
                            expression.exprStepList.Add(step);

                            expression.Value = c.holdreg;

                            compare.as3exprlist = new List <ASTool.AS3.AS3Expression>();
                            compare.as3exprlist.Add(expression);

                            builder.buildStmt(env, compare);
                        }

                        {
                            ASTool.AS3.AS3StmtExpressions conditionsJump = new ASTool.AS3.AS3StmtExpressions(c.token);
                            ASTool.AS3.AS3Expression      expression     = new ASTool.AS3.AS3Expression(c.token);
                            expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();
                            ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token);
                            step.Type   = ASTool.AS3.Expr.OpType.IF_GotoFlag;
                            step.OpCode = switchlabels[i];
                            step.Arg1   = c.holdreg;
                            expression.exprStepList.Add(step);

                            conditionsJump.as3exprlist = new List <ASTool.AS3.AS3Expression>();
                            conditionsJump.as3exprlist.Add(expression);
                            builder.buildStmt(env, conditionsJump);
                        }
                    }
                    else
                    {
                        ASTool.AS3.AS3StmtExpressions jump       = new ASTool.AS3.AS3StmtExpressions(c.token);
                        ASTool.AS3.AS3Expression      expression = new ASTool.AS3.AS3Expression(c.token);
                        expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();
                        ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token);
                        step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
                        step.OpCode = switchlabels[i];
                        expression.exprStepList.Add(step);

                        jump.as3exprlist = new List <ASTool.AS3.AS3Expression>();
                        jump.as3exprlist.Add(expression);
                        builder.buildStmt(env, jump);
                    }
                }

                int lblid = env.getLabelId();



                OpStep lbl_case_start = new OpStep(OpCode.flag, new SourceToken(as3switch.Token.line, as3switch.Token.ptr, as3switch.Token.sourceFile));
                lbl_case_start.flag = "SWITCH_START_" + lblid;
                env.block.opSteps.Add(lbl_case_start);

                for (int i = 0; i < as3switch.CaseList.Count; i++)
                {
                    ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i];

                    //if (!c.IsDefault)
                    {
                        OpStep lbl_case = new OpStep(OpCode.flag, new SourceToken(c.token.line, c.token.ptr, c.token.sourceFile));
                        lbl_case.flag = switchlabels[i];
                        env.block.opSteps.Add(lbl_case);
                    }
                    if (c.Body != null)
                    {
                        for (int j = 0; j < c.Body.Count; j++)
                        {
                            builder.buildStmt(env, c.Body[j]);
                        }
                    }
                }

                OpStep lbl_case_end = new OpStep(OpCode.flag, new SourceToken(as3switch.Token.line, as3switch.Token.ptr, as3switch.Token.sourceFile));
                lbl_case_end.flag = "SWITCH_END_" + lblid;
                env.block.opSteps.Add(lbl_case_end);
            }
        }
        public void buildAS3For(CompileEnv env, ASTool.AS3.AS3For as3for, Builder builder)
        {
            if (!string.IsNullOrEmpty(as3for.label))
            {
                //**包装一个block**
                ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3for.Token);
                tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>();
                tempblock.CodeList.Add(as3for);
                tempblock.label = as3for.label;
                as3for.label    = null;


                OpStep lbl_forlabel = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile));
                lbl_forlabel.flag = "LOOP_LABEL_START_" + tempblock.label;
                env.block.opSteps.Add(lbl_forlabel);

                builder.buildStmt(env, tempblock);


                OpStep lbl_forlabel_end = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile));
                lbl_forlabel_end.flag = "LOOP_LABEL_END_" + tempblock.label;
                env.block.opSteps.Add(lbl_forlabel_end);
            }
            else
            {
                //***
                //FOR_LOOPSTART
                //***For_Part2***
                //***if_true goto FOR_LOOPBODY
                //***goto FOR_END
                //FOR_LOOPBODY
                //***ForBody
                //FOR_CONTINUE
                //***For_Part3
                //**goto FOR_LOOPSTART
                //FOR_END

                int lblid = env.getLabelId();

                string loopstart    = "LOOP_START_" + lblid;
                string loopbody     = "LOOP_BODY_" + lblid;
                string loopcontinue = "LOOP_CONTINUE_" + lblid;
                string loopend      = "LOOP_END_" + lblid;

                {
                    OpStep lbl_loopstart = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile));
                    lbl_loopstart.flag = loopstart;
                    env.block.opSteps.Add(lbl_loopstart);
                }
                if (as3for.Part2 != null)
                {
                    builder.buildStmt(env, as3for.Part2);
                    ASTool.AS3.AS3Expression expr =
                        as3for.Part2.as3exprlist[as3for.Part2.as3exprlist.Count - 1];
                    {
                        ASTool.AS3.AS3StmtExpressions conditionsJump =
                            new ASTool.AS3.AS3StmtExpressions(as3for.Part2.Token);
                        ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Part2.Token);
                        expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

                        ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Part2.Token);
                        step.Type   = ASTool.AS3.Expr.OpType.IF_GotoFlag;
                        step.OpCode = loopbody;
                        step.Arg1   = expr.Value;
                        expression.exprStepList.Add(step);

                        conditionsJump.as3exprlist = new List <ASTool.AS3.AS3Expression>();
                        conditionsJump.as3exprlist.Add(expression);
                        builder.buildStmt(env, conditionsJump);
                    }
                    {
                        ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3for.Part2.Token);
                        jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>();

                        ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Part2.Token);
                        expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

                        ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Part2.Token);
                        step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
                        step.OpCode = loopend;
                        expression.exprStepList.Add(step);

                        jumptoend.as3exprlist.Add(expression);
                        builder.buildStmt(env, jumptoend);
                    }
                }
                {
                    OpStep lbl_loopbody = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile));
                    lbl_loopbody.flag = loopbody;
                    env.block.opSteps.Add(lbl_loopbody);
                }
                if (as3for.Body != null)
                {
                    for (int i = 0; i < as3for.Body.Count; i++)
                    {
                        builder.buildStmt(env, as3for.Body[i]);
                    }
                }
                {
                    OpStep lbl_loopcontinue = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile));
                    lbl_loopcontinue.flag = loopcontinue;
                    env.block.opSteps.Add(lbl_loopcontinue);
                }
                if (as3for.Part3 != null)
                {
                    builder.buildStmt(env, as3for.Part3);
                }
                {
                    //强行跳回开始
                    ASTool.AS3.AS3StmtExpressions jumptostart = new ASTool.AS3.AS3StmtExpressions(as3for.Token);
                    jumptostart.as3exprlist = new List <ASTool.AS3.AS3Expression>();

                    ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Token);
                    expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

                    ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Token);
                    step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
                    step.OpCode = loopstart;
                    expression.exprStepList.Add(step);

                    jumptostart.as3exprlist.Add(expression);
                    builder.buildStmt(env, jumptostart);
                }
                {
                    //结束标记
                    OpStep lbl_loopend = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile));
                    lbl_loopend.flag = loopend;
                    env.block.opSteps.Add(lbl_loopend);
                }
            }
        }
        public void buildAS3ForEach(CompileEnv env, ASTool.AS3.AS3ForEach as3foreach, Builder builder)
        {
            if (!string.IsNullOrEmpty(as3foreach.label))
            {
                //**包装一个block**
                ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3foreach.Token);
                tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>();
                tempblock.CodeList.Add(as3foreach);
                tempblock.label  = as3foreach.label;
                as3foreach.label = null;


                OpStep lbl_forlabel = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                lbl_forlabel.flag = "LOOP_LABEL_START_" + tempblock.label;
                env.block.opSteps.Add(lbl_forlabel);

                builder.buildStmt(env, tempblock);


                OpStep lbl_forlabel_end = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                lbl_forlabel_end.flag = "LOOP_LABEL_END_" + tempblock.label;
                env.block.opSteps.Add(lbl_forlabel_end);
            }
            else
            {
                int lblid = env.getLabelId();

                builder.buildStmt(env, as3foreach.ForArg);

                LeftValueBase varvalue = null;

                if (as3foreach.ForArg is ASTool.AS3.AS3StmtExpressions)
                {
                    ASTool.AS3.AS3StmtExpressions exprs = (ASTool.AS3.AS3StmtExpressions)as3foreach.ForArg;
                    if (exprs.as3exprlist.Count != 1)
                    {
                        throw new BuildException(
                                  as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "Syntax error: invalid for-in initializer, only 1 expression expected.");
                    }

                    ASTool.AS3.AS3Expression expr = exprs.as3exprlist[0];
                    varvalue = (LeftValueBase)ExpressionBuilder.getRightValue(env, expr.Value, expr.token, builder);
                }
                else if (as3foreach.ForArg is ASTool.AS3.AS3Variable)
                {
                    ASTool.AS3.AS3Variable v = (ASTool.AS3.AS3Variable)as3foreach.ForArg;
                    varvalue = (VariableBase)MemberFinder.find(v.Name, env, false, builder, v.token);
                }
                else
                {
                    throw new BuildException(
                              as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "异常错误,获得的变量类型不正确");
                }

                builder.buildExpression(env, as3foreach.ForExpr);
                RightValueBase enumerator = ExpressionBuilder.getRightValue(env, as3foreach.ForExpr.Value, as3foreach.ForExpr.token, builder);

                if (enumerator.valueType == RunTimeDataType.rt_void
                    ||
                    enumerator.valueType < RunTimeDataType.unknown
                    )
                {
                    enumerator = ExpressionBuilder.addCastOpStep(env, enumerator, RunTimeDataType._OBJECT,
                                                                 new SourceToken(as3foreach.ForExpr.token.line,
                                                                                 as3foreach.ForExpr.token.ptr,
                                                                                 as3foreach.ForExpr.token.sourceFile)
                                                                 ,
                                                                 builder);
                }

                //Register regSaveEnumerator = env.getAdditionalRegister();
                Variable varSaveEnumerator = new Variable("@saveEnumeraor_" + env.block.scope.members.Count, env.block.scope.members.Count, env.block.id);
                env.block.scope.members.Add(varSaveEnumerator);
                varSaveEnumerator.valueType = (RunTimeDataType.rt_void);
                {
                    //**IEnumerator Get And Reset();
                    OpStep opGetEnumerator = new OpStep(OpCode.foreach_get_enumerator,
                                                        new SourceToken(as3foreach.Token.line,
                                                                        as3foreach.Token.ptr,
                                                                        as3foreach.Token.sourceFile)
                                                        );

                    opGetEnumerator.reg      = varSaveEnumerator;
                    opGetEnumerator.regType  = RunTimeDataType.rt_void;
                    opGetEnumerator.arg1     = enumerator;
                    opGetEnumerator.arg1Type = enumerator.valueType;

                    env.block.opSteps.Add(opGetEnumerator);
                }

                string loopstart    = "LOOP_START_" + lblid;
                string loopbody     = "LOOP_BODY_" + lblid;
                string loopcontinue = "LOOP_CONTINUE_" + lblid;
                string loopend      = "LOOP_END_" + lblid;

                {
                    OpStep lbl_loopstart = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    lbl_loopstart.flag = loopstart;
                    env.block.opSteps.Add(lbl_loopstart);
                }

                StackSlotAccessor eaxismovenext = env.getAdditionalRegister();
                eaxismovenext.setEAXTypeWhenCompile(RunTimeDataType.rt_boolean);
                {
                    //**IEnumerator MoveNext()
                    OpStep opMoveNext = new OpStep(OpCode.enumerator_movenext,
                                                   new SourceToken(as3foreach.Token.line,
                                                                   as3foreach.Token.ptr,
                                                                   as3foreach.Token.sourceFile)
                                                   );

                    opMoveNext.reg      = eaxismovenext;
                    opMoveNext.regType  = RunTimeDataType.rt_boolean;
                    opMoveNext.arg1     = varSaveEnumerator;
                    opMoveNext.arg1Type = varSaveEnumerator.valueType;

                    env.block.opSteps.Add(opMoveNext);
                }

                {
                    OpStep op = new OpStep(OpCode.if_jmp, new SourceToken(as3foreach.ForExpr.token.line,
                                                                          as3foreach.ForExpr.token.ptr, as3foreach.ForExpr.token.sourceFile));
                    op.reg      = null;
                    op.regType  = RunTimeDataType.unknown;
                    op.arg1     = eaxismovenext;
                    op.arg1Type = eaxismovenext.valueType;
                    op.arg2     = new ASBinCode.rtData.RightValue(
                        new ASBinCode.rtData.rtString(loopbody));
                    op.arg2Type = RunTimeDataType.rt_string;

                    env.block.opSteps.Add(op);
                }
                {
                    ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token);
                    jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>();

                    ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token);
                    expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

                    ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token);
                    step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
                    step.OpCode = loopend;
                    expression.exprStepList.Add(step);

                    jumptoend.as3exprlist.Add(expression);
                    builder.buildStmt(env, jumptoend);
                }
                {
                    OpStep lbl_loopbody = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    lbl_loopbody.flag = loopbody;
                    env.block.opSteps.Add(lbl_loopbody);
                }

                {
                    RightValueBase loadValue = env.getAdditionalRegister();
                    ((StackSlotAccessor)loadValue).setEAXTypeWhenCompile(RunTimeDataType.rt_void);

                    //**IEnumerator Current()
                    OpStep opCurrent = new OpStep(OpCode.enumerator_current,
                                                  new SourceToken(as3foreach.Token.line,
                                                                  as3foreach.Token.ptr,
                                                                  as3foreach.Token.sourceFile)
                                                  );

                    opCurrent.reg      = (StackSlotAccessor)loadValue;
                    opCurrent.regType  = RunTimeDataType.rt_void;
                    opCurrent.arg1     = varSaveEnumerator;
                    opCurrent.arg1Type = varSaveEnumerator.valueType;

                    env.block.opSteps.Add(opCurrent);

                    if (varvalue.valueType != RunTimeDataType.rt_void)
                    {
                        loadValue = ExpressionBuilder.addCastOpStep(env, loadValue, varvalue.valueType,
                                                                    new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)
                                                                    ,
                                                                    builder
                                                                    );
                    }

                    var op = new OpStep(OpCode.assigning, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    op.reg      = varvalue;
                    op.regType  = varvalue.valueType;
                    op.arg1     = loadValue;
                    op.arg1Type = loadValue.valueType;
                    op.arg2     = null;
                    op.arg2Type = RunTimeDataType.unknown;

                    env.block.opSteps.Add(op);
                }
                if (as3foreach.Body != null)
                {
                    for (int i = 0; i < as3foreach.Body.Count; i++)
                    {
                        builder.buildStmt(env, as3foreach.Body[i]);
                    }
                }
                {
                    OpStep lbl_loopcontinue = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    lbl_loopcontinue.flag = loopcontinue;
                    env.block.opSteps.Add(lbl_loopcontinue);
                }
                {
                    //强行跳回开始
                    ASTool.AS3.AS3StmtExpressions jumptostart = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token);
                    jumptostart.as3exprlist = new List <ASTool.AS3.AS3Expression>();

                    ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token);
                    expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

                    ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token);
                    step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
                    step.OpCode = loopstart;
                    expression.exprStepList.Add(step);

                    jumptostart.as3exprlist.Add(expression);
                    builder.buildStmt(env, jumptostart);
                }
                {
                    //结束标记
                    OpStep lbl_loopend = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    lbl_loopend.flag = loopend;
                    env.block.opSteps.Add(lbl_loopend);
                }
                {
                    OpStep opClose = new OpStep(OpCode.enumerator_close, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    opClose.reg      = null;
                    opClose.regType  = RunTimeDataType.unknown;
                    opClose.arg1     = varSaveEnumerator;
                    opClose.arg1Type = RunTimeDataType.rt_void;
                    opClose.arg2     = null;
                    opClose.arg2Type = RunTimeDataType.rt_void;

                    env.block.opSteps.Add(opClose);
                }
            }
        }