コード例 #1
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);
                }
            }
        }
コード例 #2
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)
                          );
            }
        }
コード例 #3
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);
            }
        }
コード例 #4
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);
                }
            }
        }
コード例 #5
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);
                }
            }
        }
コード例 #6
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编译没实现");
        }