public void buildInterfaceExtends(ASTool.AS3.AS3Interface as3interface, Builder builder) { var cls = builder.buildingclasses[as3interface]; cls.staticClass.super = builder.getClassByRunTimeDataType(RunTimeDataType._OBJECT + 2); if (cls.isLink_System) { if (builder.bin.LinkObjectClass == null) { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "未设置链接对象基类"); } cls.super = builder.bin.LinkObjectClass; } else { cls.super = builder.bin.ObjectClass; } if (as3interface.ExtendsNames.Count > 0) { for (int i = 0; i < as3interface.ExtendsNames.Count; i++) { string extendName = as3interface.ExtendsNames[i]; var find = TypeReader.findClassFromImports(extendName, builder, as3interface.token); if (find.Count == 1) { if (!find[0].isInterface) { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "An interface can only extend other interfaces, but " + extendName + " is a class."); } else if ((!cls.isLink_System) && find[0].isLink_System) { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "非链接到系统的接口" + cls.name + " 不能继承链接到系统的接口 " + find[0].name); } else { if (!cls.implements.ContainsKey(find[0])) { cls.implements.Add(find[0], null); } } } else if (find.Count == 0) { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "interface " + extendName + " was not found." ); } else { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "Ambiguous reference to " + extendName ); } } } }
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 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)); } }