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); } } }
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) ); } }
public void buildAS3Switch(CompileEnv env, ASTool.AS3.AS3Switch as3switch, Builder builder) { if (!string.IsNullOrEmpty(as3switch.label)) { //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3switch.Token); tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>(); tempblock.CodeList.Add(as3switch); tempblock.label = as3switch.label; as3switch.label = null; builder.buildStmt(env, tempblock); } else { //***先编译条件*** ASTool.AS3.AS3StmtExpressions expressions = new ASTool.AS3.AS3StmtExpressions(as3switch.Token); expressions.as3exprlist = new List <ASTool.AS3.AS3Expression>(); expressions.as3exprlist.Add(as3switch.Expr); builder.buildStmt(env, expressions); //**取判断条件*** ASTool.AS3.AS3Expression expr = as3switch.Expr; int defaults = 0; for (int i = 0; i < as3switch.CaseList.Count; i++) { ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i]; if (c.IsDefault) { defaults++; } if (defaults > 1) { throw new BuildException(c.token.line, c.token.ptr, c.token.sourceFile, "switch只能有1个default:"); } } List <string> switchlabels = new List <string>(); for (int i = 0; i < as3switch.CaseList.Count; i++) { ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i]; if (!c.IsDefault) { switchlabels.Add(env.makeLabel("SWITCH_CASE")); } else { switchlabels.Add(env.makeLabel("SWITCH_DEFAULT")); } } for (int i = 0; i < as3switch.CaseList.Count; i++) { ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i]; if (!c.IsDefault) { RunTimeValueBase v = ExpressionEval.Eval(c.Condition); if (v != null && c.Condition.Value.IsReg) { OpStep op = new OpStep(OpCode.assigning, new SourceToken(c.token.line, c.token.ptr, c.token.sourceFile)); var eax = env.createASTRegister(c.Condition.Value.Reg); eax.setEAXTypeWhenCompile(v.rtType); op.reg = eax; op.regType = eax.valueType; op.arg1 = new ASBinCode.rtData.RightValue(v); op.arg1Type = v.rtType; env.block.opSteps.Add(op); } else { ASTool.AS3.AS3StmtExpressions caseExpr = new ASTool.AS3.AS3StmtExpressions(c.token); caseExpr.as3exprlist = new List <ASTool.AS3.AS3Expression>(); caseExpr.as3exprlist.Add(c.Condition); builder.buildStmt(env, caseExpr); } { ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token); step.Type = ASTool.AS3.Expr.OpType.LogicEQ; step.OpCode = "=="; step.Arg1 = c.holdreg; step.Arg2 = expr.Value; step.Arg3 = c.Condition.Value; ASTool.AS3.AS3StmtExpressions compare = new ASTool.AS3.AS3StmtExpressions(c.token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(c.token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); expression.exprStepList.Add(step); expression.Value = c.holdreg; compare.as3exprlist = new List <ASTool.AS3.AS3Expression>(); compare.as3exprlist.Add(expression); builder.buildStmt(env, compare); } { ASTool.AS3.AS3StmtExpressions conditionsJump = new ASTool.AS3.AS3StmtExpressions(c.token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(c.token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token); step.Type = ASTool.AS3.Expr.OpType.IF_GotoFlag; step.OpCode = switchlabels[i]; step.Arg1 = c.holdreg; expression.exprStepList.Add(step); conditionsJump.as3exprlist = new List <ASTool.AS3.AS3Expression>(); conditionsJump.as3exprlist.Add(expression); builder.buildStmt(env, conditionsJump); } } else { ASTool.AS3.AS3StmtExpressions jump = new ASTool.AS3.AS3StmtExpressions(c.token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(c.token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = switchlabels[i]; expression.exprStepList.Add(step); jump.as3exprlist = new List <ASTool.AS3.AS3Expression>(); jump.as3exprlist.Add(expression); builder.buildStmt(env, jump); } } int lblid = env.getLabelId(); OpStep lbl_case_start = new OpStep(OpCode.flag, new SourceToken(as3switch.Token.line, as3switch.Token.ptr, as3switch.Token.sourceFile)); lbl_case_start.flag = "SWITCH_START_" + lblid; env.block.opSteps.Add(lbl_case_start); for (int i = 0; i < as3switch.CaseList.Count; i++) { ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i]; //if (!c.IsDefault) { OpStep lbl_case = new OpStep(OpCode.flag, new SourceToken(c.token.line, c.token.ptr, c.token.sourceFile)); lbl_case.flag = switchlabels[i]; env.block.opSteps.Add(lbl_case); } if (c.Body != null) { for (int j = 0; j < c.Body.Count; j++) { builder.buildStmt(env, c.Body[j]); } } } OpStep lbl_case_end = new OpStep(OpCode.flag, new SourceToken(as3switch.Token.line, as3switch.Token.ptr, as3switch.Token.sourceFile)); lbl_case_end.flag = "SWITCH_END_" + lblid; env.block.opSteps.Add(lbl_case_end); } }
public void buildAS3For(CompileEnv env, ASTool.AS3.AS3For as3for, Builder builder) { if (!string.IsNullOrEmpty(as3for.label)) { //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3for.Token); tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>(); tempblock.CodeList.Add(as3for); tempblock.label = as3for.label; as3for.label = null; OpStep lbl_forlabel = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_forlabel.flag = "LOOP_LABEL_START_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel); builder.buildStmt(env, tempblock); OpStep lbl_forlabel_end = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_forlabel_end.flag = "LOOP_LABEL_END_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel_end); } else { //*** //FOR_LOOPSTART //***For_Part2*** //***if_true goto FOR_LOOPBODY //***goto FOR_END //FOR_LOOPBODY //***ForBody //FOR_CONTINUE //***For_Part3 //**goto FOR_LOOPSTART //FOR_END int lblid = env.getLabelId(); string loopstart = "LOOP_START_" + lblid; string loopbody = "LOOP_BODY_" + lblid; string loopcontinue = "LOOP_CONTINUE_" + lblid; string loopend = "LOOP_END_" + lblid; { OpStep lbl_loopstart = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_loopstart.flag = loopstart; env.block.opSteps.Add(lbl_loopstart); } if (as3for.Part2 != null) { builder.buildStmt(env, as3for.Part2); ASTool.AS3.AS3Expression expr = as3for.Part2.as3exprlist[as3for.Part2.as3exprlist.Count - 1]; { ASTool.AS3.AS3StmtExpressions conditionsJump = new ASTool.AS3.AS3StmtExpressions(as3for.Part2.Token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Part2.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Part2.Token); step.Type = ASTool.AS3.Expr.OpType.IF_GotoFlag; step.OpCode = loopbody; step.Arg1 = expr.Value; expression.exprStepList.Add(step); conditionsJump.as3exprlist = new List <ASTool.AS3.AS3Expression>(); conditionsJump.as3exprlist.Add(expression); builder.buildStmt(env, conditionsJump); } { ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3for.Part2.Token); jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Part2.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Part2.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopend; expression.exprStepList.Add(step); jumptoend.as3exprlist.Add(expression); builder.buildStmt(env, jumptoend); } } { OpStep lbl_loopbody = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_loopbody.flag = loopbody; env.block.opSteps.Add(lbl_loopbody); } if (as3for.Body != null) { for (int i = 0; i < as3for.Body.Count; i++) { builder.buildStmt(env, as3for.Body[i]); } } { OpStep lbl_loopcontinue = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_loopcontinue.flag = loopcontinue; env.block.opSteps.Add(lbl_loopcontinue); } if (as3for.Part3 != null) { builder.buildStmt(env, as3for.Part3); } { //强行跳回开始 ASTool.AS3.AS3StmtExpressions jumptostart = new ASTool.AS3.AS3StmtExpressions(as3for.Token); jumptostart.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopstart; expression.exprStepList.Add(step); jumptostart.as3exprlist.Add(expression); builder.buildStmt(env, jumptostart); } { //结束标记 OpStep lbl_loopend = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_loopend.flag = loopend; env.block.opSteps.Add(lbl_loopend); } } }
public void buildAS3ForEach(CompileEnv env, ASTool.AS3.AS3ForEach as3foreach, Builder builder) { if (!string.IsNullOrEmpty(as3foreach.label)) { //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3foreach.Token); tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>(); tempblock.CodeList.Add(as3foreach); tempblock.label = as3foreach.label; as3foreach.label = null; OpStep lbl_forlabel = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_forlabel.flag = "LOOP_LABEL_START_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel); builder.buildStmt(env, tempblock); OpStep lbl_forlabel_end = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_forlabel_end.flag = "LOOP_LABEL_END_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel_end); } else { int lblid = env.getLabelId(); builder.buildStmt(env, as3foreach.ForArg); LeftValueBase varvalue = null; if (as3foreach.ForArg is ASTool.AS3.AS3StmtExpressions) { ASTool.AS3.AS3StmtExpressions exprs = (ASTool.AS3.AS3StmtExpressions)as3foreach.ForArg; if (exprs.as3exprlist.Count != 1) { throw new BuildException( as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "Syntax error: invalid for-in initializer, only 1 expression expected."); } ASTool.AS3.AS3Expression expr = exprs.as3exprlist[0]; varvalue = (LeftValueBase)ExpressionBuilder.getRightValue(env, expr.Value, expr.token, builder); } else if (as3foreach.ForArg is ASTool.AS3.AS3Variable) { ASTool.AS3.AS3Variable v = (ASTool.AS3.AS3Variable)as3foreach.ForArg; varvalue = (VariableBase)MemberFinder.find(v.Name, env, false, builder, v.token); } else { throw new BuildException( as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "异常错误,获得的变量类型不正确"); } builder.buildExpression(env, as3foreach.ForExpr); RightValueBase enumerator = ExpressionBuilder.getRightValue(env, as3foreach.ForExpr.Value, as3foreach.ForExpr.token, builder); if (enumerator.valueType == RunTimeDataType.rt_void || enumerator.valueType < RunTimeDataType.unknown ) { enumerator = ExpressionBuilder.addCastOpStep(env, enumerator, RunTimeDataType._OBJECT, new SourceToken(as3foreach.ForExpr.token.line, as3foreach.ForExpr.token.ptr, as3foreach.ForExpr.token.sourceFile) , builder); } //Register regSaveEnumerator = env.getAdditionalRegister(); Variable varSaveEnumerator = new Variable("@saveEnumeraor_" + env.block.scope.members.Count, env.block.scope.members.Count, env.block.id); env.block.scope.members.Add(varSaveEnumerator); varSaveEnumerator.valueType = (RunTimeDataType.rt_void); { //**IEnumerator Get And Reset(); OpStep opGetEnumerator = new OpStep(OpCode.foreach_get_enumerator, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opGetEnumerator.reg = varSaveEnumerator; opGetEnumerator.regType = RunTimeDataType.rt_void; opGetEnumerator.arg1 = enumerator; opGetEnumerator.arg1Type = enumerator.valueType; env.block.opSteps.Add(opGetEnumerator); } string loopstart = "LOOP_START_" + lblid; string loopbody = "LOOP_BODY_" + lblid; string loopcontinue = "LOOP_CONTINUE_" + lblid; string loopend = "LOOP_END_" + lblid; { OpStep lbl_loopstart = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopstart.flag = loopstart; env.block.opSteps.Add(lbl_loopstart); } StackSlotAccessor eaxismovenext = env.getAdditionalRegister(); eaxismovenext.setEAXTypeWhenCompile(RunTimeDataType.rt_boolean); { //**IEnumerator MoveNext() OpStep opMoveNext = new OpStep(OpCode.enumerator_movenext, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opMoveNext.reg = eaxismovenext; opMoveNext.regType = RunTimeDataType.rt_boolean; opMoveNext.arg1 = varSaveEnumerator; opMoveNext.arg1Type = varSaveEnumerator.valueType; env.block.opSteps.Add(opMoveNext); } { OpStep op = new OpStep(OpCode.if_jmp, new SourceToken(as3foreach.ForExpr.token.line, as3foreach.ForExpr.token.ptr, as3foreach.ForExpr.token.sourceFile)); op.reg = null; op.regType = RunTimeDataType.unknown; op.arg1 = eaxismovenext; op.arg1Type = eaxismovenext.valueType; op.arg2 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtString(loopbody)); op.arg2Type = RunTimeDataType.rt_string; env.block.opSteps.Add(op); } { ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token); jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopend; expression.exprStepList.Add(step); jumptoend.as3exprlist.Add(expression); builder.buildStmt(env, jumptoend); } { OpStep lbl_loopbody = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopbody.flag = loopbody; env.block.opSteps.Add(lbl_loopbody); } { RightValueBase loadValue = env.getAdditionalRegister(); ((StackSlotAccessor)loadValue).setEAXTypeWhenCompile(RunTimeDataType.rt_void); //**IEnumerator Current() OpStep opCurrent = new OpStep(OpCode.enumerator_current, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opCurrent.reg = (StackSlotAccessor)loadValue; opCurrent.regType = RunTimeDataType.rt_void; opCurrent.arg1 = varSaveEnumerator; opCurrent.arg1Type = varSaveEnumerator.valueType; env.block.opSteps.Add(opCurrent); if (varvalue.valueType != RunTimeDataType.rt_void) { loadValue = ExpressionBuilder.addCastOpStep(env, loadValue, varvalue.valueType, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) , builder ); } var op = new OpStep(OpCode.assigning, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); op.reg = varvalue; op.regType = varvalue.valueType; op.arg1 = loadValue; op.arg1Type = loadValue.valueType; op.arg2 = null; op.arg2Type = RunTimeDataType.unknown; env.block.opSteps.Add(op); } if (as3foreach.Body != null) { for (int i = 0; i < as3foreach.Body.Count; i++) { builder.buildStmt(env, as3foreach.Body[i]); } } { OpStep lbl_loopcontinue = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopcontinue.flag = loopcontinue; env.block.opSteps.Add(lbl_loopcontinue); } { //强行跳回开始 ASTool.AS3.AS3StmtExpressions jumptostart = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token); jumptostart.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopstart; expression.exprStepList.Add(step); jumptostart.as3exprlist.Add(expression); builder.buildStmt(env, jumptostart); } { //结束标记 OpStep lbl_loopend = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopend.flag = loopend; env.block.opSteps.Add(lbl_loopend); } { OpStep opClose = new OpStep(OpCode.enumerator_close, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); opClose.reg = null; opClose.regType = RunTimeDataType.unknown; opClose.arg1 = varSaveEnumerator; opClose.arg1Type = RunTimeDataType.rt_void; opClose.arg2 = null; opClose.arg2Type = RunTimeDataType.rt_void; env.block.opSteps.Add(opClose); } } }
//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编译没实现"); }