public StackSlotAccessor buildAccessThisMember(ASTool.Token matchtoken, CompileEnv env)
        {
            if (!(member is VariableBase))
            {
                throw new BuildException(new BuildError(
                                             matchtoken.line, matchtoken.ptr,
                                             matchtoken.sourceFile, "包外数据期望一个Variable"));
            }

            VariableBase var = (VariableBase)member;

            var eax_member = env.getAdditionalRegister();

            eax_member.setEAXTypeWhenCompile(var.valueType);



            OpStep op = new OpStep(OpCode.link_outpackagevairable,
                                   new SourceToken(matchtoken.line, matchtoken.ptr, matchtoken.sourceFile));

            op.reg      = eax_member;
            op.regType  = eax_member.valueType;
            op.arg1     = var;
            op.arg1Type = var.valueType;

            op.arg2     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(outscopeclass.classid));
            op.arg2Type = RunTimeDataType.rt_int;


            env.block.opSteps.Add(op);



            return(eax_member);
        }
예제 #2
0
        public static void make_dotStep(CompileEnv env, ASBinCode.rtti.ClassMember member, ASTool.Token token,
                                        StackSlotAccessor eax, RightValueBase rvObj
                                        )
        {
            OpStep op = new OpStep(
                member.bindField is MethodGetterBase ?
                OpCode.access_method
                                :
                OpCode.access_dot

                , new SourceToken(token.line, token.ptr, token.sourceFile));


            RightValueBase field = (RightValueBase)member.bindField;



            op.reg      = eax; eax._isDotAccessTarget = true;
            op.regType  = eax.valueType;
            op.arg1     = rvObj;
            op.arg1Type = rvObj.valueType;
            op.arg2     = field;
            op.arg2Type = member.valueType;

            env.block.opSteps.Add(op);
        }
예제 #3
0
        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);
        }
        public LeftValueBase buildAccessThisMember(ASTool.Token matchtoken, CompileEnv env)
        {
            if (
                !(classMember.bindField is VariableBase)
                &&
                env.block.scope is ASBinCode.scopes.FunctionScope &&
                env.block.scope.parentScope is ASBinCode.scopes.ObjectInstanceScope
                &&
                ((ASBinCode.scopes.ObjectInstanceScope)env.block.scope.parentScope)._class == static_class._class
                )
            {
                return((LeftValueBase)classMember.bindField);
            }
            else
            {
                OpStep stepInitClass = new OpStep(OpCode.init_staticclass,
                                                  new SourceToken(matchtoken.line, matchtoken.ptr, matchtoken.sourceFile));
                stepInitClass.arg1 = new ASBinCode.rtData.RightValue(
                    new ASBinCode.rtData.rtInt(static_class._class.instanceClass.classid));
                stepInitClass.arg1Type = static_class._class.getRtType();
                env.block.opSteps.Add(stepInitClass);

                var _buildin_  = static_class;
                var eax_member = env.getAdditionalRegister();
                eax_member.setEAXTypeWhenCompile(classMember.valueType);

                eax_member._regMember       = classMember;
                eax_member._regMemberSrcObj = _buildin_;

                AccessBuilder.make_dotStep(env, classMember, matchtoken, eax_member, _buildin_);

                return(eax_member);
            }
        }
예제 #5
0
        public void buildCatchVariable(CompileEnv env, ASTool.AS3.AS3Catch c, int i, int tryid, Builder builder)
        {
            //Variable rtVariable =
            //    new Variable( "0"+ c.CatchVariable.Name + "_" + i + "_" + tryid

            //    , env.block.scope.members.Count);

            //rtVariable.valueType = TypeReader.fromSourceCodeStr(c.CatchVariable.TypeStr, env, c.CatchVariable.token);
            //env.block.scope.members.Add(rtVariable);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
        public void buildAS3YieldBreak(CompileEnv env, ASTool.AS3.AS3YieldBreak as3yieldbreak, Builder builder)
        {
            if (builder.buildingfunctons.Count > 0)
            {
                ASTool.AS3.AS3Function as3function = builder.buildingfunctons.Peek();
                if (as3function.IsConstructor)
                {
                    throw new BuildException(as3yieldbreak.Token.line, as3yieldbreak.Token.ptr, as3yieldbreak.Token.sourceFile,
                                             "构造函数不能用yield");
                }

                OpStep opyieldbreak = new OpStep(OpCode.yield_break, new SourceToken(as3yieldbreak.Token.line, as3yieldbreak.Token.ptr, as3yieldbreak.Token.sourceFile));
                env.block.opSteps.Add(opyieldbreak);
            }
            else
            {
                throw new BuildException(as3yieldbreak.Token.line, as3yieldbreak.Token.ptr, as3yieldbreak.Token.sourceFile,
                                         "yield break 只能在函数中");
            }
        }
        public void build_class(CompileEnv env,
                                ASBinCode.rtti.Class _class,
                                ASTool.Token token, Builder builder,
                                StackSlotAccessor outeax,
                                List <ASTool.AS3.Expr.AS3DataStackElement> args
                                )
        {
            //***查找构造函数**
            if (_class.constructor != null)
            {
                MethodGetterBase field = (MethodGetterBase)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index];
                int blockid            = field.refdefinedinblockid;

                var signature =
                    builder.dictSignatures[blockid][field];

                FuncCallBuilder funcbuilder = new FuncCallBuilder();
                funcbuilder.createParaOp(args, signature, token, env, field, builder, true, _class);
            }
            else
            {
                OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement,
                                               new SourceToken(token.line, token.ptr, 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(token.line, token.ptr, token.sourceFile));

            op.arg1     = new RightValue(new rtInt(_class.classid));
            op.arg1Type = _class.getRtType();

            outeax.setEAXTypeWhenCompile(_class.getRtType());
            op.reg     = outeax;
            op.regType = _class.getRtType();

            env.block.opSteps.Add(op);
        }
예제 #11
0
        public void buildInterfaceMembers(ASTool.AS3.AS3ClassInterfaceBase as3interface, Builder builder)
        {
            List <ASTool.AS3.IAS3Stmt> classstmts = as3interface.StamentsStack.Peek();

            var cls = builder.buildingclasses[as3interface];

            ASBinCode.CodeBlock block = new ASBinCode.CodeBlock(cls.blockid, cls.name, cls.classid, false);
            block.scope = new ASBinCode.scopes.ObjectInstanceScope(cls);

            CompileEnv env = new CompileEnv(block, false);

            builder._classbuildingEnv.Add(cls, env);



            for (int i = 0; i < classstmts.Count; i++)
            {
                buildInterfaceMember(env, classstmts[i], cls, builder);
            }

            //copyInheritsFromImplements(cls, env);
        }
        public static ASBinCode.rtti.ClassMember findClassMember(ASBinCode.rtti.Class cls,
                                                                 string name,
                                                                 CompileEnv env,
                                                                 Builder builder
                                                                 )
        {
            if (env.block.scope is ASBinCode.scopes.FunctionScope)
            {
                ASBinCode.scopes.FunctionScope funcscope = env.block.scope as ASBinCode.scopes.FunctionScope;

                if (!funcscope.function.IsAnonymous && funcscope.parentScope is ASBinCode.scopes.ObjectInstanceScope)
                {
                    return(ASBinCode.ClassMemberFinder.find(
                               cls, name,
                               ((ASBinCode.scopes.ObjectInstanceScope)funcscope.parentScope)._class));
                }
            }


            return(ASBinCode.ClassMemberFinder.find(cls, name,
                                                    builder.getClassByRunTimeDataType(ASBinCode.RunTimeDataType._OBJECT)
                                                    ));
        }
예제 #13
0
        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));
            }
        }
