Example #1
0
        private static bool CompileCodeBlockAST(Core core, ParseParam parseParams)
        {
            Dictionary <int, List <VariableLine> > unboundIdentifiers = new Dictionary <int, List <VariableLine> >();
            IEnumerable <BuildData.WarningEntry>   warnings           = null;

            ProtoCore.BuildStatus buildStatus = null;
            try
            {
                int                    blockId   = ProtoCore.DSASM.Constants.kInvalidIndex;
                CodeBlockNode          codeblock = new CodeBlockNode();
                List <AssociativeNode> nodes     = new List <AssociativeNode>();
                foreach (var i in parseParams.ParsedNodes)
                {
                    AssociativeNode assocNode = i as AssociativeNode;

                    if (assocNode != null)
                    {
                        nodes.Add(NodeUtils.Clone(assocNode));
                    }
                }
                codeblock.Body.AddRange(nodes);

                bool parsingPreloadFlag = core.IsParsingPreloadedAssembly;
                bool parsingCbnFlag     = core.IsParsingPreloadedAssembly;
                core.IsParsingPreloadedAssembly = false;
                core.IsParsingCodeBlockNode     = true;

                core.ResetForPrecompilation();
                buildStatus = PreCompile(string.Empty, core, codeblock, out blockId);

                core.IsParsingCodeBlockNode     = parsingCbnFlag;
                core.IsParsingPreloadedAssembly = parsingPreloadFlag;

                parseParams.AppendErrors(buildStatus.Errors);
                parseParams.AppendWarnings(buildStatus.Warnings);

                if (buildStatus.ErrorCount > 0)
                {
                    return(false);
                }
                warnings = buildStatus.Warnings;

                // Get the unboundIdentifiers from the warnings
                GetInputLines(parseParams.ParsedNodes, warnings, unboundIdentifiers);
                foreach (KeyValuePair <int, List <VariableLine> > kvp in unboundIdentifiers)
                {
                    foreach (VariableLine vl in kvp.Value)
                    {
                        parseParams.AppendUnboundIdentifier(vl.variable);
                    }
                }

                return(true);
            }
            catch (Exception)
            {
                buildStatus = null;
                return(false);
            }
        }
Example #2
0
        /// <summary>
        /// Check does some sanity check, e.g., if a variable is re-defined.
        /// </summary>
        /// <param name="asts"></param>
        private static List <WarningEntry> Check(IEnumerable <AssociativeNode> asts)
        {
            var warnings = new List <WarningEntry>();

            HashSet <string> scope = new HashSet <string>();

            foreach (var node in asts)
            {
                BinaryExpressionNode bnode = node as BinaryExpressionNode;
                if (bnode == null || bnode.Optr != Operator.assign)
                {
                    var fNode = node as FunctionDefinitionNode;
                    if (fNode != null)
                    {
                        var fbody = NodeUtils.Clone(fNode.FunctionBody) as CodeBlockNode;
                        var body  = fbody.Body;

                        warnings.AddRange(Check(body));

                        fNode.FunctionBody.Body.Clear();
                        fNode.FunctionBody.Body.AddRange(body.Where(n => !n.skipMe));
                    }

                    continue;
                }

                IdentifierNode ident = bnode.LeftNode as IdentifierNode;
                if (ident == null)
                {
                    continue;
                }

                var variable = ident.Value;

                if (!scope.Contains(variable))
                {
                    scope.Add(variable);

                    VariableFinder finder = new VariableFinder(variable);

                    var langNode = bnode.RightNode as LanguageBlockNode;
                    if (langNode != null)
                    {
                        var cbn = langNode.CodeBlockNode as CodeBlockNode;
                        if (cbn != null)
                        {
                            var copy = NodeUtils.Clone(cbn) as CodeBlockNode;

                            warnings.AddRange(Check(copy.Body));

                            cbn.Body.Clear();
                            cbn.Body.AddRange(copy.Body.Where(n => !n.skipMe));
                        }
                        continue;
                    }
                    bnode.RightNode.Accept(finder);

                    if (finder.Found)
                    {
                        warnings.Add(new WarningEntry
                        {
                            Message = String.Format(Resources.VariableRecursiveReference, variable),
                        });
                        node.skipMe = true;
                    }
                }
                else if (ident.ArrayDimensions == null)
                {
                    warnings.Add(new WarningEntry
                    {
                        Message = String.Format(Resources.VariableRedifinitionError, variable),
                    });
                    node.skipMe = true;
                }
            }

            return(warnings);
        }
Example #3
0
        private static bool CompileCodeBlockAST(Core core, ParseParam parseParams)
        {
            var unboundIdentifiers = new Dictionary <int, List <VariableLine> >();

            ProtoCore.BuildStatus buildStatus = null;
            try
            {
                int blockId = ProtoCore.DSASM.Constants.kInvalidIndex;


                bool parsingPreloadFlag = core.IsParsingPreloadedAssembly;
                bool parsingCbnFlag     = core.IsParsingPreloadedAssembly;
                core.IsParsingPreloadedAssembly = false;
                core.IsParsingCodeBlockNode     = true;

                core.ResetForPrecompilation();

                var astNodes = parseParams.ParsedNodes;

                // Lookup namespace resolution map in elementResolver to rewrite
                // partial classnames with their fully qualified names in ASTs
                // before passing them for pre-compilation. If partial class is not found in map,
                // update Resolution map in elementResolver with fully resolved name from compiler.
                ElementRewriter.RewriteElementNames(core.ClassTable, parseParams.ElementResolver, astNodes);

                // Clone a disposable copy of AST nodes for PreCompile() as Codegen mutates AST's
                // while performing SSA transforms and we want to keep the original AST's
                var codeblock = new CodeBlockNode();
                var nodes     = astNodes.OfType <AssociativeNode>().Select(assocNode => NodeUtils.Clone(assocNode)).ToList();
                codeblock.Body.AddRange(nodes);

                buildStatus = PreCompile(string.Empty, core, codeblock, out blockId);

                core.IsParsingCodeBlockNode     = parsingCbnFlag;
                core.IsParsingPreloadedAssembly = parsingPreloadFlag;

                parseParams.AppendErrors(buildStatus.Errors);
                parseParams.AppendWarnings(buildStatus.Warnings);

                if (buildStatus.ErrorCount > 0)
                {
                    return(false);
                }
                IEnumerable <BuildData.WarningEntry> warnings = buildStatus.Warnings;

                // Get the unboundIdentifiers from the warnings
                GetInputLines(parseParams.ParsedNodes, warnings, unboundIdentifiers);
                foreach (KeyValuePair <int, List <VariableLine> > kvp in unboundIdentifiers)
                {
                    foreach (VariableLine vl in kvp.Value)
                    {
                        parseParams.AppendUnboundIdentifier(vl.displayName, vl.variable);
                    }
                }

                return(true);
            }
            catch (Exception)
            {
                buildStatus = null;
                return(false);
            }
        }