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));
            }
        }
Example #3
0
        public void buildAccess(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, Builder builder)
        {
            if (step.OpCode == ".")
            {
                if (step.Arg1.IsReg)
                {
                    ASBinCode.RightValueBase v1 = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder);
                    if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                    {
                        if (step.Arg3.Data.Value.ToString() == "null")
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "Syntax error: 'null' is not allowed here"));
                        }
                    }

                    //ASBinCode.IRightValue v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder);
                    if (v1 is ASBinCode.StaticClassDataGetter)
                    {
                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            ASBinCode.StaticClassDataGetter sd = (ASBinCode.StaticClassDataGetter)v1;
                            var cls = sd._class;

                            build_class(env, step, v1, cls, builder);
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1 is PackagePathGetter)
                    {
                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            PackagePathGetter pd   = (PackagePathGetter)v1;
                            string            path = pd.path + "." + step.Arg3.Data.Value.ToString();

                            //**尝试查找类***

                            var found = TypeReader.findClassFromProject(path, builder, step.token);
                            if (found.Count == 1)
                            {
                                var item = found[0];

                                OpStep stepInitClass = new OpStep(OpCode.init_staticclass,
                                                                  new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                                stepInitClass.arg1 = new ASBinCode.rtData.RightValue(
                                    new ASBinCode.rtData.rtInt(item.classid));
                                stepInitClass.arg1Type = item.staticClass.getRtType();
                                env.block.opSteps.Add(stepInitClass);

                                ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
                                eax.setEAXTypeWhenCompile(item.staticClass.getRtType());
                                eax.isFindByPath = true;
                                //eax._pathGetter = new PackagePathGetter(path);

                                OpStep op = new OpStep(OpCode.assigning, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                                op.reg      = eax;
                                op.arg1     = new StaticClassDataGetter(item.staticClass);
                                op.arg1Type = item.staticClass.getRtType();

                                env.block.opSteps.Add(op);
                            }
                            else if (found.Count > 1)
                            {
                                throw new BuildException(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "类型" + path + "不明确."
                                                         );
                            }
                            else
                            {
                                //没找到
                                PackagePathGetter           g   = new PackagePathGetter(path);
                                ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
                                eax.setEAXTypeWhenCompile(RunTimeDataType.unknown);
                                eax._pathGetter = g;
                            }
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1 is ThisPointer && v1.valueType == RunTimeDataType.rt_void)
                    {
                        //throw new BuildException(
                        //   new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                        //   "动态查找成员 还没弄"));

                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            build_dot_name(env, step, v1);
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1.valueType == RunTimeDataType.unknown)
                    {
                        throw new BuildException(
                                  new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                 "遇到了unknown类型"));
                    }
                    else if (v1.valueType > RunTimeDataType.unknown)
                    {
                        ASBinCode.rtti.Class cls = builder.getClassByRunTimeDataType(v1.valueType);

                        if (cls == null)
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "编译异常 类型" + v1.valueType + "未找到"));
                        }
                        else
                        {
                            build_class(env, step, v1, cls, builder);
                        }
                    }
                    else
                    {
                        if (v1.valueType != RunTimeDataType.rt_void && v1.valueType < RunTimeDataType.unknown)
                        {
                            if (
                                builder.bin != null &&
                                builder.bin.primitive_to_class_table[v1.valueType] != null)
                            {
                                var cls = builder.bin.primitive_to_class_table[v1.valueType];
                                v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(),
                                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                                     , builder
                                                                     );
                                build_class(env, step, v1, cls, builder);
                            }
                            else
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "基础类型" + v1.valueType + "无法转换为引用类型"));
                            }
                        }
                        else
                        {
                            if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                            {
                                build_dot_name(env, step, v1);
                            }
                            else
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "静态成员名期待一个identifier"));
                            }
                        }
                    }
                }
                else
                {
                    throw new BuildException(
                              new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                             "编译异常 此处应该是个寄存器"));
                }
            }
            else if (step.OpCode == "[")             //和.作用相同
            {
                if (step.Arg1.IsReg)
                {
                    ASBinCode.RightValueBase v1 = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder);
                    if (v1 is ASBinCode.StaticClassDataGetter)
                    {
                        build_bracket_access(env, step, v1, builder);
                    }
                    else if (v1 is PackagePathGetter)
                    {
                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            PackagePathGetter pd   = (PackagePathGetter)v1;
                            string            path = pd.path + "." + step.Arg3.Data.Value.ToString();

                            //**尝试查找类***

                            //查找导入的类
                            var found = TypeReader.findClassFromImports(path, builder, step.token);
                            if (found.Count == 1)
                            {
                                var item = found[0];

                                OpStep stepInitClass = new OpStep(OpCode.init_staticclass,
                                                                  new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                                stepInitClass.arg1 = new ASBinCode.rtData.RightValue(
                                    new ASBinCode.rtData.rtInt(item.classid));
                                stepInitClass.arg1Type = item.staticClass.getRtType();
                                env.block.opSteps.Add(stepInitClass);

                                ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
                                eax.setEAXTypeWhenCompile(item.getRtType());

                                OpStep op = new OpStep(OpCode.assigning, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                                op.reg      = eax;
                                op.arg1     = new StaticClassDataGetter(item.staticClass);
                                op.arg1Type = item.staticClass.getRtType();

                                env.block.opSteps.Add(op);

                                build_bracket_access(env, step, v1, builder);
                            }
                            else
                            {
                                throw new BuildException(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "类型" + path + "不明确."
                                                         );
                            }
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1 is ThisPointer && v1.valueType == RunTimeDataType.rt_void)
                    {
                        if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
                        {
                            build_bracket_access(env, step, v1, builder);
                        }
                        else
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "静态成员名期待一个identifier"));
                        }
                    }
                    else if (v1.valueType == RunTimeDataType.unknown)
                    {
                        throw new BuildException(
                                  new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                 "遇到了unknown类型"));
                    }
                    else if (v1.valueType > RunTimeDataType.unknown)
                    {
                        ASBinCode.rtti.Class cls = builder.getClassByRunTimeDataType(v1.valueType);

                        if (cls == null)
                        {
                            throw new BuildException(
                                      new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                     "编译异常 类型" + v1.valueType + "未找到"));
                        }
                        else
                        {
                            //**todo**检查如果是数组的情况****

                            build_bracket_access(env, step, v1, builder);
                        }
                    }
                    else
                    {
                        if (v1.valueType == RunTimeDataType.rt_array)
                        {
                            var v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder);
                            if (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint)
                            {
                                build_bracket_access(env, step, v1, builder);
                            }
                            else
                            {
                                v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(),
                                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                                     , builder
                                                                     );
                                build_bracket_access(env, step, v1, builder);
                            }
                        }
                        else if (v1.valueType != RunTimeDataType.rt_void && v1.valueType < RunTimeDataType.unknown
                                 )
                        {
                            if (builder.bin.primitive_to_class_table[v1.valueType] != null)
                            {
                                v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(),
                                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                                     , builder
                                                                     );
                                build_bracket_access(env, step, v1, builder);
                            }
                            else
                            {
                                throw new BuildException(
                                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                         "基础类型" + v1.valueType + "无法转换为引用类型"));
                            }
                        }
                        else
                        {
                            build_bracket_access(env, step, v1, builder);
                        }
                    }
                }
                else
                {
                    throw new BuildException(
                              new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                             "编译异常 此处应该是个寄存器"));
                }
            }
            else
            {
                throw new BuildException(
                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                         "不支持的操作类型 " + step.Type + " " + step.OpCode));
            }
        }