Beispiel #1
0
        // 手动分配1个iterator变量
        // k, v, iter = ITER( x, iter )
        //
        internal override void Compile(CompileParameter param)
        {
            var iterVar = DelcareIteratorVar();

            param.CS.Add(new Command(Opcode.INITR, iterVar.Symbol.RegIndex))
            .SetCodePos(Pos)
            .SetComment("init iterator");


            LoopBeginCmdID = param.CS.CurrCmdID;

            X.Compile(param);

            iterVar.Compile(param);

            var jmpCmd = param.CS.Add(new Command(Opcode.VISIT, -1))
                         .SetCodePos(Pos)
                         .SetComment("for kv");

            Key.Compile(param.SetLHS(true));

            Value.Compile(param.SetLHS(true));

            iterVar.Compile(param.SetLHS(true));

            Body.Compile(param.SetLHS(false));


            param.CS.Add(new Command(Opcode.JMP, LoopBeginCmdID))
            .SetCodePos(Pos)
            .SetComment("for kv loop");

            // 循环结束
            LoopEndCmdID = param.CS.CurrCmdID;
            jmpCmd.DataA = LoopEndCmdID;
        }
Beispiel #2
0
        internal override void Compile(CompileParameter param)
        {
            var xident = X as Ident;

            if (xident != null)
            {
                if (xident.Symbol == null)
                {
                    throw new CompileException("undefined symbol: " + xident.Name, DotPos);
                }

                switch (xident.Symbol.Usage)
                {
                // 包.函数名
                case SymbolUsage.Package:
                {
                    var pkg = param.Exe.GetPackageByName(xident.Name);

                    if (pkg == null)
                    {
                        throw new CompileException("package not found: " + xident.Name, DotPos);
                    }

                    // Ident直接出代码
                    Selector.Compile(param.SetLHS(false).SetPackage(pkg));
                }
                break;

                // 实例.函数名  转换为  函数名( 实例, p2...)
                // 类成员访问
                case SymbolUsage.Parameter:
                case SymbolUsage.Variable:
                case SymbolUsage.SelfParameter:
                {
                    X.Compile(param.SetLHS(false));


                    var ci = param.Constants.AddString(Selector.Name);

                    Opcode cm = param.LHS ? Opcode.SETM : Opcode.LOADM;

                    // 无法推导X类型, 所以这里只能用动态方法直接加载,或设置
                    param.CS.Add(new Command(cm, ci))
                    .SetCodePos(DotPos).SetComment(Selector.Name);
                }
                break;

                default:
                    throw new CompileException("unknown symbol usage", DotPos);
                }
            }
            else if (X is BaseLit)
            {
                // 提供一个self, 因为LOADB会吃掉self
                GetFuncSelf().Compile(param.SetLHS(false));


                var ci = param.Constants.AddString(Selector.Name);

                // 无法推导X类型, 所以这里只能用动态方法直接加载,或设置
                param.CS.Add(new Command(Opcode.LOADB, ci))
                .SetCodePos(DotPos).SetComment(Selector.Name);
            }
            else
            {
                // 动态表达式, 需要用指令解析
                X.Compile(param);

                var ci = param.Constants.AddString(Selector.Name);

                param.CS.Add(new Command(Opcode.SEL, ci))
                .SetCodePos(DotPos).SetComment(Selector.Name);
            }
        }