private void CGNameExp(FuncInfo funcInfo, ConstExpNode node, int a) { LocalVarInfo varInfo = null; int r = 0; if (funcInfo.VarDic1.TryGetValue(node.name, out varInfo)) { funcInfo.EmitMove(a, varInfo.RegIndex); } else if (funcInfo.UpValOfIndex(node.name) != -1) { r = funcInfo.UpValOfIndex(node.name); funcInfo.EmitGetUpval(a, r); } //else if (funcInfo.ConstDic.TryGetValue(node.name, out r)) // { // funcInfo.EmitLoadK(a, node.name); // } else { var exp = new TableAccessExpNode(); exp.PreExp = new ConstExpNode(new Token(TokenType.Identifier, "_ENV", -1)); exp.Exp = new ConstExpNode(new Token(TokenType.String, node.name, -1)); CGTableAccessExp(funcInfo, exp, a); } }
private void CGVarargExp(FuncInfo funcInfo, ConstExpNode node, int a, int n) { if (!funcInfo.IsVararg) { throw new Exception("this function is not use ... beacuse it is not vararg function"); } else { funcInfo.EmitVararg(a, n); } }
private bool IsVarargOrFuncCall(ExpNode node) { switch (node.Type) { case GrammarNodeType.FuncCallExp: return(true); } ConstExpNode cNode = null; if (node is ConstExpNode) { cNode = node as ConstExpNode; if (cNode.ExpType == ConstExpNode.ConstExpType.VarargExp) { return(true); } } return(false); }
private void CGAssignStat(FuncInfo funcInfo, AssignStatNode node) { int nExps = node.ExpList.Count; int nVars = node.VarList.Count; int oldRegs = funcInfo.UsedReg; var tRegs = new int[nVars]; var kRegs = new int[nVars]; var vRegs = new int[nVars]; int i = 0; foreach (var exp in node.VarList) { TableAccessExpNode taExp = null; ConstExpNode constExp = null; if ((taExp = exp as TableAccessExpNode) != null) { tRegs[i] = funcInfo.AllocReg(); CGExp(funcInfo, taExp.PreExp, tRegs[i], 1); kRegs[i] = funcInfo.AllocReg(); CGExp(funcInfo, taExp.Exp, kRegs[i], 1); } i++; } for (int j = 0; j < nVars; j++) { vRegs[j] = funcInfo.UsedReg + j; } if (nExps >= nVars) { i = 0; foreach (var exp in node.ExpList) { int a = funcInfo.AllocReg(); if (i > nVars && i == nExps - 1 && IsVarargOrFuncCall(exp)) { CGExp(funcInfo, exp, a, 0); } else { CGExp(funcInfo, exp, a, 1); } i++; } } else { bool multRet = false; i = 0; foreach (var exp in node.ExpList) { int a = funcInfo.AllocReg(); if (i == nExps - 1 && IsVarargOrFuncCall(exp)) { multRet = true; int n = nVars - nExps + 1; CGExp(funcInfo, exp, a, n); funcInfo.AllocRegs(n - 1); } else { CGExp(funcInfo, exp, a, 1); } i++; } if (!multRet) { int n = nVars - nExps; int a = funcInfo.AllocRegs(n); funcInfo.EmitLoadNil(a, n); } } i = 0; foreach (var exp in node.VarList) { ConstExpNode varNode = null; int r = 0; if ((varNode = exp as ConstExpNode) != null) { var name = varNode.name; LocalVarInfo info = null; if (funcInfo.VarDic1.TryGetValue(name, out info)) { funcInfo.EmitMove(info.RegIndex, vRegs[i]); } else if (funcInfo.UpValOfIndex(name) >= 0) { int b = funcInfo.UpValOfIndex(name); funcInfo.EmitSetUpval(vRegs[i], b); } else if (funcInfo.ConstDic.TryGetValue(varNode.name, out r)) { funcInfo.EmitLoadK(vRegs[i], varNode.name); } else //全局变量 { int a = funcInfo.UpValOfIndex("_ENV"); if (kRegs[i] <= 0) { int b = 0x100 + funcInfo.IndexOfConstVar(name); funcInfo.EmitSetTabUp(a, b, vRegs[i]); } else { funcInfo.EmitSetTabUp(a, kRegs[i], vRegs[i]); } } } else { funcInfo.EmitSetTable(tRegs[i], kRegs[i], vRegs[i]); } i++; } funcInfo.UsedReg = oldRegs; }