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 }); } }
public override Action GetStepAction(CancellationToken cancel) { return(() => { if (Analyzer == null) { lock (this) { if (Analyzer == null) { Analyzer = new ApteridAnalyzer(Context, ParseUnit.SourceFile, Unit); } } } try { Analyzer.Analyze(cancel); } 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) }); } }
public void Analyze(CancellationToken cancel) { var sourceNode = SourceFile.ParseTree as Parse.Syntax.Source; if (sourceNode == null) { Unit.AddError(new AnalyzerError { ErrorNode = SourceFile.ParseTree, Message = string.Format(ErrorMessages.E_0010_Analyzer_ParseTreeIsNotSource, SourceFile.Name) }); return; } var modules = AnalyzeSource(sourceNode, cancel).Result; if (Unit.Errors.Any() && Context.AbortOnError) { return; } ResolveTypes(modules, cancel); }
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)); }
void AnalyzeBinding(Module module, Parse.Syntax.Binding bindingNode, Binding binding, CancellationToken cancel) { if (bindingNode.Body == null || !bindingNode.Body.Any()) { Unit.AddError(new AnalyzerError { ErrorNode = bindingNode, Message = string.Format(ErrorMessages.E_0014_Analyzer_EmptyBinding, bindingNode.Name.Text), }); return; } var triviaNodes = new List <Parse.Syntax.Node>(); Expression expression = null; Parse.Syntax.Literal literalNode; Parse.Syntax.Literal <BigInteger> bigIntLiteral; foreach (var node in bindingNode.Body) { if (cancel.IsCancellationRequested) { throw new OperationCanceledException(cancel); } if ((literalNode = node as Parse.Syntax.Literal) != null) { if ((bigIntLiteral = literalNode as Parse.Syntax.Literal <BigInteger>) != null) { expression = new Expressions.IntegerLiteral(bigIntLiteral.Value) { SyntaxNode = bigIntLiteral }; } else { throw new NotImplementedException(string.Format("Literals of type {0} not implemented yet.", literalNode.ValueType.Name)); } } else if (node is Parse.Syntax.Space) { triviaNodes.Add(node); } } if (expression == null) { Unit.AddError(new AnalyzerError { ErrorNode = bindingNode, Message = string.Format(ErrorMessages.E_0014_Analyzer_EmptyBinding, bindingNode.Name.Text), }); return; } foreach (var tn in triviaNodes) { expression.PostTrivia.Add(tn); } binding.Expression = expression; }
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)); }
public override Action GetStepAction(CancellationToken cancel) { return(() => { try { // set up compilation units if (Unit.ParseUnits == null) { Unit.ParseUnits = Unit.SourceFiles .Where(sf => (Unit.Mode & CompileOutputMode.SaveToFile) == 0 || Context.ForceRecompile || !sf.Exists || Unit.OutputFileInfo == null || sf.LastWriteTimeUtc > Unit.OutputFileInfo.LastWriteTimeUtc) .Select(sf => new ParseUnit { SourceFile = sf }) .ToList(); } // TODO: make dummy modules from references if (Unit.AnalysisUnit == null) { lock (Unit) { if (Unit.AnalysisUnit == null) { Unit.AnalysisUnit = new AnalysisUnit { ParseUnits = Unit.ParseUnits }; } } } if (Unit.GenerationUnit == null) { lock (Unit) { if (Unit.GenerationUnit == null) { Unit.GenerationUnit = new GenerationUnit { Mode = Unit.Mode, ParseUnits = Unit.ParseUnits, AnalysisUnit = Unit.AnalysisUnit, }; } } } // tasks var parseAndAnalyzeActions = new List <Tuple <Action, Action> >(); foreach (var parseUnit in Unit.ParseUnits) { Action parse = null; Action analyze = null; if ((Unit.Mode & CompileOutputMode.Parse) != 0) { parse = new ParseSourceFile(Context, parseUnit).GetStepAction(Context.CancelSource.Token); } if ((Unit.Mode & CompileOutputMode.Analyze) != 0) { analyze = new AnalyzeSourceFile(Context, Unit.AnalysisUnit, parseUnit).GetStepAction(Context.CancelSource.Token); } parseAndAnalyzeActions.Add(Tuple.Create(parse, analyze)); } var tasks = parseAndAnalyzeActions .Select(pa => { if (pa.Item1 != null && pa.Item2 != null) { var parse = Task.Factory.StartNew(pa.Item1, TaskCreationOptions.AttachedToParent); return parse.ContinueWith(t => pa.Item2()); } else if (pa.Item1 != null) { return Task.Factory.StartNew(pa.Item1, TaskCreationOptions.AttachedToParent); } else if (pa.Item2 != null) { return Task.Factory.StartNew(pa.Item2, TaskCreationOptions.AttachedToParent); } else { return null; } }) .Where(t => t != null); Task.WhenAll(tasks).Wait(); if ((Unit.Mode & CompileOutputMode.Generate) != 0 && !Unit.Errors.Any()) { var generate = new GenerateAssembly(Context, Unit).GetStepAction(Context.CancelSource.Token); var task = Task.Factory.StartNew(generate, TaskCreationOptions.AttachedToParent); task.Wait(); } } catch (OperationCanceledException) { throw; } catch (Exception e) { Unit.AddError(new CompilerError { Exception = e }); } }); }
public override Action GetStepAction(CancellationToken cancel) { return(() => { var sourceFile = Unit.SourceFile; // verify that the source file exists if (!sourceFile.Exists) { Unit.AddError <NodeError>(string.Format(ErrorMessages.E_0006_Compiler_InvalidSourceFile, sourceFile.Name)); if (Context.AbortOnError) { return; } } if (cancel.IsCancellationRequested) { throw new OperationCanceledException(cancel); } // parse try { if (Unit.Parser == null) { lock (this) { if (Unit.Parser == null) { Unit.Parser = new ApteridParser(handle_left_recursion: true); } } } var parser = Unit.Parser; parser.SourceFile = sourceFile; sourceFile.Parser = parser; var result = parser.GetMatch(sourceFile.Buffer, parser.ApteridSource); sourceFile.MatchResult = result; sourceFile.MatchState = result.MatchState; if (cancel.IsCancellationRequested) { throw new OperationCanceledException(cancel); } if (result.Success) { // check for error sections sourceFile.ParseTree = result.Result; var errorSections = sourceFile.GetNodes <Parse.Syntax.ErrorSection>(); foreach (var es in errorSections) { var error = new NodeError { SourceFile = sourceFile, Message = ErrorMessages.E_0007_Parser_SyntaxError, ErrorNode = es, ErrorIndex = es.StartIndex }; Unit.AddError(error); } } else { var error = new NodeError { SourceFile = sourceFile, Message = result.Error, ErrorIndex = result.ErrorIndex }; Unit.AddError(error); } } catch (OperationCanceledException) { throw; } catch (Exception e) { Unit.AddError(new NodeError { Exception = e }); } }); }
public override Action GetStepAction(CancellationToken cancel) { return(() => { try { var saveToFile = (Unit.Mode & CompileOutputMode.SaveToFile) != 0; var emitSymbols = (Unit.Mode & CompileOutputMode.EmitSymbols) != 0; var optimize = (Unit.Mode & CompileOutputMode.Optimize) != 0; if (saveToFile && !Unit.OutputFileInfo.Directory.Exists) { Unit.AddError(new CompilerError { Message = ErrorMessages.E_0016_Compiler_InvalidOutputDir }); saveToFile = false; } var access = saveToFile ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run; var assemblyName = GetAssemblyName(); if (Unit.GenerationUnit.AssemblyBuilder == null) { lock (Unit) { if (Unit.GenerationUnit.AssemblyBuilder == null) { var assemblyBuilder = Unit.GenerationUnit.AssemblyBuilder = saveToFile ? AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, access, Unit.OutputFileInfo.Directory.FullName) : AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, access); Unit.GenerationUnit.ModuleBuilder = null; if (emitSymbols) { var modes = DebuggableAttribute.DebuggingModes.Default; if (!optimize) { modes |= DebuggableAttribute.DebuggingModes.DisableOptimizations; } var ctor = typeof(DebuggableAttribute).GetConstructor(new[] { typeof(DebuggableAttribute.DebuggingModes) }); var attb = new CustomAttributeBuilder(ctor, new object[] { modes }); assemblyBuilder.SetCustomAttribute(attb); } } } } if (Unit.GenerationUnit.ModuleBuilder == null) { lock (Unit) { if (Unit.GenerationUnit.ModuleBuilder == null) { var moduleBuilder = Unit.GenerationUnit.ModuleBuilder = saveToFile ? Unit.GenerationUnit.AssemblyBuilder.DefineDynamicModule(Unit.OutputFileInfo.Name, Unit.OutputFileInfo.Name, emitSymbols) : Unit.GenerationUnit.AssemblyBuilder.DefineDynamicModule(Unit.OutputFileInfo.Name, emitSymbols); if (emitSymbols) { foreach (var sf in Unit.SourceFiles) { Unit.GenerationUnit.SymbolDocs[sf.Name] = moduleBuilder.DefineDocument(sf.Name, SourceFile.ApteridLanguageId, SourceFile.ApteridLanguageVendorId, SourceFile.ApteridLanguageSourceFileId); } } } } } var generators = Unit.AnalysisUnit.Modules.Values .Select(m => Task.Factory.StartNew(new GenerateModule(Context, Unit.GenerationUnit, m) .GetStepAction(Context.CancelSource.Token), TaskCreationOptions.AttachedToParent)) .ToArray(); Task.WaitAll(generators); if ((Unit.Mode & CompileOutputMode.SaveToFile) != 0) { var emit = Task.Factory.StartNew(new EmitAssembly(Context, Unit) .GetStepAction(Context.CancelSource.Token), TaskCreationOptions.AttachedToParent); emit.Wait(); } } catch (OperationCanceledException) { throw; } catch (Exception e) { Unit.AddError(new GeneratorError { Exception = e }); } }); }