예제 #14
0
        public void build_class(CompileEnv env,
                                ASBinCode.rtti.Class _class,
                                ASTool.Token token, Builder builder,
                                StackSlotAccessor outeax,
                                List <ASTool.AS3.Expr.AS3DataStackElement> args
                                )
        {
            var _cls = _class;

            if (_cls.staticClass == null)
            {
                _cls = _cls.instanceClass;
            }
            if (_cls.isLink_System)
            {
                OpStep stepInitClass = new OpStep(OpCode.init_staticclass,
                                                  new SourceToken(token.line, token.ptr, token.sourceFile));
                stepInitClass.arg1 = new ASBinCode.rtData.RightValue(
                    new ASBinCode.rtData.rtInt(_cls.classid));
                stepInitClass.arg1Type = _cls.staticClass.getRtType();
                env.block.opSteps.Add(stepInitClass);
            }

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

                var signature =
                    builder.dictSignatures[blockid][field];

                FuncCallBuilder funcbuilder = new FuncCallBuilder();
                OpStep          opMakeArgs  = null;
                funcbuilder.createParaOp(out opMakeArgs, args, signature, token, env, field, builder, true, _class);

                if (_cls.isLink_System)
                {
                    if (signature.parameters.Count == 0)
                    {
                        opMakeArgs.opCode    = OpCode.prepare_constructor_argement_linksystem;
                        opMakeArgs.memregid1 = 0;
                    }
                    else
                    {
                        bool canconvert = true;
                        for (int i = 0; i < signature.parameters.Count; i++)
                        {
                            if (signature.parameters[i].defaultValue != null || signature.parameters[i].isPara)
                            {
                                canconvert = false;
                            }
                        }
                        if (canconvert)
                        {
                            opMakeArgs.opCode    = OpCode.prepare_constructor_argement_linksystem;
                            opMakeArgs.memregid1 = (short)signature.parameters.Count;
                        }
                    }
                }
            }
            else
            {
                OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement,
                                               new SourceToken(token.line, token.ptr, token.sourceFile));
                opMakeArgs.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid));
                opMakeArgs.arg1Type = RunTimeDataType.rt_int;
                env.block.opSteps.Add(opMakeArgs);

                if (_cls.isLink_System)
                {
                    opMakeArgs.opCode    = OpCode.prepare_constructor_argement_linksystem;
                    opMakeArgs.memregid1 = 0;
                }
            }

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

            op.arg1     = new RightValue(new rtInt(_class.classid));
            op.arg1Type = _class.getRtType();

            outeax.setEAXTypeWhenCompile(_class.getRtType());
            op.reg     = outeax;
            op.regType = _class.getRtType();

            env.block.opSteps.Add(op);
        }
