public override CILInstructionMethod BuildNode(ParseTreeNode node) { CILInstructionMethod result = null; var instrMethodParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.INSTR_METHOD); var callParseTreeNode = instrMethodParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_call); if (callParseTreeNode != null) { result = new CallInstruction(); } var callvirtParseTreeNode = instrMethodParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_callvirt); if (callvirtParseTreeNode != null) { result = new CallVirtualInstruction(); } var newobjParseTreeNode = instrMethodParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_newobj); if (newobjParseTreeNode != null) { result = new NewObjectInstruction(); } if (result != null) { var typeParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.type); result.MethodReturnType = TypeParseTreeNodeHelper.GetType(typeParseTreeNode); var typeSpecParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.typeSpec); result.TypeSpecification = TypeSpecParseTreeNodeHelper.GetValue(typeSpecParseTreeNode); var methodNameParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.methodName); result.MethodName = MethodNameParseTreeNodeHelper.GetMethodName(methodNameParseTreeNode); var sigArgs0ParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.sigArgs0); result.MethodArgumentTypes = SigArgs0ParseTreeNodeHelper.GetTypes(sigArgs0ParseTreeNode); var callConvParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.callConv); result.CallConvention = CallConvParseTreeNodeHelper.GetValue(callConvParseTreeNode); return(result); } throw new ArgumentException("Cannot recognize CIL instruction method."); }
public override CILMethod BuildNode(ParseTreeNode node) { var instructions = new List <CILInstruction>(); var instructionsLabels = new List <string>(); var isEntryPoint = false; var localsTypes = new List <CILType>(); var locals = new OrderedDictionary(); var localsAddresses = new List <Guid>(); var methodName = string.Empty; CILType returnType = null; CILCallConvention callConvention = null; var methodHeadParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.methodHead); var methodNameParseTreeNode = methodHeadParseTreeNode.GetFirstChildWithGrammarName(GrammarNames.methodName); methodName = MethodNameParseTreeNodeHelper.GetMethodName(methodNameParseTreeNode); var headSigArgs0ParseTreeNode = methodHeadParseTreeNode.GetFirstChildWithGrammarName(GrammarNames.sigArgs0); var argumentTypes = SigArgs0ParseTreeNodeHelper.GetTypes(headSigArgs0ParseTreeNode); var argumentNames = SigArgs0ParseTreeNodeHelper.GetNames(headSigArgs0ParseTreeNode); var callConvParseTreeNode = methodHeadParseTreeNode.GetFirstChildWithGrammarName(GrammarNames.callConv); callConvention = CallConvParseTreeNodeHelper.GetValue(callConvParseTreeNode); var headTypeParseTreeNode = methodHeadParseTreeNode.GetFirstChildWithGrammarName(GrammarNames.type); returnType = TypeParseTreeNodeHelper.GetType(headTypeParseTreeNode); var methodDeclsParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.methodDecls); while (methodDeclsParseTreeNode != null) { var methodDeclParseTreeNode = methodDeclsParseTreeNode.GetFirstChildWithGrammarName(GrammarNames.methodDecl); var instrParseTreeNode = methodDeclParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.instr); if (instrParseTreeNode != null) { var instruction = _instructionBuilder.BuildNode(instrParseTreeNode); instructions.Add(instruction); } var idParseTreeNode = methodDeclParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.id); if (idParseTreeNode != null) { var label = IdParseTreeNodeHelper.GetValue(idParseTreeNode); instructionsLabels.Add(label); } var dotEntrypointParseTreeNode = methodDeclParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_dotEntrypoint); if (dotEntrypointParseTreeNode != null) { isEntryPoint = true; } var localsHeadParseTreeNode = methodDeclParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.localsHead); if (localsHeadParseTreeNode != null) { var sigArgs0ParseTreeNode = methodDeclParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.sigArgs0); localsTypes = SigArgs0ParseTreeNodeHelper.GetTypes(sigArgs0ParseTreeNode); locals = SigArgs0ParseTreeNodeHelper.GetLocalsDictionary(sigArgs0ParseTreeNode); localsAddresses = localsTypes.Select(x => Guid.NewGuid()).ToList(); } methodDeclsParseTreeNode = methodDeclsParseTreeNode.GetFirstChildWithGrammarName(GrammarNames.methodDecls); } instructions.Reverse(); instructionsLabels.Reverse(); var result = new CILMethod { ArgumentTypes = argumentTypes, Instructions = instructions, InstructionsLabels = instructionsLabels, IsEntryPoint = isEntryPoint, LocalsTypes = localsTypes, LocalsAddresses = localsAddresses, Locals = locals, MethodName = methodName, CallConvention = callConvention, ReturnType = returnType, ArgumentNames = argumentNames }; foreach (var instruction in instructions) { instruction.ParentMethod = result; } return(result); }