ネタ元:
負けじと C# 版のコンパイラを作ってみましたw
単に C# のソースを吐き出すだけではなくて、無駄に CodeDOM を使って実際に exe ファイルを出力するようにしてみました。
using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom.Compiler;
using System.Diagnostics;
using Microsoft.CSharp;
namespace TestBrainf_ck
{
class Brainf_ckCompiler
{
delegate string Action();
Dictionary<char, Action> actionDictionary;
public Brainf_ckCompiler()
{
actionDictionary = new Dictionary<char, Action>();
actionDictionary.Add('>', delegate { return "++ptr;"; });
actionDictionary.Add('<', delegate { return "--ptr;"; });
actionDictionary.Add('+', delegate { return "++memory[ptr];"; });
actionDictionary.Add('-', delegate { return "--memory[ptr];"; });
actionDictionary.Add(',', delegate { return "memory[ptr] = Console.ReadKey(true).KeyChar;"; });
actionDictionary.Add('.', delegate { return "Console.Write(memory[ptr]);"; });
actionDictionary.Add('[', delegate { return "while(memory[ptr] != 0){"; });
actionDictionary.Add(']', delegate { return "}"; });
}
public bool Compile(string program, string outputFileName)
{
string source = ToCSharp(program);
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = true;
cp.CompilerOptions += "/out:" + outputFileName + " /optimize";
Console.WriteLine("コンパイルしています...");
CodeDomProvider cdp = new CSharpCodeProvider();
CompilerResults cr = cdp.CompileAssemblyFromSource(cp, source);
foreach (CompilerError error in cr.Errors)
{
if (error.IsWarning)
{
Console.WriteLine("warning: " + error.ErrorText);
}
else
{
Console.WriteLine("error: " + error.ErrorText);
}
}
if (!cr.Errors.HasErrors)
{
Console.WriteLine("コンパイルに成功しました");
return true;
}
else
{
Console.WriteLine("コンパイルに失敗しました");
return false;
}
}
private string ToCSharp(string program)
{
StringBuilder sourceBuilder = new StringBuilder();
sourceBuilder.Append(@"
using System;
class Brainf_ck
{
[STAThread]
static void Main()
{
int ptr = 0;
char[] memory = new char[65536];
");
foreach (char c in program)
{
if (actionDictionary.ContainsKey(c))
{
sourceBuilder.AppendLine(actionDictionary[c]());
}
}
sourceBuilder.Append(@"
}
}
");
return sourceBuilder.ToString();
}
}
class Program
{
static void Main(string[] args)
{
string program = @"
>+++++++++[<++++++++>-]<.
>+++++++[<++++>-]<+.
+++++++.
.
+++.
[-]>++++++++[<++++>-]<.
>+++++++++++[<+++++>-]<.
++++++++++.
>++[<++++++>-]<+.
---.
>++[<+++++>-]<.
--------.
>++[<------>-]<.
[-]>++++++++[<++++++++>-]<-.
[-]>++[<+++++>-]<.
,";
Brainf_ckCompiler compiler = new Brainf_ckCompiler();
compiler.Compile(program, "Brainf_ck.exe");
Process process = new Process();
process.StartInfo.FileName = "Brainf_ck.exe";
process.Start();
process.WaitForExit();
}
}
}
CodeDOM 作った人はマジ変態だと思います(><;)