예제 #15
0
        private void buildInterfaceMember(CompileEnv env,
                                          ASTool.AS3.IAS3Stmt stmt,
                                          ASBinCode.rtti.Class cls,
                                          Builder builder
                                          )
        {
            if (stmt is ASTool.AS3.AS3Block)
            {
                ASTool.AS3.AS3Block as3block = (ASTool.AS3.AS3Block)stmt;
                for (int i = 0; i < as3block.CodeList.Count; i++)
                {
                    buildInterfaceMember(env, as3block.CodeList[i], cls, builder);
                }
            }
            else if (stmt is ASTool.AS3.AS3Function)
            {
                ASTool.AS3.AS3Function as3function = (ASTool.AS3.AS3Function)stmt;

                {
                    if (!as3function.IsAnonymous)
                    {
                        //List<ASBinCode.rtti.ClassMember> tooverridefunctions = new List<ASBinCode.rtti.ClassMember>();


                        string funcname = as3function.Name;
                        if (as3function.IsGet || as3function.IsSet)
                        {
                            funcname = "@" + as3function.Name + (as3function.IsGet ? "_get" : "_set");
                        }

                        //for (int j = 0; j < cls.classMembers.Count; j++)
                        //{
                        //    if (cls.classMembers[j].name == funcname //as3function.Name
                        //        &&
                        //        (
                        //            cls.classMembers[j].inheritFrom == null
                        //            ||
                        //            (cls.classMembers[j].isPublic && as3function.Access.IsPublic
                        //            )
                        //        )
                        //        &&
                        //        (
                        //        cls.classMembers[j].inheritFrom != null
                        //        &&
                        //        !cls.classMembers[j].inheritFrom.classMembers[j].isConstructor
                        //        )
                        //        )
                        //    {
                        //        if (as3function.Access.IsOverride
                        //            )
                        //        {
                        //            if (!(cls.classMembers[j].bindField is ClassMethodGetter)
                        //                ||
                        //                cls.classMembers[j].inheritFrom.classMembers[j].isConstructor

                        //                )
                        //            {
                        //                throw new BuildException(
                        //                    new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                        //                                            "Method marked override must override another method.")
                        //                    );
                        //            }

                        //            if (cls.classMembers[j].isFinal)
                        //            {
                        //                throw new BuildException(
                        //                    new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                        //                                            "Cannot redefine a final method.")
                        //                    );
                        //            }


                        //            tooverridefunctions.Add(cls.classMembers[j]);
                        //            continue;
                        //        }

                        //        if (cls.classMembers[j].inheritFrom == null
                        //            )
                        //        {
                        //            throw new BuildException(
                        //                new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                        //                                        "重复的类成员:" + as3function.Name)
                        //                );
                        //        }
                        //        else
                        //        {
                        //            throw new BuildException(
                        //                new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                        //                                        "Overriding a function that is not marked for override")
                        //                );
                        //        }
                        //    }
                        //}

                        if (as3function.Access.IsStatic)
                        {
                            throw new BuildException(
                                      new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                     "The static attribute may be used only on definitions inside a class.")
                                      );
                        }


                        if (as3function.Access.IsOverride)
                        {
                            throw new BuildException(
                                      new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                     "The override attribute can only be used on a method defined in a class.")
                                      );
                        }


                        //***非访问器***
                        if (!as3function.IsGet && !as3function.IsSet)
                        {
                            ASBinCode.rtti.ClassMember member =
                                new ASBinCode.rtti.ClassMember(as3function.Name, cls,
                                                               new InterfaceMethodGetter(as3function.Name,
                                                                                         cls,
                                                                                         env.block.id)
                                                               );

                            member.setTypeWhenCompile(RunTimeDataType.rt_function);
                            member.isInternal = as3function.Access.IsInternal;
                            member.isPrivate  = as3function.Access.IsPrivate;
                            member.isProtectd = as3function.Access.IsProtected;
                            member.isPublic   = as3function.Access.IsPublic;
                            member.isStatic   = as3function.Access.IsStatic;
                            member.isConst    = true;

                            member.isOverride = as3function.Access.IsOverride;
                            member.isFinal    = as3function.Access.IsFinal;

                            member.isGetter = as3function.IsGet;
                            member.isSetter = as3function.IsSet;

                            member.isConstructor = as3function.IsConstructor;

                            if (member.isPrivate)
                            {
                                ((MethodGetterBase)member.bindField).setNotReadVirtual();
                            }

                            int s = 0;
                            if (member.isPrivate)
                            {
                                s++;
                            }
                            if (member.isPublic)
                            {
                                s++;
                            }
                            if (member.isProtectd)
                            {
                                s++;
                            }
                            if (member.isInternal)
                            {
                                s++;
                            }

                            if (s != 0)
                            {
                                throw new BuildException(
                                          new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                         "Members of an interface cannot be declared public, private, protected, or internal.")
                                          );
                            }

                            member.isPublic = true;

                            if (as3function.FunctionBody.Nodes.Count > 0)
                            {
                                throw new BuildException(
                                          new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                         "Methods defined in an interface must not have a body.")
                                          );
                            }

                            cls.classMembers.Add(member);

                            builder._buildingmembers.Add(member, as3function);
                        }
                        else
                        {
                            ASBinCode.rtti.ClassMember member =
                                new ASBinCode.rtti.ClassMember("@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"), cls,
                                                               new InterfaceMethodGetter("@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"),
                                                                                         cls,
                                                                                         env.block.id)
                                                               );

                            member.setTypeWhenCompile(RunTimeDataType.rt_function);
                            member.isInternal = as3function.Access.IsInternal;
                            member.isPrivate  = as3function.Access.IsPrivate;
                            member.isProtectd = as3function.Access.IsProtected;
                            member.isPublic   = as3function.Access.IsPublic;
                            member.isStatic   = as3function.Access.IsStatic;
                            member.isConst    = true;

                            member.isOverride = as3function.Access.IsOverride;
                            member.isFinal    = as3function.Access.IsFinal;

                            member.isGetter = as3function.IsGet;
                            member.isSetter = as3function.IsSet;

                            member.isConstructor = as3function.IsConstructor;

                            if (member.isGetter && member.isSetter)
                            {
                                throw new BuildException(
                                          new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                         "不能同时是getter和setter")
                                          );
                            }



                            int s = 0;
                            if (member.isPrivate)
                            {
                                s++;
                            }
                            if (member.isPublic)
                            {
                                s++;
                            }
                            if (member.isProtectd)
                            {
                                s++;
                            }
                            if (member.isInternal)
                            {
                                s++;
                            }

                            if (s != 0)
                            {
                                throw new BuildException(
                                          new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                         "Members of an interface cannot be declared public, private, protected, or internal.")
                                          );
                            }

                            member.isPublic = true;

                            if (as3function.FunctionBody.Nodes.Count > 0)
                            {
                                throw new BuildException(
                                          new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                         "Methods defined in an interface must not have a body.")
                                          );
                            }

                            cls.classMembers.Add(member);
                            builder._buildingmembers.Add(member, as3function);



                            //***查找ClassPropertyGetter****
                            ClassPropertyGetter pg = null;

                            for (int i = 0; i < cls.classMembers.Count; i++)
                            {
                                if (cls.classMembers[i].name == as3function.Name && cls.classMembers[i].inheritFrom == null)
                                {
                                    if (cls.classMembers[i].bindField is ClassPropertyGetter)
                                    {
                                        pg = (ClassPropertyGetter)cls.classMembers[i].bindField;

                                        if (member.isGetter && pg.getter != null
                                            &&
                                            cls.classMembers[pg.getter.indexOfMembers].inheritFrom == null

                                            )
                                        {
                                            throw new BuildException(
                                                      new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                                     "属性访问器重复")
                                                      );
                                        }
                                        else if (member.isSetter && pg.setter != null
                                                 &&
                                                 cls.classMembers[pg.setter.indexOfMembers].inheritFrom == null
                                                 )
                                        {
                                            throw new BuildException(
                                                      new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                                     "属性设置器重复")
                                                      );
                                        }
                                    }
                                    else
                                    {
                                        throw new BuildException(
                                                  new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                                 "期望一个属性")
                                                  );
                                    }
                                }
                            }

                            if (pg == null)
                            {
                                pg = new ClassPropertyGetter(as3function.Name, cls, cls.classMembers.Count);
                                ASBinCode.rtti.ClassMember m = new ASBinCode.rtti.ClassMember(as3function.Name, cls, pg);

                                cls.classMembers.Add(m);
                                m.isPublic = true;
                                m.isStatic = member.isStatic;
                            }
                            if (member.isGetter)
                            {
                                pg.getter = (MethodGetterBase)member.bindField;
                            }
                            else
                            {
                                pg.setter = (MethodGetterBase)member.bindField;
                            }
                        }
                    }
                    else
                    {
                        throw new BuildException(
                                  new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                                 "'function' is not allowed here")
                                  );
                    }
                }
            }
            else if (stmt is ASTool.AS3.AS3Variable)
            {
                //字段 数据成员
                throw new BuildException(
                          new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                         "A 'var' declaration is not permitted in an interface.")
                          );
                //
            }
            else if (stmt is ASTool.AS3.AS3Const)
            {
                throw new BuildException(
                          new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                         "A 'const' declaration is not permitted in an interface.")
                          );
            }
            else
            {
                throw new BuildException(
                          new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile,
                                         "接口成员中不能出现" + stmt)
                          );
            }
        }
