private void CGExp(FuncInfo funcInfo, ExpNode node, int r, int n) { switch (node.Type) { case GrammarNodeType.ConstExp: var constNode = node as ConstExpNode; switch (constNode.ExpType) { case ConstExpNode.ConstExpType.FalseExp: funcInfo.EmitLoadBool(r, 0, 0); break; case ConstExpNode.ConstExpType.IdentifierExp: CGNameExp(funcInfo, constNode, r); break; case ConstExpNode.ConstExpType.NilExp: funcInfo.EmitLoadNil(r, n); break; case ConstExpNode.ConstExpType.NumberExp: funcInfo.EmitLoadK(r, constNode.tokenValue); break; case ConstExpNode.ConstExpType.StringExp: funcInfo.EmitLoadK(r, constNode.tokenValue); break; case ConstExpNode.ConstExpType.TrueExp: funcInfo.EmitLoadBool(r, 1, 0); break; case ConstExpNode.ConstExpType.VarargExp: CGVarargExp(funcInfo, constNode, r, n); break; } break; case GrammarNodeType.ParenExp: CGExp(funcInfo, (node as ParenExpNode).Exp, r, 1); break; case GrammarNodeType.TableAccessExp: CGTableAccessExp(funcInfo, node as TableAccessExpNode, r); break; case GrammarNodeType.TableConstructorExp: CGTableConstructorExp(funcInfo, node as TableConstructorExpNode, r); break; case GrammarNodeType.UnaryExp: CGUnaryExp(funcInfo, node as UnaryExpNode, r); break; case GrammarNodeType.FuncCallExp: CGFuncCallExp(funcInfo, node as FuncCallExpNode, r, n); break; case GrammarNodeType.ConcatExp: CGConcatExp(funcInfo, node as ConcatExpNode, r); break; case GrammarNodeType.FunctionDefExp: CGFuncDefExp(funcInfo, node as FuncdefExpNode, r); break; case GrammarNodeType.DoubleOperationExp: CGBinOpExp(funcInfo, node as DoubleOperationExpNode, r); break; } }