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.");
        }
Esempio n. 2
0
        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);
        }