예제 #16
0
        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 static ASBinCode.IMember find(string name, CompileEnv env, bool isStaticMember, Builder builder, ASTool.Token token)
        {
            //List<IScope> findpath = new List<IScope>();
            //List<IScope> outscopes = new List<IScope>();//查找顺序,最后查找包外代码

            //Dictionary<IScope, ASBinCode.rtti.Class> finderclass = new Dictionary<IScope, ASBinCode.rtti.Class>();



            //{
            //    ASBinCode.rtti.Class defineClass = null;
            //    IScope s = env.block.scope;
            //    while (s !=null)
            //    {
            //        if (s is ASBinCode.scopes.ObjectInstanceScope)
            //        {
            //            ASBinCode.rtti.Class cls = ((ASBinCode.scopes.ObjectInstanceScope)s)._class;
            //            if (isStaticMember && cls.staticClass != null)
            //            {
            //                cls = cls.staticClass;
            //            }
            //            if (defineClass == null)
            //            {
            //                defineClass = cls;
            //                if (cls.mainClass != null)
            //                {
            //                    defineClass = cls.mainClass;
            //                }

            //            }
            //        }
            //        finderclass.Add(s,defineClass);

            //        if (s is ASBinCode.scopes.OutPackageMemberScope && !(ReferenceEquals(s,env.block.scope)))
            //        {
            //            outscopes.Add(s);

            //        }
            //        else
            //        {
            //            findpath.Add(s);
            //        }

            //        s = s.parentScope;
            //    }

            //    findpath.AddRange(outscopes);
            //}



            //ASBinCode.IScope scope = null;
            //for (int j = 0; j < findpath.Count; j++)
            //{
            //    scope = findpath[j];

            //    if (scope is ASBinCode.scopes.ObjectInstanceScope)
            //    {
            //        //查找类方法
            //        ASBinCode.rtti.Class cls = ((ASBinCode.scopes.ObjectInstanceScope)scope)._class;

            //        var fm = ASBinCode.ClassMemberFinder.find(cls, name, finderclass[scope]);
            //        if (fm != null)
            //        {
            //            return fm.bindField;
            //        }

            //    }

            //    if (!(scope is ASBinCode.scopes.OutPackageMemberScope)
            //        ||
            //        (
            //            finderclass[scope] == null
            //            ||
            //            ((ASBinCode.scopes.OutPackageMemberScope)scope).mainclass == finderclass[scope]
            //        )
            //        )
            //    {
            //        //从后往前找。可解决catch块同名变量e问题
            //        for (int i = scope.members.Count - 1; i >= 0; i--)
            //        {
            //            if (scope.members[i].name == name
            //                )
            //            {
            //                return scope.members[i].clone();
            //            }
            //        }
            //    }


            //}
            bool skipoutpackagescope = false;

            ASBinCode.rtti.Class defineClass = null;

            ASBinCode.IScope scope = env.block.scope;

            while (scope != null)
            {
                if (scope is ASBinCode.scopes.ObjectInstanceScope)
                {
                    //查找类方法
                    ASBinCode.rtti.Class cls = ((ASBinCode.scopes.ObjectInstanceScope)scope)._class;

                    if (defineClass == null)
                    {
                        defineClass = cls;
                    }

                    if (!isStaticMember && cls.staticClass == null)
                    {
                        defineClass         = defineClass.instanceClass;
                        skipoutpackagescope = true;
                        break;
                    }
                    else
                    {
                        var fm = ASBinCode.ClassMemberFinder.find(cls, name, defineClass);
                        if (fm != null)
                        {
                            return(fm.bindField);
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (!(scope is ASBinCode.scopes.OutPackageMemberScope)
                    ||
                    (
                        defineClass == null
                        ||
                        ((ASBinCode.scopes.OutPackageMemberScope)scope).mainclass == defineClass
                    )
                    )
                {
                    //从后往前找。可解决catch块同名变量e问题
                    for (int i = scope.members.Count - 1; i >= 0; i--)
                    {
                        if (scope.members[i].name == name
                            )
                        {
                            return(scope.members[i].clone());
                        }
                    }
                }
                scope = scope.parentScope;
            }

            //***如果成员未找到,查找@__buildin__//
            if (!env.isEval)
            {
                var buildin = TypeReader.findClassFromImports("@__buildin__", builder, token);
                if (buildin.Count == 1)
                {
                    var bi = buildin[0].staticClass;

                    var member = ClassMemberFinder.find(bi, name, bi);
                    if (member != null && !(member.bindField is ClassPropertyGetter) && member.inheritFrom == null
                        &&
                        member.name != "Object"
                        )
                    {
                        FindStaticMember sm = new FindStaticMember();
                        sm.classMember  = member;
                        sm.static_class = new StaticClassDataGetter(bi);

                        return(sm);
                        //return member.bindField;
                    }
                }
            }

            //***在静态成员中查找***
            var findstaticclass = defineClass;


            while (findstaticclass != null && findstaticclass.staticClass != null)
            {
                var bi     = findstaticclass.staticClass;
                var member = ClassMemberFinder.find(bi, name, defineClass.staticClass);
                if (member != null)
                {
                    if (member != null && member.bindField is ClassPropertyGetter && name == "prototype")
                    {
                        throw new BuildException(token.line, token.ptr, token.sourceFile, "Access of possibly undefined property prototype.");
                    }

                    FindStaticMember sm = new FindStaticMember();
                    sm.classMember  = member;
                    sm.static_class = new StaticClassDataGetter(bi);


                    return(sm);
                    //return member.bindField;
                }
                findstaticclass = findstaticclass.super;
            }

            if (skipoutpackagescope)
            {
                return(null);
            }


            if (defineClass != null && defineClass.mainClass != null)
            {
                defineClass = defineClass.mainClass;
            }

            //***在包外代码中查找****
            if (defineClass != null && defineClass.staticClass != null)
            {
                IScope outpackagescope = null;

                if (defineClass.mainClass == null)
                {
                    outpackagescope =
                        builder._class_outScopeBlock[defineClass].scope;
                }
                else
                {
                    outpackagescope =
                        builder._class_outScopeBlock[defineClass.mainClass].scope;
                }

                for (int i = outpackagescope.members.Count - 1; i >= 0; i--)
                {
                    if (outpackagescope.members[i].name == name
                        )
                    {
                        //return outpackagescope.members[i].clone();
                        FindOutPackageScopeMember fo = new FindOutPackageScopeMember();
                        fo.member = outpackagescope.members[i].clone();


                        fo.outscopeclass = ((ASBinCode.scopes.OutPackageMemberScope)outpackagescope).mainclass;

                        return(fo);
                        //return fo;
                    }
                }
            }



            return(null);
        }
예제 #18
0
        public static ASBinCode.RunTimeValueBase Eval(ASTool.AS3.AS3Expression expression,
                                                      Builder importBuilder = null
                                                      )
        {
            try
            {
                Builder builder = new Builder(new BuildOptions()
                {
                    isConsoleOut = false
                }, true);

                int bid = builder.getBlockId();

                if (importBuilder != null && importBuilder._currentImports.Count > 0)
                {
                    List <ASBinCode.rtti.Class> imps = new List <ASBinCode.rtti.Class>();
                    imps.AddRange(importBuilder._currentImports.Peek());

                    builder._currentImports.Push(imps);

                    bid = importBuilder.bin.blocks.Count;
                }

                CompileEnv tempEnv = new CompileEnv(new CodeBlock(bid, "temp", -65535, true), true);
                tempEnv.block.scope = new ASBinCode.scopes.StartUpBlockScope();
                builder.buildExpressNotEval(tempEnv, expression);

                tempEnv.completSteps(builder);
                tempEnv.block.totalStackSlots = tempEnv.combieNeedStackSlots();

                if (builder.buildErrors.Count == 0)
                {
                    RightValueBase value = builds.ExpressionBuilder.getRightValue(tempEnv, expression.Value, expression.token, builder);

                    if (player == null)
                    {
                        player = new ASRuntime.Player(null);
                    }
                    CSWC tempswc = new CSWC();
                    if (importBuilder != null)
                    {
                        tempswc.blocks.AddRange(importBuilder.bin.blocks);
                        tempswc.classes.AddRange(importBuilder.bin.classes);
                        tempswc.functions.AddRange(importBuilder.bin.functions);
                    }
                    tempswc.blocks.Add(tempEnv.block);

                    Variable variableResult = new Variable("@@", tempEnv.block.scope.members.Count, tempEnv.block.id);
                    tempEnv.block.scope.members.Add(variableResult);
                    OpStep step = new OpStep(OpCode.assigning, new SourceToken(0, 0, ""));
                    step.reg  = variableResult;
                    step.arg1 = value;
                    tempEnv.block.opSteps.Add(step);
                    tempEnv.block.instructions = tempEnv.block.opSteps.ToArray();
                    tempEnv.block.opSteps      = null;
                    player.loadCode(tempswc, tempEnv.block);

                    RunTimeValueBase result = player.run(variableResult);

                    return(result);
                    //IRunTimeScope scope = player.run();

                    //if (player.runtimeError ==null)
                    //{
                    //    return value.getValue(scope);
                    //}
                    //else
                    //{
                    //    return null;
                    //}
                }
                else
                {
                    return(null);
                }
            }
            catch (BuildException)
            {
                return(null);
            }
        }
        public void buildAS3Break(CompileEnv env, ASTool.AS3.AS3Break as3break)
        {
            if (string.IsNullOrEmpty(as3break.breakFlag))
            {
                //throw new BuildException(as3break.Token.line, as3break.Token.ptr, as3break.Token.sourceFile,
                //                    "语句关联break尚未实现");
                //***向上查找

                //int l = 0;
                Stack <string> flagstack = new Stack <string>();

                for (int i = env.block.opSteps.Count - 1; i >= 0; i--)
                {
                    var s = env.block.opSteps[i];
                    if (s.opCode == OpCode.flag)
                    {
                        if (s.flag.StartsWith("LOOP_END_") || s.flag.StartsWith("SWITCH_END_"))
                        {
                            flagstack.Push(s.flag);
                            //l--;
                        }

                        if (s.flag.StartsWith("LOOP_START_") || s.flag.StartsWith("SWITCH_START_"))
                        {
                            if (flagstack.Count == 0)
                            {
                                string header = null;
                                if (s.flag.StartsWith("LOOP_START_"))
                                {
                                    header = "LOOP_END_";
                                }
                                else
                                {
                                    header = "SWITCH_END_";
                                }

                                string id = s.flag.Substring(header.Length + 2);

                                //label标记跳转
                                OpStep op = new OpStep(OpCode.jmp, new SourceToken(as3break.Token.line, as3break.Token.ptr, as3break.Token.sourceFile));
                                op.reg     = null;
                                op.regType = RunTimeDataType.unknown;
                                op.arg1    = new ASBinCode.rtData.RightValue(
                                    new ASBinCode.rtData.rtString(header + id));
                                op.arg1Type = RunTimeDataType.rt_string;
                                op.arg2     = null;
                                op.arg2Type = RunTimeDataType.unknown;

                                env.block.opSteps.Add(op);

                                return;
                            }
                            else
                            {
                                string p = flagstack.Pop();
                                if ((p.StartsWith("LOOP_END_") && s.flag.StartsWith("LOOP_START_"))
                                    ||
                                    (p.StartsWith("SWITCH_END_") && s.flag.StartsWith("SWITCH_START_")))

                                {
                                }
                                else
                                {
                                    throw new BuildException(as3break.Token.line, as3break.Token.ptr, as3break.Token.sourceFile, "switch或loop开关不匹配");
                                }
                                //l++;
                            }
                        }
                    }
                }

                throw new BuildException(as3break.Token.line, as3break.Token.ptr, as3break.Token.sourceFile,
                                         "break的关联块未找到");
            }
            else
            {
                //语句块break

                int l = 0;
                for (int i = 0; i < env.block.opSteps.Count; i++)
                {
                    var s = env.block.opSteps[i];
                    if (s.opCode == OpCode.flag)
                    {
                        if (s.flag == "Label" + env.labelblocks + "_End_" + as3break.breakFlag)
                        {
                            l--;
                        }
                        else if (s.flag == "Label" + env.labelblocks + "_Start_" + as3break.breakFlag)
                        {
                            l++;
                        }
                    }
                }
                if (l < 1)
                {
                    throw new BuildException(as3break.Token.line, as3break.Token.ptr, as3break.Token.sourceFile,
                                             "break的关联标记[" + as3break.breakFlag + "]未找到");
                }

                //label标记跳转
                OpStep op = new OpStep(OpCode.jmp, new SourceToken(as3break.Token.line, as3break.Token.ptr, as3break.Token.sourceFile));
                op.reg     = null;
                op.regType = RunTimeDataType.unknown;
                op.arg1    = new ASBinCode.rtData.RightValue(
                    new ASBinCode.rtData.rtString("Label" + env.labelblocks + "_End_" + as3break.breakFlag));
                op.arg1Type = RunTimeDataType.rt_string;
                op.arg2     = null;
                op.arg2Type = RunTimeDataType.unknown;

                env.block.opSteps.Add(op);
            }
        }
예제 #20
0
        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);
                }
            }
        }
