private static void build_dot(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, ASBinCode.rtti.ClassMember member) { ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax._regMember = member; eax._regMemberSrcObj = v1; eax.setEAXTypeWhenCompile(member.valueType); make_dotStep(env, member, step.token, eax, v1); //OpStep op = new OpStep( // member.bindField is ClassMethodGetter? // OpCode.access_method // : // OpCode.access_dot // , new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); //op.reg = eax; //op.regType = eax.valueType; //op.arg1 = v1; //op.arg1Type = v1.valueType; //op.arg2 = (IRightValue)member.bindField; //new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(member.index)); //op.arg2Type = member.valueType; //RunTimeDataType.rt_int; //env.block.opSteps.Add(op); }
private static void build_dot_name(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1) { ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void); OpStep op = new OpStep(OpCode.access_dot_byname, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtString(step.Arg3.Data.Value.ToString())); op.arg2Type = RunTimeDataType.rt_string; env.block.opSteps.Add(op); }
private void jumpTo(CompileEnv env, ASTool.AS3.AS3Try as3try, Builder builder, string label) { ASTool.AS3.AS3StmtExpressions jumptofinally = new ASTool.AS3.AS3StmtExpressions(as3try.Token); jumptofinally.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3try.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3try.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = label; expression.exprStepList.Add(step); jumptofinally.as3exprlist.Add(expression); builder.buildStmt(env, jumptofinally); }
private void build_void(CompileEnv env, RightValueBase cls, ASTool.AS3.Expr.AS3ExprStep step, Builder builder) { OpStep opnewclass = new OpStep(OpCode.new_instance_class, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); opnewclass.arg1 = cls; opnewclass.arg1Type = RunTimeDataType.rt_void; StackSlotAccessor _eax = env.createASTRegister(step.Arg1.Reg); _eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void); opnewclass.reg = _eax; opnewclass.regType = RunTimeDataType.rt_void; OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_class_argement, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); opMakeArgs.arg1 = cls; opMakeArgs.arg1Type = RunTimeDataType.rt_void; env.block.opSteps.Add(opMakeArgs); if (step.Arg3 != null) { List <ASTool.AS3.Expr.AS3DataStackElement> args = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value; for (int i = 0; i < args.Count; i++) { ASTool.AS3.Expr.AS3DataStackElement argData = args[i]; RightValueBase arg = builds.ExpressionBuilder.getRightValue(env, argData, step.token, builder); //***参数准备*** OpStep opPushArgs = new OpStep(OpCode.push_parameter_class, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); opPushArgs.arg1 = arg; opPushArgs.arg1Type = arg.valueType; opPushArgs.arg2 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(i)); opPushArgs.arg2Type = RunTimeDataType.rt_int; env.block.opSteps.Add(opPushArgs); } } env.block.opSteps.Add(opnewclass); }
private void build_class(CompileEnv env, ASBinCode.rtti.Class _class, ASTool.AS3.Expr.AS3ExprStep step, Builder builder) { //***参数检查*** List <ASTool.AS3.Expr.AS3DataStackElement> args; if (!step.Arg2.IsReg && step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_vector) { ASTool.AS3.AS3Vector vector = (ASTool.AS3.AS3Vector)step.Arg2.Data.Value; if (vector.Constructor == null) { args = new List <ASTool.AS3.Expr.AS3DataStackElement>(); } else { if (vector.isInitData) { args = new List <ASTool.AS3.Expr.AS3DataStackElement>(); } else { args = (List <ASTool.AS3.Expr.AS3DataStackElement>)vector.Constructor.Data.Value; } } } else { if (step.Arg3 != null) { args = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value; } else { args = new List <ASTool.AS3.Expr.AS3DataStackElement>(); } } StackSlotAccessor insEax = env.createASTRegister(step.Arg1.Reg); build_class(env, _class, step.token, builder, insEax, args ); if (!step.Arg2.IsReg && step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_vector) { ASTool.AS3.AS3Vector vector = (ASTool.AS3.AS3Vector)step.Arg2.Data.Value; if (vector.Constructor != null && vector.isInitData) { //***追加初始化Vector*** var initdata = (List <ASTool.AS3.Expr.AS3DataStackElement>)vector.Constructor.Data.Value; var vt = builder.bin.dict_Vector_type[_class]; for (int i = 0; i < initdata.Count; i++) { var d = ExpressionBuilder.getRightValue(env, initdata[i], step.token, builder); if (!ASRuntime.TypeConverter.testImplicitConvert(d.valueType, vt, builder)) { throw(new BuildException(new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "不能将[" + d.valueType + "]类型存入Vector.<" + vt + ">"))); } if (d.valueType != vt) { d = ExpressionBuilder.addCastOpStep(env, d, vt, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder); } OpStep oppush = new OpStep(OpCode.vector_push, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); oppush.reg = null; oppush.regType = RunTimeDataType.unknown; oppush.arg1 = insEax; oppush.arg1Type = insEax.valueType; oppush.arg2 = d; oppush.arg2Type = d.valueType; env.block.opSteps.Add(oppush); } //throw new NotImplementedException(); } } ////***查找构造函数** //if (_class.constructor != null) //{ // ClassMethodGetter field = (ClassMethodGetter)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index]; // int blockid = field.refdefinedinblockid; // var signature = // builder.dictSignatures[blockid][field]; // //***参数检查*** // List<ASTool.AS3.Expr.AS3DataStackElement> args; // if (step.Arg3 != null) // { // args = (List<ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value; // } // else // { // args = new List<ASTool.AS3.Expr.AS3DataStackElement>(); // } // FuncCallBuilder funcbuilder = new FuncCallBuilder(); // funcbuilder.createParaOp(args, signature, step, env, field, builder, true, _class); //} //else //{ // OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement, // new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); // opMakeArgs.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid)); // opMakeArgs.arg1Type = RunTimeDataType.rt_int; // env.block.opSteps.Add(opMakeArgs); //} //OpStep op = new OpStep(OpCode.new_instance, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); //op.arg1 = new RightValue(new rtInt(_class.classid)); //op.arg1Type = _class.getRtType(); //Register eax = env.createASTRegister(step.Arg1.Reg.ID); //eax.setEAXTypeWhenCompile(_class.getRtType()); //op.reg = eax; //op.regType = _class.getRtType(); //env.block.opSteps.Add(op); }
public void buildConstructor(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, Builder builder) { if (step.OpCode == "new") { if (step.Arg1.IsReg) { ASBinCode.rtti.Class _class = null; if (step.Arg2.IsReg) { var cls = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder); if (cls is ASBinCode.StaticClassDataGetter) { _class = builder.getClassByRunTimeDataType(cls.valueType).instanceClass; build_class(env, _class, step, builder); return; } else if (cls is MethodGetterBase) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Method cannot be used as a constructor.")); } else if (cls.valueType == ASBinCode.RunTimeDataType.rt_void || cls.valueType == ASBinCode.RunTimeDataType.rt_function) { //从Class对象中new build_void(env, cls, step, builder); return; } else if (cls.valueType > ASBinCode.RunTimeDataType.unknown) { _class = builder.getClassByRunTimeDataType(cls.valueType); if (_class.isInterface) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, _class.name + " Interfaces cannot be instantiated with the new operator.")); } else if (_class.staticClass != null) { build_class(env, _class, step, builder); } else if (cls is StackSlotAccessor && ((StackSlotAccessor)cls).isFindByPath && _class.staticClass == null) { build_class(env, _class.instanceClass, step, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + cls.valueType + "不能new")); } return; } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + cls.valueType + "不能new")); } } else { //***查找对象类型 var find = TypeReader.findClassFromImports(step.Arg2.Data.Value.ToString(), builder, step.token); if (find.Count == 1) { _class = find[0]; if (_class.isInterface) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, _class.name + " Interfaces cannot be instantiated with the new operator.")); } else if (_class.no_constructor) { } build_class(env, _class, step, builder); return; } else { var cls = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder); if (cls is ASBinCode.StaticClassDataGetter) { _class = builder.getClassByRunTimeDataType(cls.valueType).instanceClass; build_class(env, _class, step, builder); return; } else if (cls is MethodGetterBase) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Method cannot be used as a constructor.")); } else if (cls.valueType == ASBinCode.RunTimeDataType.rt_void || cls.valueType == ASBinCode.RunTimeDataType.rt_function) { //从Class对象中new build_void(env, cls, step, builder); return; } else if (cls.valueType > RunTimeDataType.unknown && (builder.getClassByRunTimeDataType(cls.valueType).classid == 2 || builder.getClassByRunTimeDataType(cls.valueType).classid == 0 )) { build_void(env, cls, step, builder); return; } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + cls.valueType + "不能new")); } } } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 此处应该是个寄存器")); } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "不支持的操作类型 " + step.Type + " " + step.OpCode)); } }
public void buildAS3IF(CompileEnv env, ASTool.AS3.AS3IF as3if, Builder builder) { if (!string.IsNullOrEmpty(as3if.label)) { //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3if.Token); tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>(); tempblock.CodeList.Add(as3if); tempblock.label = as3if.label; as3if.label = null; builder.buildStmt(env, tempblock); } else { //***先编译条件*** builder.buildStmt(env, as3if.Condition); //**取判断条件*** ASTool.AS3.AS3Expression expr = as3if.Condition.as3exprlist[as3if.Condition.as3exprlist.Count - 1]; //if true goto TRUE_LBL //*** //goto IF_END_LBL //TRUE_LBL //*** //IF_END_LBL string truelabel = env.makeLabel("IF_TRUE"); string endlabel = env.makeLabel("IF_END"); { ASTool.AS3.AS3StmtExpressions conditionsJump = new ASTool.AS3.AS3StmtExpressions(as3if.Condition.Token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3if.Condition.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3if.Token); step.Type = ASTool.AS3.Expr.OpType.IF_GotoFlag; step.OpCode = truelabel; step.Arg1 = expr.Value; expression.exprStepList.Add(step); conditionsJump.as3exprlist = new List <ASTool.AS3.AS3Expression>(); conditionsJump.as3exprlist.Add(expression); builder.buildStmt(env, conditionsJump); } { //false部分 if (as3if.FalsePass != null) { for (int i = 0; i < as3if.FalsePass.Count; i++) { builder.buildStmt(env, as3if.FalsePass[i]); } } //跳转到end; ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3if.Token); jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3if.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3if.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = endlabel; expression.exprStepList.Add(step); jumptoend.as3exprlist.Add(expression); builder.buildStmt(env, jumptoend); //**写入true标记 OpStep lbl_true = new OpStep(OpCode.flag, new SourceToken(as3if.Token.line, as3if.Token.ptr, as3if.Token.sourceFile)); lbl_true.flag = truelabel; env.block.opSteps.Add(lbl_true); } { //true部分 if (as3if.TruePass != null) { for (int i = 0; i < as3if.TruePass.Count; i++) { builder.buildStmt(env, as3if.TruePass[i]); } } //**写入end标记 OpStep lbl_end = new OpStep(OpCode.flag, new SourceToken(as3if.Token.line, as3if.Token.ptr, as3if.Token.sourceFile)); lbl_end.flag = endlabel; env.block.opSteps.Add(lbl_end); } } }
public void buildAccess(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, Builder builder) { if (step.OpCode == ".") { if (step.Arg1.IsReg) { ASBinCode.RightValueBase v1 = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder); if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { if (step.Arg3.Data.Value.ToString() == "null") { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Syntax error: 'null' is not allowed here")); } } //ASBinCode.IRightValue v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder); if (v1 is ASBinCode.StaticClassDataGetter) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { ASBinCode.StaticClassDataGetter sd = (ASBinCode.StaticClassDataGetter)v1; var cls = sd._class; build_class(env, step, v1, cls, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1 is PackagePathGetter) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { PackagePathGetter pd = (PackagePathGetter)v1; string path = pd.path + "." + step.Arg3.Data.Value.ToString(); //**尝试查找类*** var found = TypeReader.findClassFromProject(path, builder, step.token); if (found.Count == 1) { var item = found[0]; OpStep stepInitClass = new OpStep(OpCode.init_staticclass, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); stepInitClass.arg1 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtInt(item.classid)); stepInitClass.arg1Type = item.staticClass.getRtType(); env.block.opSteps.Add(stepInitClass); ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(item.staticClass.getRtType()); eax.isFindByPath = true; //eax._pathGetter = new PackagePathGetter(path); OpStep op = new OpStep(OpCode.assigning, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; op.arg1 = new StaticClassDataGetter(item.staticClass); op.arg1Type = item.staticClass.getRtType(); env.block.opSteps.Add(op); } else if (found.Count > 1) { throw new BuildException(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + path + "不明确." ); } else { //没找到 PackagePathGetter g = new PackagePathGetter(path); ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(RunTimeDataType.unknown); eax._pathGetter = g; } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1 is ThisPointer && v1.valueType == RunTimeDataType.rt_void) { //throw new BuildException( // new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, // "动态查找成员 还没弄")); if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { build_dot_name(env, step, v1); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1.valueType == RunTimeDataType.unknown) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "遇到了unknown类型")); } else if (v1.valueType > RunTimeDataType.unknown) { ASBinCode.rtti.Class cls = builder.getClassByRunTimeDataType(v1.valueType); if (cls == null) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 类型" + v1.valueType + "未找到")); } else { build_class(env, step, v1, cls, builder); } } else { if (v1.valueType != RunTimeDataType.rt_void && v1.valueType < RunTimeDataType.unknown) { if ( builder.bin != null && builder.bin.primitive_to_class_table[v1.valueType] != null) { var cls = builder.bin.primitive_to_class_table[v1.valueType]; v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(), new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder ); build_class(env, step, v1, cls, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "基础类型" + v1.valueType + "无法转换为引用类型")); } } else { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { build_dot_name(env, step, v1); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 此处应该是个寄存器")); } } else if (step.OpCode == "[") //和.作用相同 { if (step.Arg1.IsReg) { ASBinCode.RightValueBase v1 = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder); if (v1 is ASBinCode.StaticClassDataGetter) { build_bracket_access(env, step, v1, builder); } else if (v1 is PackagePathGetter) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { PackagePathGetter pd = (PackagePathGetter)v1; string path = pd.path + "." + step.Arg3.Data.Value.ToString(); //**尝试查找类*** //查找导入的类 var found = TypeReader.findClassFromImports(path, builder, step.token); if (found.Count == 1) { var item = found[0]; OpStep stepInitClass = new OpStep(OpCode.init_staticclass, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); stepInitClass.arg1 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtInt(item.classid)); stepInitClass.arg1Type = item.staticClass.getRtType(); env.block.opSteps.Add(stepInitClass); ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(item.getRtType()); OpStep op = new OpStep(OpCode.assigning, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; op.arg1 = new StaticClassDataGetter(item.staticClass); op.arg1Type = item.staticClass.getRtType(); env.block.opSteps.Add(op); build_bracket_access(env, step, v1, builder); } else { throw new BuildException(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + path + "不明确." ); } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1 is ThisPointer && v1.valueType == RunTimeDataType.rt_void) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { build_bracket_access(env, step, v1, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1.valueType == RunTimeDataType.unknown) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "遇到了unknown类型")); } else if (v1.valueType > RunTimeDataType.unknown) { ASBinCode.rtti.Class cls = builder.getClassByRunTimeDataType(v1.valueType); if (cls == null) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 类型" + v1.valueType + "未找到")); } else { //**todo**检查如果是数组的情况**** build_bracket_access(env, step, v1, builder); } } else { if (v1.valueType == RunTimeDataType.rt_array) { var v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder); if (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint) { build_bracket_access(env, step, v1, builder); } else { v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(), new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder ); build_bracket_access(env, step, v1, builder); } } else if (v1.valueType != RunTimeDataType.rt_void && v1.valueType < RunTimeDataType.unknown ) { if (builder.bin.primitive_to_class_table[v1.valueType] != null) { v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(), new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder ); build_bracket_access(env, step, v1, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "基础类型" + v1.valueType + "无法转换为引用类型")); } } else { build_bracket_access(env, step, v1, builder); } } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 此处应该是个寄存器")); } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "不支持的操作类型 " + step.Type + " " + step.OpCode)); } }
private static void build_bracket_access(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, Builder builder) { ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void); var v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder); if (v1.valueType == RunTimeDataType.rt_void ) { OpStep op = new OpStep(OpCode.bracket_access, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } else if (v1.valueType > RunTimeDataType.unknown && builder.bin.dict_Vector_type.ContainsKey(builder.getClassByRunTimeDataType(v1.valueType)) ) { ASBinCode.rtti.Class vector = builder.getClassByRunTimeDataType(v1.valueType); RunTimeDataType vt = builder.bin.dict_Vector_type[vector]; if (v2.valueType > RunTimeDataType.unknown) { v2 = ExpressionBuilder.addCastToPrimitive(env, v2, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile), builder); } if (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint ) { v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder); eax.setEAXTypeWhenCompile(vt); { OpStep op = new OpStep(OpCode.vectorAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } } else { OpStep op = new OpStep(OpCode.vectorAccessor_convertidx, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } //if (v2.valueType != RunTimeDataType.rt_int) //{ // v2=ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int, // new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) // , builder); //} //eax.setEAXTypeWhenCompile(vt); //eax._vector_Type = vt; //{ // OpStep op = new OpStep(OpCode.vectorAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); // op.reg = eax; // op.regType = eax.valueType; // op.arg1 = v1; // op.arg1Type = v1.valueType; // op.arg2 = v2; // op.arg2Type = v2.valueType; // env.block.opSteps.Add(op); //} } else if (builder.bin.ArrayClass != null && builder.bin.ArrayClass.getRtType() == v1.valueType && (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint ) ) { v1 = builds.ExpressionBuilder.addCastToPrimitive(env, v1, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile), builder); v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder); OpStep op = new OpStep(OpCode.arrayAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } else if (v1.valueType == RunTimeDataType.rt_array && (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint ) ) { v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder); OpStep op = new OpStep(OpCode.arrayAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } else { OpStep op = new OpStep(OpCode.bracket_byname, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } }
private static void build_class(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, ASBinCode.rtti.Class cls, Builder builder) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { ASBinCode.rtti.ClassMember member = null; //***查找对象成员*** member = MemberFinder.findClassMember(cls, step.Arg3.Data.Value.ToString(), env, builder); if (member == null) { if (cls.dynamic && cls.staticClass != null //***编译时检查不能向Class动态加属性。 ) { //***此处编译为动态属性*** build_dot_name(env, step, v1); return; } } if (member == null) { if (step.Arg3.Data.Value.ToString() == "hasOwnProperty" ) //***这是Object原型链对象,特殊处理 { //***此处编译为动态属性*** build_dot_name(env, step, v1); return; } if (v1 is SuperPointer) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Attempted access of inaccessible property " + step.Arg3.Data.Value + " through a reference with static type " + ((SuperPointer)v1).thisClass.name + ".")); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, cls.name + "对象成员" + step.Arg3.Data.Value + "未找到")); } } if (!member.isConst && env.isEval) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Eval时忽略非Const成员")); } build_dot(env, step, v1, member); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } }
public void buildAS3Switch(CompileEnv env, ASTool.AS3.AS3Switch as3switch, Builder builder) { if (!string.IsNullOrEmpty(as3switch.label)) { //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3switch.Token); tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>(); tempblock.CodeList.Add(as3switch); tempblock.label = as3switch.label; as3switch.label = null; builder.buildStmt(env, tempblock); } else { //***先编译条件*** ASTool.AS3.AS3StmtExpressions expressions = new ASTool.AS3.AS3StmtExpressions(as3switch.Token); expressions.as3exprlist = new List <ASTool.AS3.AS3Expression>(); expressions.as3exprlist.Add(as3switch.Expr); builder.buildStmt(env, expressions); //**取判断条件*** ASTool.AS3.AS3Expression expr = as3switch.Expr; int defaults = 0; for (int i = 0; i < as3switch.CaseList.Count; i++) { ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i]; if (c.IsDefault) { defaults++; } if (defaults > 1) { throw new BuildException(c.token.line, c.token.ptr, c.token.sourceFile, "switch只能有1个default:"); } } List <string> switchlabels = new List <string>(); for (int i = 0; i < as3switch.CaseList.Count; i++) { ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i]; if (!c.IsDefault) { switchlabels.Add(env.makeLabel("SWITCH_CASE")); } else { switchlabels.Add(env.makeLabel("SWITCH_DEFAULT")); } } for (int i = 0; i < as3switch.CaseList.Count; i++) { ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i]; if (!c.IsDefault) { RunTimeValueBase v = ExpressionEval.Eval(c.Condition); if (v != null && c.Condition.Value.IsReg) { OpStep op = new OpStep(OpCode.assigning, new SourceToken(c.token.line, c.token.ptr, c.token.sourceFile)); var eax = env.createASTRegister(c.Condition.Value.Reg); eax.setEAXTypeWhenCompile(v.rtType); op.reg = eax; op.regType = eax.valueType; op.arg1 = new ASBinCode.rtData.RightValue(v); op.arg1Type = v.rtType; env.block.opSteps.Add(op); } else { ASTool.AS3.AS3StmtExpressions caseExpr = new ASTool.AS3.AS3StmtExpressions(c.token); caseExpr.as3exprlist = new List <ASTool.AS3.AS3Expression>(); caseExpr.as3exprlist.Add(c.Condition); builder.buildStmt(env, caseExpr); } { ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token); step.Type = ASTool.AS3.Expr.OpType.LogicEQ; step.OpCode = "=="; step.Arg1 = c.holdreg; step.Arg2 = expr.Value; step.Arg3 = c.Condition.Value; ASTool.AS3.AS3StmtExpressions compare = new ASTool.AS3.AS3StmtExpressions(c.token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(c.token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); expression.exprStepList.Add(step); expression.Value = c.holdreg; compare.as3exprlist = new List <ASTool.AS3.AS3Expression>(); compare.as3exprlist.Add(expression); builder.buildStmt(env, compare); } { ASTool.AS3.AS3StmtExpressions conditionsJump = new ASTool.AS3.AS3StmtExpressions(c.token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(c.token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token); step.Type = ASTool.AS3.Expr.OpType.IF_GotoFlag; step.OpCode = switchlabels[i]; step.Arg1 = c.holdreg; expression.exprStepList.Add(step); conditionsJump.as3exprlist = new List <ASTool.AS3.AS3Expression>(); conditionsJump.as3exprlist.Add(expression); builder.buildStmt(env, conditionsJump); } } else { ASTool.AS3.AS3StmtExpressions jump = new ASTool.AS3.AS3StmtExpressions(c.token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(c.token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(c.token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = switchlabels[i]; expression.exprStepList.Add(step); jump.as3exprlist = new List <ASTool.AS3.AS3Expression>(); jump.as3exprlist.Add(expression); builder.buildStmt(env, jump); } } int lblid = env.getLabelId(); OpStep lbl_case_start = new OpStep(OpCode.flag, new SourceToken(as3switch.Token.line, as3switch.Token.ptr, as3switch.Token.sourceFile)); lbl_case_start.flag = "SWITCH_START_" + lblid; env.block.opSteps.Add(lbl_case_start); for (int i = 0; i < as3switch.CaseList.Count; i++) { ASTool.AS3.AS3SwitchCase c = as3switch.CaseList[i]; //if (!c.IsDefault) { OpStep lbl_case = new OpStep(OpCode.flag, new SourceToken(c.token.line, c.token.ptr, c.token.sourceFile)); lbl_case.flag = switchlabels[i]; env.block.opSteps.Add(lbl_case); } if (c.Body != null) { for (int j = 0; j < c.Body.Count; j++) { builder.buildStmt(env, c.Body[j]); } } } OpStep lbl_case_end = new OpStep(OpCode.flag, new SourceToken(as3switch.Token.line, as3switch.Token.ptr, as3switch.Token.sourceFile)); lbl_case_end.flag = "SWITCH_END_" + lblid; env.block.opSteps.Add(lbl_case_end); } }
public void buildAS3For(CompileEnv env, ASTool.AS3.AS3For as3for, Builder builder) { if (!string.IsNullOrEmpty(as3for.label)) { //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3for.Token); tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>(); tempblock.CodeList.Add(as3for); tempblock.label = as3for.label; as3for.label = null; OpStep lbl_forlabel = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_forlabel.flag = "LOOP_LABEL_START_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel); builder.buildStmt(env, tempblock); OpStep lbl_forlabel_end = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_forlabel_end.flag = "LOOP_LABEL_END_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel_end); } else { //*** //FOR_LOOPSTART //***For_Part2*** //***if_true goto FOR_LOOPBODY //***goto FOR_END //FOR_LOOPBODY //***ForBody //FOR_CONTINUE //***For_Part3 //**goto FOR_LOOPSTART //FOR_END int lblid = env.getLabelId(); string loopstart = "LOOP_START_" + lblid; string loopbody = "LOOP_BODY_" + lblid; string loopcontinue = "LOOP_CONTINUE_" + lblid; string loopend = "LOOP_END_" + lblid; { OpStep lbl_loopstart = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_loopstart.flag = loopstart; env.block.opSteps.Add(lbl_loopstart); } if (as3for.Part2 != null) { builder.buildStmt(env, as3for.Part2); ASTool.AS3.AS3Expression expr = as3for.Part2.as3exprlist[as3for.Part2.as3exprlist.Count - 1]; { ASTool.AS3.AS3StmtExpressions conditionsJump = new ASTool.AS3.AS3StmtExpressions(as3for.Part2.Token); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Part2.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Part2.Token); step.Type = ASTool.AS3.Expr.OpType.IF_GotoFlag; step.OpCode = loopbody; step.Arg1 = expr.Value; expression.exprStepList.Add(step); conditionsJump.as3exprlist = new List <ASTool.AS3.AS3Expression>(); conditionsJump.as3exprlist.Add(expression); builder.buildStmt(env, conditionsJump); } { ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3for.Part2.Token); jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Part2.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Part2.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopend; expression.exprStepList.Add(step); jumptoend.as3exprlist.Add(expression); builder.buildStmt(env, jumptoend); } } { OpStep lbl_loopbody = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_loopbody.flag = loopbody; env.block.opSteps.Add(lbl_loopbody); } if (as3for.Body != null) { for (int i = 0; i < as3for.Body.Count; i++) { builder.buildStmt(env, as3for.Body[i]); } } { OpStep lbl_loopcontinue = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_loopcontinue.flag = loopcontinue; env.block.opSteps.Add(lbl_loopcontinue); } if (as3for.Part3 != null) { builder.buildStmt(env, as3for.Part3); } { //强行跳回开始 ASTool.AS3.AS3StmtExpressions jumptostart = new ASTool.AS3.AS3StmtExpressions(as3for.Token); jumptostart.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3for.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3for.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopstart; expression.exprStepList.Add(step); jumptostart.as3exprlist.Add(expression); builder.buildStmt(env, jumptostart); } { //结束标记 OpStep lbl_loopend = new OpStep(OpCode.flag, new SourceToken(as3for.Token.line, as3for.Token.ptr, as3for.Token.sourceFile)); lbl_loopend.flag = loopend; env.block.opSteps.Add(lbl_loopend); } } }
public void buildAS3ForEach(CompileEnv env, ASTool.AS3.AS3ForEach as3foreach, Builder builder) { if (!string.IsNullOrEmpty(as3foreach.label)) { //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3foreach.Token); tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>(); tempblock.CodeList.Add(as3foreach); tempblock.label = as3foreach.label; as3foreach.label = null; OpStep lbl_forlabel = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_forlabel.flag = "LOOP_LABEL_START_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel); builder.buildStmt(env, tempblock); OpStep lbl_forlabel_end = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_forlabel_end.flag = "LOOP_LABEL_END_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel_end); } else { int lblid = env.getLabelId(); builder.buildStmt(env, as3foreach.ForArg); LeftValueBase varvalue = null; if (as3foreach.ForArg is ASTool.AS3.AS3StmtExpressions) { ASTool.AS3.AS3StmtExpressions exprs = (ASTool.AS3.AS3StmtExpressions)as3foreach.ForArg; if (exprs.as3exprlist.Count != 1) { throw new BuildException( as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "Syntax error: invalid for-in initializer, only 1 expression expected."); } ASTool.AS3.AS3Expression expr = exprs.as3exprlist[0]; varvalue = (LeftValueBase)ExpressionBuilder.getRightValue(env, expr.Value, expr.token, builder); } else if (as3foreach.ForArg is ASTool.AS3.AS3Variable) { ASTool.AS3.AS3Variable v = (ASTool.AS3.AS3Variable)as3foreach.ForArg; varvalue = (VariableBase)MemberFinder.find(v.Name, env, false, builder, v.token); } else { throw new BuildException( as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "异常错误,获得的变量类型不正确"); } builder.buildExpression(env, as3foreach.ForExpr); RightValueBase enumerator = ExpressionBuilder.getRightValue(env, as3foreach.ForExpr.Value, as3foreach.ForExpr.token, builder); if (enumerator.valueType == RunTimeDataType.rt_void || enumerator.valueType < RunTimeDataType.unknown ) { enumerator = ExpressionBuilder.addCastOpStep(env, enumerator, RunTimeDataType._OBJECT, new SourceToken(as3foreach.ForExpr.token.line, as3foreach.ForExpr.token.ptr, as3foreach.ForExpr.token.sourceFile) , builder); } //Register regSaveEnumerator = env.getAdditionalRegister(); Variable varSaveEnumerator = new Variable("@saveEnumeraor_" + env.block.scope.members.Count, env.block.scope.members.Count, env.block.id); env.block.scope.members.Add(varSaveEnumerator); varSaveEnumerator.valueType = (RunTimeDataType.rt_void); { //**IEnumerator Get And Reset(); OpStep opGetEnumerator = new OpStep(OpCode.foreach_get_enumerator, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opGetEnumerator.reg = varSaveEnumerator; opGetEnumerator.regType = RunTimeDataType.rt_void; opGetEnumerator.arg1 = enumerator; opGetEnumerator.arg1Type = enumerator.valueType; env.block.opSteps.Add(opGetEnumerator); } string loopstart = "LOOP_START_" + lblid; string loopbody = "LOOP_BODY_" + lblid; string loopcontinue = "LOOP_CONTINUE_" + lblid; string loopend = "LOOP_END_" + lblid; { OpStep lbl_loopstart = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopstart.flag = loopstart; env.block.opSteps.Add(lbl_loopstart); } StackSlotAccessor eaxismovenext = env.getAdditionalRegister(); eaxismovenext.setEAXTypeWhenCompile(RunTimeDataType.rt_boolean); { //**IEnumerator MoveNext() OpStep opMoveNext = new OpStep(OpCode.enumerator_movenext, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opMoveNext.reg = eaxismovenext; opMoveNext.regType = RunTimeDataType.rt_boolean; opMoveNext.arg1 = varSaveEnumerator; opMoveNext.arg1Type = varSaveEnumerator.valueType; env.block.opSteps.Add(opMoveNext); } { OpStep op = new OpStep(OpCode.if_jmp, new SourceToken(as3foreach.ForExpr.token.line, as3foreach.ForExpr.token.ptr, as3foreach.ForExpr.token.sourceFile)); op.reg = null; op.regType = RunTimeDataType.unknown; op.arg1 = eaxismovenext; op.arg1Type = eaxismovenext.valueType; op.arg2 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtString(loopbody)); op.arg2Type = RunTimeDataType.rt_string; env.block.opSteps.Add(op); } { ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token); jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopend; expression.exprStepList.Add(step); jumptoend.as3exprlist.Add(expression); builder.buildStmt(env, jumptoend); } { OpStep lbl_loopbody = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopbody.flag = loopbody; env.block.opSteps.Add(lbl_loopbody); } { RightValueBase loadValue = env.getAdditionalRegister(); ((StackSlotAccessor)loadValue).setEAXTypeWhenCompile(RunTimeDataType.rt_void); //**IEnumerator Current() OpStep opCurrent = new OpStep(OpCode.enumerator_current, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opCurrent.reg = (StackSlotAccessor)loadValue; opCurrent.regType = RunTimeDataType.rt_void; opCurrent.arg1 = varSaveEnumerator; opCurrent.arg1Type = varSaveEnumerator.valueType; env.block.opSteps.Add(opCurrent); if (varvalue.valueType != RunTimeDataType.rt_void) { loadValue = ExpressionBuilder.addCastOpStep(env, loadValue, varvalue.valueType, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) , builder ); } var op = new OpStep(OpCode.assigning, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); op.reg = varvalue; op.regType = varvalue.valueType; op.arg1 = loadValue; op.arg1Type = loadValue.valueType; op.arg2 = null; op.arg2Type = RunTimeDataType.unknown; env.block.opSteps.Add(op); } if (as3foreach.Body != null) { for (int i = 0; i < as3foreach.Body.Count; i++) { builder.buildStmt(env, as3foreach.Body[i]); } } { OpStep lbl_loopcontinue = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopcontinue.flag = loopcontinue; env.block.opSteps.Add(lbl_loopcontinue); } { //强行跳回开始 ASTool.AS3.AS3StmtExpressions jumptostart = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token); jumptostart.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopstart; expression.exprStepList.Add(step); jumptostart.as3exprlist.Add(expression); builder.buildStmt(env, jumptostart); } { //结束标记 OpStep lbl_loopend = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopend.flag = loopend; env.block.opSteps.Add(lbl_loopend); } { OpStep opClose = new OpStep(OpCode.enumerator_close, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); opClose.reg = null; opClose.regType = RunTimeDataType.unknown; opClose.arg1 = varSaveEnumerator; opClose.arg1Type = RunTimeDataType.rt_void; opClose.arg2 = null; opClose.arg2Type = RunTimeDataType.rt_void; env.block.opSteps.Add(opClose); } } }