Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 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));
            }
        }
Exemplo n.º 4
0
        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);
            }
        }