Exemple #1
0
        public override IEnumerable <string> Run(ToolContext context)
        {
            var files = context.InputFiles.Select(Path.GetFullPath).ToList();

            if (files.Count == 0)
            {
                return(Enumerable.Empty <string> ());
            }

            var buildDir = Path.GetTempPath();

            var args = new List <string> {
                "-emit-ir", "-g", "-Osize"
            };

            args.AddRange(files);

            var outFiles = new List <string> ();

            if (Run(buildDir, "swiftc", args.ToArray()) == 0)
            {
                foreach (var f in files)
                {
                    var outName = Path.ChangeExtension(Path.GetFileName(f), ".ll");
                    var outPath = Path.Combine(buildDir, outName);
                    Console.WriteLine(outPath);
                    outFiles.Add(outPath);
                }
            }
            return(outFiles);
        }
Exemple #2
0
        public override IEnumerable <string> Run(ToolContext context)
        {
            var files = context.InputFiles.Select(Path.GetFullPath).ToList();

            if (files.Count == 0)
            {
                return(Enumerable.Empty <string> ());
            }

            var srcDir   = Environment.CurrentDirectory;
            var buildDir = Path.GetTempPath();

            var iswin = Environment.OSVersion.Platform == PlatformID.Win32NT;

            var outputAssembly = true;

            var args = new List <string> {
                "-g", "-O1", "-S", "-emit-llvm", "-frtti"
            };

            var argsHasStd = false;

            foreach (var e in context.ExtraArguments)
            {
                switch (e)
                {
                case "-c":
                    outputAssembly = false;
                    args.Add("-o");
                    args.Add(context.OutputFile);
                    break;

                case var _ when e.StartsWith("-O"):
                    // Optimization is already set
                    break;

                case var _ when e.StartsWith("-std"):
                    argsHasStd = true;

                    args.Add(e);
                    break;

                case var _ when e.StartsWith("-I"): {
                    var orig = e.Substring(2);
                    var fix  = Path.GetFullPath(orig, srcDir);
                    args.Add("-I" + fix);
                }
                break;

                default:
                    args.Add(e);
                    break;
                }
            }

            if (!argsHasStd)
            {
                if (context.InputFiles.Any(x => cppExtensions.Contains(Path.GetExtension(x))))
                {
                    args.Add("-std=c++17");
                }
                else
                {
                    args.Add("-std=c99");
                }
            }

            if (!iswin)
            {
                args.Add("-fpic");
            }

            args.AddRange(files);
            var clangFileCount = files.Count;

            args.Insert(0, "-I" + Environment.CurrentDirectory);

            var outFiles = new List <string> ();

            var clangResult = clangFileCount > 0 ? Run(buildDir, "clang", args.ToArray()) : 0;

            if (clangResult == 0)
            {
                if (outputAssembly)
                {
                    foreach (var f in files)
                    {
                        var outPath = GetOutFilePath(buildDir, f);
                        //Console.WriteLine ($"OUTLL = {outPath}");
                        outFiles.Add(outPath);
                    }
                }
                else
                {
                }
            }

            return(outFiles);
        }