예제 #21
0
        public void buildAS3Throw(CompileEnv env, ASTool.AS3.AS3Throw as3throw, Builder builder)
        {
            if (as3throw.Exception != null)
            {
                var testV = ExpressionEval.Eval(as3throw.Exception);
                if (testV != null && as3throw.Exception.Value.IsReg)
                {
                    OpStep op = new OpStep(OpCode.raise_error, new SourceToken(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile));

                    op.arg1     = new ASBinCode.rtData.RightValue(testV);
                    op.arg1Type = testV.rtType;
                    op.arg2     = null;
                    op.arg2Type = RunTimeDataType.unknown;
                    op.reg      = null;
                    op.regType  = RunTimeDataType.unknown;

                    env.block.opSteps.Add(op);
                }
                else
                {
                    builder.buildExpression(env, as3throw.Exception);

                    OpStep op = new OpStep(OpCode.raise_error, new SourceToken(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile));

                    RightValueBase lv = builds.ExpressionBuilder.getRightValue(env, as3throw.Exception.Value, as3throw.Token, builder);
                    op.arg1     = lv;
                    op.arg1Type = lv.valueType;
                    op.arg2     = null;
                    op.arg2Type = RunTimeDataType.unknown;
                    op.reg      = null;
                    op.regType  = RunTimeDataType.unknown;

                    env.block.opSteps.Add(op);
                }
            }
            else
            {
                //***只有在catch块中才能throw***;
                int l = 0;
                for (int i = 0; i < env.block.opSteps.Count; i++)
                {
                    if (env.block.opSteps[i].opCode == OpCode.enter_catch)
                    {
                        l++;
                    }
                    else if (env.block.opSteps[i].opCode == OpCode.quit_catch)
                    {
                        l--;
                    }
                }

                if (l < 1)
                {
                    throw new BuildException(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile,
                                             "此处不能有throw;"
                                             );
                }

                throw new BuildException(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile,
                                         "throw必须有抛出的对象;"
                                         );

                //OpStep op = new OpStep(OpCode.raise_error, new SourceToken(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile));

                //op.arg1 = null;
                //op.arg1Type =  RunTimeDataType.unknown;
                //op.arg2 = null;
                //op.arg2Type = RunTimeDataType.unknown;
                //op.reg = null;
                //op.regType = RunTimeDataType.unknown;

                //env.block.opSteps.Add(op);
            }
        }
