internal static void Main(string[] args) { if (args.Length < 1) { Console.Error.WriteLine(ERROR_STRING + "no path provided"); return; } string path; string[] arguments = GetOptions(args, out path); // If /b option is provided, use "basic" or "concise" or "classic" folders interpreting // Basic Folders is now legacy bool pureFolders = !(arguments.Contains("b")); bool exe = !(arguments.Contains("e")); // If /s option is provided, put code out as C# string if (arguments.Contains("s")) { ProgramBuilder builder = ProgramBuilder.Generate(pureFolders, path); builder.BuildProgram(); Console.Write(builder.ProgramText); return; } // Otherwise, compile the program string errors = ""; bool succeeded = Compile(path, ref errors, exe, pureFolders); Console.WriteLine(); // clear line after program output if (succeeded) { Console.WriteLine("Complete"); } else { Console.Error.Write(ERROR_STRING); Console.Error.WriteLine(errors); } }
/// <summary> /// Actually build the Folders program /// </summary> /// <param name="path">path to root directory of the Folders program</param> /// <param name="errors">used to return error messages</param> /// <param name="exe">whether we create an exe or simply compile + run in memory</param> /// <param name="pureFolders">Pure Folders (non-semantic folder names) vs the (legacy) Classic Folders Syntax</param> /// <returns></returns> public static bool Compile(string path, ref string errors, bool exe, bool pureFolders) { ProgramBuilder builder = ProgramBuilder.Generate(pureFolders, path); builder.BuildProgram(); StringBuilder errorList = new StringBuilder(); string entireProgram = "#include <bits/stdc++.h>\n" + builder.Declarations + "int main() {\n" + builder.ProgramText + "\n}"; Console.WriteLine(entireProgram); if (errorList.Length > 0) { errors = errorList.ToString(); return(false); } // we have successfully compiled return(true); }
/// <summary> /// Actually build the Folders program /// </summary> /// <param name="path">path to root directory of the Folders program</param> /// <param name="errors">used to return error messages</param> /// <param name="exe">whether we create an exe or simply compile + run in memory</param> /// <param name="pureFolders">Pure Folders (non-semantic folder names) vs the (legacy) Classic Folders Syntax</param> /// <returns></returns> public static bool Compile(string path, ref string errors, bool exe, bool pureFolders) { ProgramBuilder builder = ProgramBuilder.Generate(pureFolders, path); builder.BuildProgram(); StringBuilder errorList = new StringBuilder(); CompilerResults results; string entireProgram = @"using System; using System.IO; using Rottytooth.Esolang.Folders.Runtime; public static class Program { private static VarManager _varManager; static Program() { _varManager = new VarManager(""" + builder.ProgramName + @"""); } " + builder.Declarations + @" public static void Main() { " + builder.ProgramText + @" } } public class StartUp { public void Execute() { Program.Main(); } }"; using (CSharpCodeProvider csc = new CSharpCodeProvider(new Dictionary <string, string>() { { "CompilerVersion", "v4.0" } })) { if (exe) // building to an executable { CompilerParameters parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, builder.ProgramName + ".exe", true); parameters.ReferencedAssemblies.Add("Rottytooth.Esolang.Folders.Runtime.dll"); parameters.GenerateExecutable = true; results = csc.CompileAssemblyFromSource(parameters, entireProgram); } else // compiling in-memory and executing { CompilerParameters parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }) { GenerateInMemory = true }; parameters.ReferencedAssemblies.Add("Rottytooth.Esolang.Folders.Runtime.dll"); results = csc.CompileAssemblyFromSource(parameters, entireProgram); if (results.Errors != null && results.Errors.Count == 0) { Type type = results.CompiledAssembly.GetType("StartUp"); var obj = Activator.CreateInstance(type); var output = type.GetMethod("Execute").Invoke(obj, new object[] { }); } } } // output any errors results.Errors.Cast <CompilerError>().ToList().ForEach(error => errorList.AppendLine(error.ErrorText)); if (errorList.Length > 0) { errors = errorList.ToString(); return(false); } // we have successfully compiled return(true); }