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); } }
/// <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); }
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); } }