private static ProjectFile ParseYaml(string projectDir) { if (!new DirectoryInfo(projectDir).Exists) { ErrorReporter.Error("Project folder does not exist"); return(default(ProjectFile)); } var projectFile = new DirectoryInfo(projectDir).GetFiles().FirstOrDefault((fi) => fi.Name == "project.yml" || fi.Name == "project.yaml"); if (projectFile is null) { ErrorReporter.ErrorFL("project file not found", "project.yml"); return(default(ProjectFile)); } var deserializer = new DeserializerBuilder() .WithNamingConvention(NullNamingConvention.Instance) .Build(); var deserialized = deserializer.Deserialize <ProjectFile>(projectFile.OpenText()); // Enums default to the first value so take care of that if (deserialized.CToolChain == CToolChain.NoValue) { ErrorReporter.ErrorFL("required value `ctoolchain` not found", "project.yml"); return(default(ProjectFile)); } return(deserialized); }
public void Parse() { // Read only the first sixty lines foreach (var line in File.ReadLines(FilePath).Take(60)) { if (line.StartsWith("module ", 0)) { if (ModuleName != "") { ErrorReporter.ErrorFL("file can contain only one `module` statement", FileName); } var ind = line.IndexOf(' ', 7); if (ind == -1) { ind = line.Length; } ModuleName = line.Substring(7, ind - 7); if (ModuleName.Any((c) => !char.IsLetterOrDigit(c) && c != '.')) { ErrorReporter.ErrorFL("module name can contain only letters, digits and dots", FileName); } } else if (line.StartsWith("import ", 0)) { var ind = line.IndexOf(' ', 7); if (ind == -1) { ind = line.Length; } var import = line.Substring(7, ind - 7); if (import.Any((c) => !char.IsLetterOrDigit(c) && c != '.')) { ErrorReporter.ErrorFL("an import can contain only letters, digits and dots", FileName); } Imports.Add(import); } else if (line.StartsWith("include \"", 0)) { var ind = line.IndexOf('"', 9); if (ind == -1) { ind = line.Length; } Includes.Add(line.Substring(9, ind - 9)); } } if (ModuleName == "") { ErrorReporter.ErrorFL("no `module` statement found", FileName); } }
public void Parse() { // We go through all includes from all files // This is a list of yet unparsed included files var Includes = new List <string> { RootFilePath }; while (Includes.Count != 0) { var newIncludes = new List <string>(); foreach (var file in Includes) { var parsed = new SourceFile(file); parsed.Parse(); if (parsed.ModuleName != Name) { ErrorReporter.ErrorFL("File is included in module {1} but belongs in module {2}", file, Name, parsed.ModuleName); } foreach (var include in parsed.Includes) { var actualInclude = Path.Combine(new FileInfo(file).DirectoryName, include); if (Files.Contains(actualInclude)) { ErrorReporter.NoteFL("Trying to include {0} into the module {1} but it is already included", file, include, Name); } newIncludes.Add(actualInclude); } foreach (var import in parsed.Imports) { // Standard library imports are handled specially if (import.StartsWith("std", 0)) { Imports.Add(import); continue; } var actualImport = Path.Combine( new FileInfo(file).DirectoryName, import.Replace('.', Path.DirectorySeparatorChar)); if (!Imports.Contains(actualImport)) { Imports.Add(actualImport); } } } Includes.ForEach((x) => Files.Add(x)); Includes.Clear(); Includes = newIncludes; } }