private void CGTableConstructorExp(FuncInfo funcInfo, TableConstructorExpNode node, int a) { int nArray = 0; foreach (var key in node.KeyExpList) { var nilNode = key as ConstExpNode; if (nilNode != null && nilNode.ExpType == ConstExpNode.ConstExpType.NilExp) { nArray++; } } int nExps = node.KeyExpList.Count; funcInfo.EmitNewTable(a, nArray, nExps - nArray); int i = 0; foreach (var key in node.KeyExpList) { var nilNode = key as ConstExpNode; var valNode = node.ValExpList[i]; if (nilNode.ExpType == ConstExpNode.ConstExpType.NilExp) { } int b = funcInfo.AllocReg(); CGExp(funcInfo, key, b, 1); int c = funcInfo.AllocReg(); CGExp(funcInfo, valNode, c, 1); funcInfo.FreeRegs(2); funcInfo.EmitSetTable(a, b, c); i++; } }
private void CGTableAccessExp(FuncInfo funcInfo, TableAccessExpNode node, int a) { int b = funcInfo.AllocReg(); CGExp(funcInfo, node.PreExp, b, 1); int c = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp, c, 1); funcInfo.EmitGetTable(a, b, c); funcInfo.FreeRegs(2); }
private void CGConcatExp(FuncInfo funcInfo, ConcatExpNode node, int a) { foreach (var exp in node.ExpList) { int r = funcInfo.AllocReg(); CGExp(funcInfo, exp, r, 1); } int c = funcInfo.UsedReg - 1; int b = node.ExpList.Count - 1; funcInfo.FreeRegs(c - b + 1); funcInfo.EmitABC(a, b, c, OP.OP_CONCAT); }
private void CGBinOpExp(FuncInfo funcInfo, DoubleOperationExpNode node, int a) { switch (node.OpType) { case TokenType.And: case TokenType.Or: { int b = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp1, b, 1); funcInfo.FreeReg(); if (node.OpType == TokenType.And) { funcInfo.EmitTestSet(a, b, 0); } else { funcInfo.EmitTestSet(a, b, 1); } int jmpPC = funcInfo.EmitJMP(0, 0); int c = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp2, c, 1); funcInfo.FreeReg(); funcInfo.EmitMove(a, c); funcInfo.FixSBX(jmpPC, funcInfo.PC() - jmpPC); break; } default: { int b = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp1, b, 1); int c = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp2, c, 1); funcInfo.EmitDoubleOperator(a, b, c, node.OpType); funcInfo.FreeRegs(2); break; } } }
private int PrepFuncCall(FuncInfo funcInfo, FuncCallExpNode node, int a) { int nArgs = node.Args.Count; bool lastVarIsVarargOrFuncCall = false; CGExp(funcInfo, node.PreExp, a, 1); if (node.NameExp.ExpType != ConstExpNode.ConstExpType.NilExp) { int c = 0x100 + funcInfo.IndexOfConstVar(node.NameExp.name); funcInfo.EmitSelf(a, a, c); } int i = 0; foreach (var arg in node.Args) { int r = funcInfo.AllocReg(); if (i == nArgs - 1 && IsVarargOrFuncCall(arg)) { lastVarIsVarargOrFuncCall = true; CGExp(funcInfo, arg, r, -1); } else { CGExp(funcInfo, arg, r, 1); } i++; } funcInfo.FreeRegs(nArgs); if (node.NameExp.ExpType != ConstExpNode.ConstExpType.NilExp) { nArgs++; } if (lastVarIsVarargOrFuncCall) { nArgs--; } return(nArgs); }
private void CGReturnStat(FuncInfo funcInfo, List <ExpNode> returneExps) { if (returneExps == null) { funcInfo.EmitReturn(0, 0); return; } bool muleRet = IsVarargOrFuncCall(returneExps.Last()); foreach (var exp in returneExps) { int r = funcInfo.AllocReg(); if (r == returneExps.Count - 1 && muleRet) { CGExp(funcInfo, exp, r, -1); } else { CGExp(funcInfo, exp, r, 1); } } funcInfo.FreeRegs(returneExps.Count); }