Exemple #3
0
        static int Main(string[] args)
        {
            //
            // Start loading in the background
            //
            Library.LoadStandardLibrariesAsync();

            //
            // Inputs
            //
            var files       = new List <string> ();
            var extraArgs   = new List <string> ();
            var outName     = "";
            var safeMemory  = false;
            var showHelp    = false;
            var showVersion = false;

            //
            // Parse command line
            //
            for (int i = 0; i < args.Length;)
            {
                var a = args[i];
                if (a[0] == '-')
                {
                    if (a == "-o")
                    {
                        if (i + 1 < args.Length)
                        {
                            outName = args[i + 1];
                            i      += 2;
                        }
                        else
                        {
                            i++;
                        }
                    }
                    else if (a == "-h" || a == "--help" || a == "-?")
                    {
                        showHelp = true;
                        i++;
                    }
                    else if (a == "-v" || a == "--version")
                    {
                        showVersion = true;
                        i++;
                    }
                    else if (a == "--safe-memory")
                    {
                        safeMemory = true;
                        i++;
                    }
                    else
                    {
                        extraArgs.Add(a);
                        i++;
                    }
                }
                else
                {
                    files.Add(a);
                    i++;
                }
            }

            if (showVersion)
            {
                var version = typeof(Program).Assembly.GetName().Version;
                Console.WriteLine($"Krueger Systems IRIL {version}");
                if (!showHelp)
                {
                    return(0);
                }
            }

            if (showHelp)
            {
                Console.WriteLine($"OVERVIEW: C/C++ to .NET assembly compiler by Frank A. Krueger");
                Console.WriteLine();
                Console.WriteLine($"USAGE: iril [options] <inputs>");
                Console.WriteLine();
                Console.WriteLine($"INPUTS: .c and .ll files");
                Console.WriteLine();
                Console.WriteLine($"OPTIONS:");
                Console.WriteLine($"  -o <asm file>      Path to the assembly .dll to output");
                Console.WriteLine($"  -h, -?, --help     Display this help");
                Console.WriteLine($"  -v, --version      Display the version");
                Console.WriteLine($"  --safe-memory      Verify memory accesses to make code safe from crashes");
                return(0);
            }

            //
            // Cleanup input
            //
            if (string.IsNullOrWhiteSpace(outName) && files.Count > 0)
            {
                outName = Path.ChangeExtension(Path.GetFileName(files[0]), ".dll");
            }

            //
            // Compile C Files
            //
            var clang   = new ClangTool();
            var cfiles  = files.Where(x => clang.InputExtensions.Contains(Path.GetExtension(x)));
            var context = new ToolContext {
                InputFiles     = cfiles.ToArray(),
                ExtraArguments = extraArgs.ToArray(),
                OutputFile     = outName,
            };
            var cllfiles = clang.Run(context);

            var llfiles = (from f in files
                           let e = Path.GetExtension(f)
                                   where e == ".ll" || e == ".o"
                                   select f)
                          .Concat(cllfiles)
                          .ToList();

            //
            // Early out
            //
            if (llfiles.Count == 0)
            {
                if (context.ExtraArguments.Contains("-c"))
                {
                    return(0);
                }
                Error("No inputs");
                return(1);
            }

            try {
                //
                // Parse
                //
                Info($"Parsing {llfiles.Count} files...");
                var modules = llfiles.AsParallel().Select(x => {
                    var code = File.ReadAllText(x);
                    return(Module.Parse(code, x));
                }).ToList();

                //
                // Compile
                //
                Info("Compiling...");
                var comp = new Compilation(new CompilationOptions(modules, outName, safeMemory: safeMemory));
                comp.Compile();

                //
                // Show errors
                //
                var errors = (from m in modules from e in m.Errors select e)
                             .Concat(comp.Messages)
                             .OrderBy(x => x.FilePath).ThenBy(x => x.Text)
                             .ToList();
                foreach (var e in errors)
                {
                    Console.Write("iril: ");
                    if (e.Type == MessageType.Error)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Write("error: ");
                    }
                    else
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.Write("warning: ");
                    }
                    Console.ResetColor();

                    if (!string.IsNullOrEmpty(e.FilePath))
                    {
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.Write(e.FilePath);
                        Console.Write(": ");
                        Console.ResetColor();
                    }

                    Console.WriteLine(e.Text);

                    if (!string.IsNullOrEmpty(e.Surrounding))
                    {
                        Console.WriteLine(e.Surrounding);
                    }
#if DEBUG
                    if (e.Exception != null)
                    {
                        Console.ForegroundColor = ConsoleColor.DarkYellow;
                        Console.WriteLine(e.Exception);
                        Console.ResetColor();
                    }
#endif
                }

                //
                // Output
                //
                Info($"Writing {outName}...");
                comp.WriteAssembly(outName);

                if (errors.Count > 0)
                {
                    Info($"{errors.Count(x => x.Type == MessageType.Error)} errors, {errors.Count (x => x.Type == MessageType.Warning)} warnings");
                }

                return(modules.Any(m => m.HasErrors) ? 3 : 0);
            }
            catch (Exception ex) {
                Error(ex.ToString());
                return(2);
            }
        }
Exemple #4
0
 public abstract IEnumerable <string> Run(ToolContext context);