internal override void Compile(CompileParameter param) { int SelfCount = 0; // 尝试放入self作为第一个参数 var selector = Func as SelectorExpr; if (selector != null) { SelfCount += selector.CompileSelfParameter(param.SetLHS(false)); } // 先放参数 foreach (var arg in Args) { arg.Compile(param.SetLHS(false)); } // 本包及动态闭包调用 Func.Compile(param.SetLHS(false)); param.CS.Add(new Command(Opcode.CALL, Args.Count + SelfCount, GetReceiverCount())).SetCodePos(LParen); }
internal override void Compile(CompileParameter param) { Condition.Compile(param.SetLHS(false)); var jnzCmd = param.CS.Add(new Command(Opcode.JZ, 0)) .SetCodePos(IfPos) .SetComment("if condition false"); Body.Compile(param.SetLHS(false)); var jmpCmd = param.CS.Add(new Command(Opcode.JMP, 0)) .SetCodePos(IfPos) .SetComment("if condition true"); // false body跳入 jnzCmd.DataA = param.CS.CurrCmdID; if (ElseBody.Stmts.Count > 0) { ElseBody.Compile(param.SetLHS(false)); } // true body执行完毕跳出 jmpCmd.DataA = param.CS.CurrCmdID; }
internal override void Compile(CompileParameter param) { foreach (var b in Stmts) { b.Compile(param.SetLHS(false)); } }
internal int CompileSelfParameter(CompileParameter param) { var xident = X as Ident; if (xident != null) { if (xident.Symbol == null) { throw new CompileException("undefined symbol: " + xident.Name, DotPos); } // a.Do()的a 放入 switch (xident.Symbol.Usage) { case SymbolUsage.Parameter: case SymbolUsage.Variable: { X.Compile(param.SetLHS(false)); return(1); } } } return(0); }
internal override void Compile(CompileParameter param) { Index.Compile(param.SetLHS(false)); X.Compile(param.SetLHS(false)); if (param.LHS) { // 赋值 param.CS.Add(new Command(Opcode.SETI)).SetCodePos(LBrackPos); } else { // 取值 param.CS.Add(new Command(Opcode.LOADI)).SetCodePos(LBrackPos); } }
internal override void Compile(CompileParameter param) { for (int i = Results.Count - 1; i >= 0; i--) { Results[i].Compile(param.SetLHS(false)); } param.CS.Add(new Command(Opcode.RET)).SetCodePos(RetPos); }
internal override void Compile(CompileParameter param) { LoopBeginCmdID = param.CS.CurrCmdID; Condition.Compile(param.SetLHS(false)); var jzCmd = param.CS.Add(new Command(Opcode.JZ, 0)) .SetCodePos(Pos) .SetComment("while condition"); param.LHS = false; Body.Compile(param.SetLHS(false)); param.CS.Add(new Command(Opcode.JMP, LoopBeginCmdID)) .SetCodePos(Pos) .SetComment("while loop"); // false body跳入 LoopEndCmdID = param.CS.CurrCmdID; jzCmd.DataA = LoopEndCmdID; }
internal override void Compile(CompileParameter param) { if (Init != null) { Init.Compile(param.SetLHS(false)); } LoopBeginCmdID = param.CS.CurrCmdID; Command jzCmd = null; if (Condition != null) { Condition.Compile(param.SetLHS(false)); jzCmd = param.CS.Add(new Command(Opcode.JZ, -1)) .SetCodePos(Pos) .SetComment("for condition"); } Body.Compile(param.SetLHS(false)); if (Post != null) { Post.Compile(param.SetLHS(false)); } param.CS.Add(new Command(Opcode.JMP, LoopBeginCmdID)) .SetCodePos(Pos) .SetComment("for loop"); // false body跳入 if (jzCmd != null) { jzCmd.DataA = param.CS.CurrCmdID; } LoopEndCmdID = param.CS.CurrCmdID; }
internal override void Compile(CompileParameter param) { switch (Op) { case TokenType.Assign: { foreach (var e in RHS) { e.Compile(param.SetLHS(false)); } } break; case TokenType.AddAssign: case TokenType.SubAssign: case TokenType.MulAssign: case TokenType.QuoAssign: { // 这种操作只允许一个一个来 if (LHS.Count != 1 || RHS.Count != 1) { throw new CompileException("assignment require 1 operand", AssignPos); } LHS[0].Compile(param.SetLHS(false)); RHS[0].Compile(param.SetLHS(false)); param.CS.Add(new Command(Token2OpCode(Op))) .SetCodePos(AssignPos); } break; } foreach (var e in LHS) { e.Compile(param.SetLHS(true)); } }
internal override void Compile(CompileParameter param) { foreach (var b in X) { // ExprStmt下不出现CallExpr可能是-foo(); 1+foo() 这种奇葩写法 // 返回值无法被回收, 所以直接报错 if (!(b is CallExpr)) { throw new CompileException("invalid expression statement", DefPos); } b.Compile(param.SetLHS(false)); } }
// 手动分配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; }
internal override void Compile(CompileParameter param) { var cmd = param.CS.Add(new Command(Opcode.NEW)).SetCodePos(LBracePos).SetComment("Builtin.Map"); cmd.EntryName = new ObjectName("Builtin", "Map"); var kvParam = param.SetLHS(false); foreach (var kv in Values) { kv.Key.Compile(kvParam); kv.Value.Compile(kvParam); } param.CS.Add(new Command(Opcode.SETD, Values.Count)).SetCodePos(LBracePos); }
internal override void Compile(CompileParameter param) { var opcode = Token2OpCode(Op); if (opcode != Opcode.NOP) { X.Compile(param); } else { throw new CompileException("Unknown unary operator", OpPos); } param.CS.Add(new Command(opcode)).SetCodePos(OpPos); // 赋值 X.Compile(param.SetLHS(true)); }
internal override void Compile(CompileParameter param) { ObjectName on = new ObjectName(param.Pkg.Name, Name.Name); if (ClassName != null) { // 成员函数必须有至少1个参数(self) if (TypeInfo.Params.Count < 1) { throw new CompileException("Expect 'self' in method", TypeInfo.FuncPos); } on.ClassName = ClassName.Name; } var newset = new ValuePhoFunc(on, TypeInfo.FuncPos, TypeInfo.ScopeInfo.CalcUsedReg(), TypeInfo.ScopeInfo); bodyCS = newset; _proc = param.Exe.AddFunc(newset); if (ClassName != null) { param.NextPassToResolve(this); } var funcParam = param.SetLHS(false).SetCmdSet(newset); Body.Compile(funcParam); TypeInfo.GenDefaultRet(Body.Child(), funcParam); newset.InputValueCount = TypeInfo.Params.Count; newset.OutputValueCount = FuncType.CalcReturnValueCount(Body.Child()); }
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); } }
// foo var a // closure var b 间接UpValue a // closure2 var c 直接UpValue a, b // LINKU和LOADU对应 // 引用模式分为2种 // 1. 引用最近的上一层作用域, LINKU第一个参数=0(当前执行体不是闭包时) // 1. 引用上N层作用域, LINKU第一个参数=1 (当前执行体为闭包时) // // UpValue索引计算 // 不使用被引用的变量在它归属作用域分配的寄存器索引 // 直接引用并使用的UpValue internal override void Compile(CompileParameter param) { var newset = new ValuePhoFunc(param.Pkg.GenClosureName(), TypeInfo.FuncPos, TypeInfo.ScopeInfo.CalcUsedReg(), TypeInfo.ScopeInfo); var proc = param.Exe.AddFunc(newset); var closureCmd = new Command(Opcode.CLOSURE).SetCodePos(TypeInfo.FuncPos); closureCmd.EntryName = newset.Name; param.CS.Add(closureCmd); var funcParam = param.SetLHS(false).SetCmdSet(newset); // 深度遍历, 所以最终引用层会先被遍历到 Body.Compile(funcParam); // 找到这一层闭包用的upvalues集合(引用上面函数作用域的) FindUsedUpvalue(Body); // 给每一个upvalue添加引用的upvalue foreach (var uv in UpValues) { AddRefUpvalueInNode(TypeInfo.ScopeInfo, uv.Symbol.RegBelong, uv); } int ThisLevelIndex = 0; foreach (var uv in UpValues) { var cmd = param.CS.Add(new Command(Opcode.LINKU, -1, -1)) .SetComment(uv.ToString()) .SetCodePos(TypeInfo.FuncPos); // 引用的上一层的upvalue的索引, 对应指令引用LocalReg的Index int UplevelIndex = GetRegIndex(TypeInfo.ScopeInfo, uv.Name); if (UplevelIndex != -1) { cmd.DataA = 0; cmd.DataB = UplevelIndex; } else { // 引用上层自己的Upvalue(间接引用) UplevelIndex = GetUpvalueIndex(TypeInfo.ScopeInfo, uv.Name); cmd.DataA = 1; cmd.DataB = UplevelIndex; } // LOADU的对应的Upvalue的索引, 修改下 uv.CmdGen.DataA = ThisLevelIndex; ThisLevelIndex++; } TypeInfo.GenDefaultRet(Body.Child(), funcParam); newset.InputValueCount = TypeInfo.Params.Count; newset.OutputValueCount = FuncType.CalcReturnValueCount(Body.Child()); }