Beispiel #1
0
        public static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                ErrorReporter.Error("action missing: ./maat [action] ");
            }

            var action = args[0];

            if (action == "init")
            {
                ActionInit();
            }
            else if (action == "update")
            {
                ActionUpdate(".");
            }
            else if (action == "generate")
            {
                ActionGenerate(".");
            }
            else if (action == "build")
            {
                ActionBuild(".");
            }
            else if (action == "run")
            {
                ActionRun(".");
            }
            else if (action == "help")
            {
                ActionHelp();
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        public static void ActionBuild(string projectDir)
        {
            ActionGenerate(projectDir);
            var projectYaml = ParseYaml(projectDir);

            string ninjaName = CommandInterface.IsWindows ? "ninja.exe" : "ninja";

            // Download ninja if running for the first time
            if (!File.Exists(Path.Combine(projectDir, "dist", "bin", ninjaName)))
            {
                Console.WriteLine("Downloading ninja... (this only happens once)");

                var url = CommandInterface.IsWindows ? "https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-win.zip"
                        : CommandInterface.IsOSX ? "https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-mac.zip"
                        : "https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-linux.zip";

                using var client = new HttpClient();
                var ninja = client.GetStreamAsync(url);
                ninja.Wait();

                using (var archive = File.Open(Path.Combine(projectDir, "dist", "bin", "ninja.zip"), FileMode.OpenOrCreate, FileAccess.Write))
                {
                    ninja.Result.CopyTo(archive);
                }

                // Extract the archive
                ZipFile.ExtractToDirectory(Path.Combine(projectDir, "dist", "bin", "ninja.zip"), Path.Combine(projectDir, "dist", "bin"));
                // Remove the archive
                File.Delete(Path.Combine(projectDir, "dist", "bin", "ninja.zip"));

                // On Linux, the file must be set as executable
                if (CommandInterface.IsLinux)
                {
                    CommandInterface.RunCommand("chmod", new string[] { "+x", Path.Combine(projectDir, "dist", "bin", ninjaName) }, ".");
                }
            }

            // If RebuildFC is true, regenerate the compiler
            if (projectYaml.RebuildFC == "always")
            {
                if (!Directory.Exists(Path.Combine(projectDir, "dist", "functional")))
                {
                    ErrorReporter.Error("regenerate-fc set to true, but dist/functional does not exist");
                }

                Console.WriteLine("Rebuilding the compiler...");

                // here we use build instead of release because it is faster
                CommandInterface.RunCommand("dotnet", new string[] { "build" }, Path.Combine(projectDir, "dist", "functional"));

                foreach (var file in
                         Directory.EnumerateFiles(Path.Combine(projectDir, "dist", "functional", "bin", "Debug", "netcoreapp3.1")))
                {
                    File.Copy(file, Path.Combine(projectDir, "dist", "bin", new FileInfo(file).Name), true);
                }
            }

            CommandInterface.RunCommand(Path.Combine(projectDir, "dist", "bin", ninjaName), new string[0], projectDir, true);
        }
Beispiel #4
0
        public SourceFile(string filePath)
        {
            FilePath = filePath;
            if (!FilePath.EndsWith(".f"))
            {
                FilePath += ".f";
            }

            if (!File.Exists(FilePath))
            {
                ErrorReporter.Error("file {0} does not exist", FilePath);
            }

            FileName   = new FileInfo(FilePath).Name;
            ModuleName = "";
            Imports    = new List <string>();
            Includes   = new List <string>();
        }
Beispiel #5
0
        public static (string, string) RunCommand(string cmd, string[] args, string workingDir, bool printOutput = false)
        {
            if (!(IsWindows || IsLinux))
            {
                ErrorReporter.Warning("The command inteface has not been tested on this OS and might not work");
            }

            var process   = new Process();
            var startInfo = new ProcessStartInfo(cmd, string.Join(" ", args))
            {
                UseShellExecute        = false,
                CreateNoWindow         = true,
                RedirectStandardError  = true,
                RedirectStandardOutput = true,
                WorkingDirectory       = workingDir
            };

            process.StartInfo = startInfo;
            process.Start();

            if (printOutput)
            {
                process.OutputDataReceived += (sender, data) => Console.WriteLine(data.Data);
                process.BeginOutputReadLine();
            }

            process.WaitForExit();

            if (process.ExitCode != 0)
            {
                Console.Write(process.StandardError.ReadToEnd());
                ErrorReporter.Error("Command `{0}` failed.", cmd);
            }

            if (printOutput)
            {
                return("", process.StandardError.ReadToEnd());
            }
            return(process.StandardOutput.ReadToEnd(), process.StandardError.ReadToEnd());
        }
Beispiel #6
0
        public static void ActionInit()
        {
            Console.WriteLine("Initializing a new Functional project...");
            Console.Write("Enter the project name: ");
            var projectName = Console.ReadLine(); // TODO: Check if it contains only alphanumerics

            if (Directory.Exists(projectName))
            {
                ErrorReporter.Error("A directory named {0} already exists in this folder.", projectName);
            }

            string defaultToolchain = CommandInterface.IsWindows ? "gcc" // TODO: MSVC support
                             : CommandInterface.IsOSX ? "clang"
                             : "gcc";

            Console.Write("Enter the name of the C toolchain you want to use (default: {0}): ", defaultToolchain);
            string toolchain = Console.ReadLine();

            if (toolchain == "")
            {
                toolchain = defaultToolchain;
            }

            if (!(toolchain == "gcc" || toolchain == "clang"))
            {
                ErrorReporter.Error("Invalid C toolchain. Supported options are GCC (= MinGW on Windows) and Clang");
            }

            Console.WriteLine("Creating the project structure...");

            // Create the directory
            Directory.CreateDirectory(projectName);

            // Initialize project.yml
            File.WriteAllLines(Path.Combine(projectName, "project.yml"), new string[]
            {
                "---",
                "name: " + projectName,
                "main: main.f",
                "ctoolchain: " + toolchain
            });

            // Initialize src/main.f
            Directory.CreateDirectory(Path.Combine(projectName, "src"));
            File.WriteAllLines(Path.Combine(projectName, "src", "main.f"), new string[]
            {
                "module main",
                "",
                "import std.io",
                "",
                "main :: Nil",
                "main = writeStr \"Hello world!\"",
                ""
            });

            // Initialize build directory (just create)
            Directory.CreateDirectory(Path.Combine(projectName, "build"));

            // Initialize dist/bin and dist/std
            Directory.CreateDirectory(Path.Combine(projectName, "dist", "bin"));
            Directory.CreateDirectory(Path.Combine(projectName, "dist", "std"));

            ActionUpdate(projectName);
        }