예제 #22
0
        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);
            }
        }
예제 #23
0
        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));
            }
        }
예제 #24
0
        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);
            }
        }
예제 #25
0
        //private int trydepth;
        public void buildAS3Try(CompileEnv env, ASTool.AS3.AS3Try as3try, Builder builder)
        {
            //***先编译Try块
            //trydepth++;
            int tryid = as3try.holdTryId;

            //string LBL_BEGIN_TRY = "BEGIN_TRY_" + tryid;
            //string LBL_END_TRY = "END_TRY_" + tryid;
            string LBL_BEGIN_FINALLY = "BEGIN_FINALLY_" + tryid;
            string LBL_END_FINALLY   = "END_FINALLY_" + tryid;

            string LBL_CATCH = "BEGIN_CATCH_" + tryid;

            //OpStep begintry = new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));
            //begintry.flag = LBL_BEGIN_TRY;
            //env.block.opSteps.Add(begintry);

            //**包装一个block**
            ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3try.Token);
            tempblock.CodeList = as3try.TryBlock;
            tempblock.label    = as3try.label;

            {
                OpStep enter_try = new OpStep(OpCode.enter_try, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));
                enter_try.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid));
                enter_try.arg1Type = RunTimeDataType.rt_int;
                env.block.opSteps.Add(enter_try);
            }


            builder.buildStmt(env, tempblock);

            {
                OpStep quit_try = new OpStep(OpCode.quit_try, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));
                quit_try.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid));
                quit_try.arg1Type = RunTimeDataType.rt_int;
                env.block.opSteps.Add(quit_try);
            }

            //OpStep endtry= new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));
            //endtry.flag = LBL_END_TRY;
            //env.block.opSteps.Add(endtry);

            //***跳转到Finally块***
            {
                jumpTo(env, as3try, builder, LBL_BEGIN_FINALLY);
            }

            OpStep startCatch = new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));

            startCatch.flag = LBL_CATCH;
            env.block.opSteps.Add(startCatch);



            //***编译Catch块***
            for (int i = 0; i < as3try.CatchList.Count; i++)
            {
                var c = as3try.CatchList[i];
                //c.CatchVariable.Name = "0"+c.CatchVariable.Name + "_" + i;


                VariableBase rtVariable = new Variable(c.CatchVariable.Name, env.block.scope.members.Count, true, env.block.id);
                rtVariable.valueType = TypeReader.fromSourceCodeStr(c.CatchVariable.TypeStr, c.CatchVariable.token, builder);
                env.block.scope.members.Add(rtVariable);

                //builder.buildVariables(env, c.CatchVariable);
                //string catchvariablename = "0" + c.CatchVariable.Name + "_" + i + "_" + tryid;
                //Variable rtVariable = (Variable)MemberFinder.find(catchvariablename, env);
                //rtVariable.resetName(c.CatchVariable.Name);

                //rtVariable.valueType = RunTimeDataType.rt_void;

                OpStep op = new OpStep(OpCode.catch_error,
                                       new SourceToken(c.CatchVariable.token.line,
                                                       c.CatchVariable.token.ptr, c.CatchVariable.token.sourceFile));
                op.reg      = rtVariable;
                op.regType  = TypeReader.fromSourceCodeStr(c.CatchVariable.TypeStr, c.CatchVariable.token, builder);
                op.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid));
                op.arg1Type = RunTimeDataType.rt_int;
                op.arg2     = null;
                op.arg2Type = RunTimeDataType.unknown;

                env.block.opSteps.Add(op);

                {
                    OpStep enter_catch = new OpStep(OpCode.enter_catch, new SourceToken(c.CatchVariable.token.line, c.CatchVariable.token.ptr, c.CatchVariable.token.sourceFile));
                    enter_catch.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid));
                    enter_catch.arg1Type = RunTimeDataType.rt_int;
                    env.block.opSteps.Add(enter_catch);
                }

                int bstidx = env.block.opSteps.Count;
                for (int j = 0; j < c.CatchBlock.Count; j++)
                {
                    builder.buildStmt(env, c.CatchBlock[j]);
                }

                for (int k = bstidx; k < env.block.opSteps.Count; k++)
                {
                    var oop = env.block.opSteps[k];
                    if (Equals(oop.reg, rtVariable))
                    {
                        ((Variable)oop.reg).resetName("0" + rtVariable.name + "_" + i + "_" + tryid);
                    }
                    if (Equals(oop.arg1, rtVariable))
                    {
                        ((Variable)oop.arg1).resetName("0" + rtVariable.name + "_" + i + "_" + tryid);
                    }
                    if (Equals(oop.arg2, rtVariable))
                    {
                        ((Variable)oop.arg2).resetName("0" + rtVariable.name + "_" + i + "_" + tryid);
                    }
                }

                rtVariable.resetName("0" + rtVariable.name + "_" + i + "_" + tryid);

                {
                    OpStep quit_catch = new OpStep(OpCode.quit_catch, new SourceToken(c.CatchVariable.token.line, c.CatchVariable.token.ptr, c.CatchVariable.token.sourceFile));
                    quit_catch.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid));
                    quit_catch.arg1Type = RunTimeDataType.rt_int;
                    env.block.opSteps.Add(quit_catch);
                }

                {
                    jumpTo(env, as3try, builder, LBL_BEGIN_FINALLY);
                }
            }

            //FINALLY
            {
                OpStep finallylbl = new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));
                finallylbl.flag = LBL_BEGIN_FINALLY;
                env.block.opSteps.Add(finallylbl);

                {
                    OpStep enter_finally = new OpStep(OpCode.enter_finally, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));
                    enter_finally.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid));
                    enter_finally.arg1Type = RunTimeDataType.rt_int;
                    env.block.opSteps.Add(enter_finally);
                }

                if (as3try.FinallyBlock != null)
                {
                    for (int i = 0; i < as3try.FinallyBlock.Count; i++)
                    {
                        builder.buildStmt(env, as3try.FinallyBlock[i]);
                    }
                }
                else
                {
                    if (as3try.CatchList.Count == 0)
                    {
                        throw new BuildException(as3try.Token.line,
                                                 as3try.Token.ptr,
                                                 as3try.Token.sourceFile, "try块至少要有1个catch块或1个finally块.");
                    }
                }

                {
                    OpStep quit_finally = new OpStep(OpCode.quit_finally, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));
                    quit_finally.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid));
                    quit_finally.arg1Type = RunTimeDataType.rt_int;
                    env.block.opSteps.Add(quit_finally);
                }

                OpStep endfinally = new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile));
                endfinally.flag = LBL_END_FINALLY;
                env.block.opSteps.Add(endfinally);
            }

            //trydepth--;



            //throw new BuildException(as3try.Token.line,as3try.Token.ptr,as3try.Token.sourceFile,"try catch finally编译没实现");
        }
