/BrainFuckCompiler/Program.cs
C# | 130 lines | 126 code | 4 blank | 0 comment | 3 complexity | 26f78e5c0b21785616710cb6c9915217 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Text;
- using ZackFlame.IronBrainFuck.JIT;
-
- namespace BrainFuckCompiler
- {
- public static class Program
- {
- static readonly MethodInfo get_In, get_Out;
-
- static Program()
- {
- get_In = typeof(Console).GetProperty("In").GetGetMethod();
- get_Out = typeof(Console).GetProperty("Out").GetGetMethod();
- }
-
- public static void Main(string[] args)
- {
- string compilerName = Path.GetFileName(
- System.Reflection.Assembly.GetExecutingAssembly().Location);
-
- if (args.Length < 2)
- {
- Console.WriteLine(string.Format(
- "IronBrainFuck command-line compiler" +
- "{0}" +
- "{0}Usage: {1} <brainFuckCodeFile> <outputPath>" +
- "{0}e.g. {1} brain.bf c:\brain.exe",
- Environment.NewLine,
- compilerName));
- }
- else
- {
- string assemblyName = Path.GetFileNameWithoutExtension(args[1]);
- string directory = Path.GetDirectoryName(args[1]);
- if (directory.Length == 0)
- directory = ".\\";
-
- try
- {
- string brainFuckProgram = File.ReadAllText(args[0]);
- CompileAndSave(brainFuckProgram, assemblyName, directory);
-
- Environment.Exit(0);
- }
- catch (FileNotFoundException ex)
- {
- Console.Error.WriteLine("{0}: specified file '{1}' not found",
- compilerName, ex.FileName);
- Environment.Exit(1);
- }
- catch (IOException ex)
- {
- Console.Error.WriteLine("{0}: IO error: {1}",
- compilerName, ex.Message);
- Environment.Exit(2);
- }
- catch (System.Security.SecurityException ex)
- {
- Console.Error.WriteLine("{0}: security error: {1}",
- compilerName, ex.Message);
- Environment.Exit(3);
- }
- catch (InvalidProgramException ex)
- {
- Console.Error.WriteLine("{0}: invalid BrainFuck program: {1}",
- compilerName, ex.Message);
- Environment.Exit(4);
- }
- }
- }
-
- public static void CompileAndSave(string brainFuckProgram, string assemblyName, string saveDirectory)
- {
- AppDomain appDomain = AppDomain.CurrentDomain;
-
- AssemblyName name = new AssemblyName(assemblyName);
- AssemblyBuilder assemblyBuilder = appDomain.DefineDynamicAssembly(
- name, AssemblyBuilderAccess.RunAndSave, saveDirectory);
-
- ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(
- "BrainFuckProgram", assemblyName + ".exe");
-
- TypeBuilder typeBuilder = moduleBuilder.DefineType("Program",
- TypeAttributes.Class |
- TypeAttributes.Public |
- TypeAttributes.Sealed);
-
- MethodBuilder brainMethod = typeBuilder.DefineMethod("Execute",
- MethodAttributes.Public |
- MethodAttributes.Static,
- typeof(UInt16),
- new Type[]
- {
- typeof(UInt16[]), typeof(UInt16), // Cells, CellIndex
- typeof(TextReader), typeof(TextWriter) // Input, Output
- });
-
- ILGenerator brainIL = brainMethod.GetILGenerator();
- BrainCompiler.GenerateIL(brainIL, brainFuckProgram);
-
- MethodBuilder mainMethod = typeBuilder.DefineMethod("Main",
- MethodAttributes.HideBySig |
- MethodAttributes.Public |
- MethodAttributes.Static,
- typeof(Int32),
- new Type[] { typeof(string[]) });
-
- ILGenerator mainIL = mainMethod.GetILGenerator();
- mainIL.Emit(OpCodes.Ldc_I4, (int)UInt16.MaxValue + 1);
- mainIL.Emit(OpCodes.Newarr, typeof(UInt16));
- mainIL.Emit(OpCodes.Ldc_I4_0);
- mainIL.Emit(OpCodes.Call, get_In);
- mainIL.Emit(OpCodes.Call, get_Out);
- mainIL.Emit(OpCodes.Call, brainMethod);
- mainIL.Emit(OpCodes.Ret);
-
- typeBuilder.CreateType();
-
- assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);
- assemblyBuilder.Save(assemblyName + ".exe",
- PortableExecutableKinds.ILOnly, ImageFileMachine.I386);
- }
- }
- }