Task <Module[]> AnalyzeSource(Parse.Syntax.Source sourceNode, CancellationToken cancel) { var nodesAndModules = new List <Tuple <Parse.Syntax.Module, Module> >(); // collect top-level modules var triviaNodes = new List <Parse.Syntax.Node>(); Module curModule = null; Parse.Syntax.Module moduleNode = null; foreach (var node in sourceNode.Children) { if (cancel.IsCancellationRequested) { throw new OperationCanceledException(cancel); } if ((moduleNode = node as Parse.Syntax.Module) != null) { // look for existing module var moduleName = new QualifiedName { Qualifiers = moduleNode.Qualifiers.Select(id => id.Text), Name = moduleNode.Name.Text }; lock (Unit.Modules) { if (!Unit.Modules.TryGetValue(moduleName, out curModule)) { curModule = new Module { Name = moduleName }; Unit.Modules.Add(curModule.Name, curModule); } foreach (var tn in triviaNodes) { curModule.PreTrivia.Add(tn); } triviaNodes.Clear(); } nodesAndModules.Add(Tuple.Create(moduleNode, curModule)); } else if (node is Parse.Syntax.Directive) { throw new NotImplementedException(); } else if (node is Parse.Syntax.Space) { triviaNodes.Add(node); } else { Unit.AddError(new AnalyzerError { ErrorNode = node, Message = string.Format(ErrorMessages.E_0011_Analyzer_InvalidToplevelItem, ApteridError.Truncate(node.Text)), }); } } if (curModule != null) { foreach (var tn in triviaNodes) { curModule.PostTrivia.Add(tn); } } // analyze var tasks = nodesAndModules.Select(mm => AnalyzeModule(mm.Item1, mm.Item2, cancel)); return(Task.WhenAll(tasks)); }
Task <Module> AnalyzeModule(Parse.Syntax.Module moduleNode, Module module, CancellationToken cancel) { var bindings = new List <Tuple <Parse.Syntax.Binding, Binding> >(); // collect module bindings var triviaNodes = new List <Parse.Syntax.Node>(); Binding curBinding = null; Parse.Syntax.Binding bindingNode = null; foreach (var node in moduleNode.Body) { if (cancel.IsCancellationRequested) { throw new OperationCanceledException(cancel); } if ((bindingNode = node as Parse.Syntax.Binding) != null) { var bindingName = new QualifiedName(module, bindingNode.Name.Text); lock (module.Bindings) { if (module.Bindings.TryGetValue(bindingName, out curBinding)) { Unit.AddError(new AnalyzerError { ErrorNode = node, Message = string.Format(ErrorMessages.E_0012_Analyzer_DuplicateBinding, bindingName.Name), }); } else { curBinding = new Binding { Parent = module, Name = bindingName, SyntaxNode = bindingNode }; bindings.Add(Tuple.Create(bindingNode, curBinding)); module.Bindings.Add(curBinding.Name, curBinding); } foreach (var tn in triviaNodes) { curBinding.PreTrivia.Add(tn); } triviaNodes.Clear(); } } else if (node is Parse.Syntax.Space) { triviaNodes.Add(node); } else { Unit.AddError(new AnalyzerError { ErrorNode = node, Message = string.Format(ErrorMessages.E_0013_Analyzer_InvalidScopeItem, ApteridError.Truncate(node.Text)), }); } } if (curBinding != null) { foreach (var tn in triviaNodes) { curBinding.PostTrivia.Add(tn); } } // analyze var tasks = bindings.Select(bb => Task.Factory.StartNew(() => AnalyzeBinding(module, bb.Item1, bb.Item2, cancel), TaskCreationOptions.AttachedToParent)); return(Task.WhenAll(tasks).ContinueWith(t => module)); }
void ResolveTypes(IEnumerable <Module> modules, CancellationToken cancel) { var trr = new TypeResolveRec { Constraint = s => new[] { s }, // true ExpTypeVars = Enumerable.Empty <Tuple <Expression, Var> >(), }; trr = modules.Aggregate(trr, (mtr, m) => { if (cancel.IsCancellationRequested) { throw new OperationCanceledException(cancel); } return(m.Bindings.Values.Aggregate(mtr, (btr, b) => { if (cancel.IsCancellationRequested) { throw new OperationCanceledException(cancel); } return ResolveExpressionType(btr, b.Expression); })); }); try { var varTypes = Goal.Eval(trr.Constraint).First(); foreach (var expVar in trr.ExpTypeVars) { var e = expVar.Item1; var v = expVar.Item2; if (varTypes.Binds(v)) { e.ResolvedType = varTypes[v]; } else { Unit.AddError(new AnalyzerError { ErrorNode = e.SyntaxNode, Message = string.Format(ErrorMessages.E_0015_Analyzer_UnableToInferType, ApteridError.Truncate(e.SyntaxNode.Text)), }); } } } catch (OperationCanceledException) { throw; } catch (Exception e) { Unit.AddError(new AnalyzerError { Exception = e }); } }
void GenerateLiteralBinding(GenerateTypeInfo typeInfo, Analyze.Binding binding, Analyze.Expressions.Literal literal) { if (literal.ResolvedType == null) { Unit.AddError(new GeneratorError { Message = string.Format(ErrorMessages.E_0017_Generator_UnresolvedType, ApteridError.Truncate(literal.SyntaxNode.Text)), ErrorNode = literal.SyntaxNode }); return; } var atts = FieldAttributes.Static | FieldAttributes.InitOnly; atts |= binding.IsPublic ? FieldAttributes.Public : FieldAttributes.Private; var field = typeInfo.TypeBuilder.DefineField(binding.Name.Name, literal.ResolvedType.CLRType, atts); typeInfo.Bindings.Add(literal, field); if (literal.Value == null) { if (field.FieldType.IsValueType) { field.SetConstant(Activator.CreateInstance(field.FieldType)); } else { field.SetConstant(null); } } else { typeInfo.StaticFieldsToInit.Add(new FieldInitInfo { Node = binding.SyntaxNode, Field = field, GenLoad = il => GenerateLoadLiteral(il, literal, field.FieldType) }); } }