예제 #26
0
        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);
        }
예제 #27
0
        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"));
            }
        }
예제 #28
0
        public void buildAS3Continue(CompileEnv env, ASTool.AS3.AS3Continue as3continue, Builder builder)
        {
            if (string.IsNullOrEmpty(as3continue.continueFlag))
            {
                int l = 0;

                for (int i = env.block.opSteps.Count - 1; i >= 0; i--)
                {
                    var s = env.block.opSteps[i];
                    if (s.opCode == OpCode.flag)
                    {
                        if (s.flag.StartsWith("LOOP_END_"))
                        {
                            l--;
                        }

                        if (s.flag.StartsWith("LOOP_START_"))
                        {
                            if (l == 0)
                            {
                                string id = s.flag.Substring(11);

                                //label标记跳转
                                OpStep op = new OpStep(OpCode.jmp, new SourceToken(as3continue.Token.line, as3continue.Token.ptr, as3continue.Token.sourceFile));
                                op.reg     = null;
                                op.regType = RunTimeDataType.unknown;
                                op.arg1    = new ASBinCode.rtData.RightValue(
                                    new ASBinCode.rtData.rtString("LOOP_CONTINUE_" + id));

                                op.arg1Type = RunTimeDataType.rt_string;
                                op.arg2     = null;
                                op.arg2Type = RunTimeDataType.unknown;

                                env.block.opSteps.Add(op);

                                return;
                            }
                            else
                            {
                                l++;
                            }
                        }
                    }
                }

                throw new BuildException(as3continue.Token.line, as3continue.Token.ptr, as3continue.Token.sourceFile,
                                         "continue的关联块未找到");
            }
            else
            {
                //命名label的continue;
                int l     = 0;
                int stidx = 0;
                for (int i = 0; i < env.block.opSteps.Count; i++)
                {
                    var s = env.block.opSteps[i];
                    if (s.opCode == OpCode.flag)
                    {
                        if (s.flag == "LOOP_LABEL_END_" + as3continue.continueFlag)
                        {
                            l--;
                        }
                        else if (s.flag == "LOOP_LABEL_START_" + as3continue.continueFlag)
                        {
                            l++;
                            stidx = i;
                        }
                    }
                }
                if (l < 1)
                {
                    throw new BuildException(as3continue.Token.line, as3continue.Token.ptr, as3continue.Token.sourceFile,
                                             "continue的关联标记[" + as3continue.continueFlag + "]未找到");
                }

                //**查找关联的循环**
                for (int i = stidx; i < env.block.opSteps.Count; i++)
                {
                    var s = env.block.opSteps[i];
                    if (s.opCode == OpCode.flag)
                    {
                        if (s.flag.StartsWith("LOOP_START_"))
                        {
                            string id = s.flag.Substring(11);

                            //label标记跳转
                            OpStep op = new OpStep(OpCode.jmp, new SourceToken(as3continue.Token.line, as3continue.Token.ptr, as3continue.Token.sourceFile));
                            op.reg     = null;
                            op.regType = RunTimeDataType.unknown;
                            op.arg1    = new ASBinCode.rtData.RightValue(
                                new ASBinCode.rtData.rtString("LOOP_CONTINUE_" + id));

                            op.arg1Type = RunTimeDataType.rt_string;
                            op.arg2     = null;
                            op.arg2Type = RunTimeDataType.unknown;

                            env.block.opSteps.Add(op);

                            return;
                        }
                    }
                }

                throw new BuildException(as3continue.Token.line, as3continue.Token.ptr, as3continue.Token.sourceFile,
                                         "continue的关联标记[" + as3continue.continueFlag + "]未找到");
            }
        }
예제 #29
0
        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);
                }
            }
        }