さっそくC#でプログラム言語「てってってー」のインタプリタを書いたよ
何かを受信(^o^)ノ
プログラム言語「てってってー」
javascript - てってってー言語を移植してみた - 404 Blog Not Found
Wikipedia - Brainf*ck
というわけで、C#erな自分はC#で「てってってー言語」のインタプリタを書いてみました。
基本「Brainf*ck」のモシャスということで、決して難しい内容ではありません。
時間の都合上真面目にやるのは面倒くさいので、細かいところが本家の仕様と
若干異なっちゃっていたりしますが、ご了承ください(・ω・)
まずは、プログラミング言語「てってってー」仕様から
本家をご参照ください → プログラム言語「てってってー」
てってってーインタプリタC#による実装
using System; using System.Collections.Generic; using System.Text.RegularExpressions; namespace ConsoleApplication1 { /// <summary> /// てってってーインタプリタ /// </summary> public sealed class Tettettee { private const int memorySize = 65535; private string _source; public Tettettee(string source) { _source = source; } /// <summary> /// 分析 /// </summary> /// <returns></returns> private string[] Analyze() { //フィルタリング _source = new Regex(@"[\s]*\{[^\}]+\}").Replace(_source, ""); //分析用の正規表現 var rx = new Regex(@"ー.*?てー|ててー|てっー|てってー|てっててー|てってっー|てってってー|てってっててー|てってってっー"); var list = new List<string>(); foreach (Match m in rx.Matches(_source)) list.Add(m.ToString()); return list.ToArray(); } /// <summary> /// てってってー♪ /// </summary> public unsafe void Run() { var array = Analyze(); char* point = stackalloc char[memorySize]; for (int i = 0; i < array.Length; i++) { switch (array[i]) { case "ててー": //Brainf*ckで言うところの「+」 (*point)++; break; case "てっー": //Brainf*ckで言うところの「-」 (*point)--; break; case "てってー": //Brainf*ckで言うところの「>」 point++; break; case "てっててー": //Brainf*ckで言うところの「<」 point--; break; case "てってっー": //Brainf*ckで言うところの「.」やったあと「>」 Console.Write(*point); point++; break; case "てってってー": //Brainf*ckで言うところの「,」やったあと「>」 *point = ((char)Console.Read()); point++; break; case "てってっててー": //Brainf*ckで言うところの「[」 if (*point == 0) i = Loop(array, i); break; case "てってってっー"://Brainf*ckで言うところの「]」 if (*point != 0) i = Loop(array, i); break; default: //「ー」に一致 //てってってー言語の独自仕様 char[] ar = array[i].ToString().Substring(1, array[i].Length - 3).ToCharArray(); fixed (char* cp = ar) { for (var j = 0; j < ar.Length; j++) { *point = cp[j]; point++; } } break; } } } /// <summary> /// てってってーなループを表現します。 /// </summary> /// <param name="source"></param> /// <param name="index"></param> /// <returns></returns> private static int Loop(string[] source, int index) { int nest = default(int); bool flag = source[index] == "てってっててー"; for (var i = index; flag ? i < source.Length : i >= 0; i = i + (flag ? 1 : -1)) { if (source[i] == "てってっててー") nest++; else if (source[i] == "てってってっー") nest--; if (nest == 0) return i; } return -1; } } }
using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string filename = args[0]; var sb = new StringBuilder(); foreach (var line in Lines(filename)) sb.Append(line); new Tettettee(sb.ToString()).Run(); Console.ReadLine(); } private static IEnumerable<string> Lines(string path) { using (System.IO.StreamReader sr = new System.IO.StreamReader(path, Encoding.GetEncoding("Shift-Jis"))) { string line; while ((line = sr.ReadLine()) != null) yield return line; } } } }
てってってーのコード
{「てってってーてってっててー」と出力するプログラム} ーてってってー {「てってっ」をメモリに書き込む} てっててーてっててーてっててーてっててー {ポインタを4つ戻す} てってっーてってっーてってっーてってっー {標準出力へ4文字出力する} ーててーてっててーてってっー {「て」をメモリに書き込み、ポインタを戻してから標準出力へ出力する} ーーてってっててー {「ーてってって」をメモリに書き込む} てっててーてっててーてっててーてっててーてっててーてっててー {ポインタを6つ戻す} てってっーてってっーてってっーてってっーてってっーてってっー {標準出力へ6文字出力する} ーててーてっててーてってっー {「て」をメモリに書き込み、ポインタを戻してから標準出力へ出力する} ーーてーてっててーてってっー {「ー」をメモリに書き込み、ポインタを戻してから標準出力へ出力する}
本家より転載させていただきますた。
実行結果
てってってーてってっててー
てってってーてってっててー♪ m9(^Д^)プギャーーーッ
てってってーてってっててー♪ m9(^Д^)プギャーーーッ
てってってーてってっててー♪ m9(^Д^)プギャーーーッ
ネタに便乗するというのも、なかなか楽なもんじゃありません。
お疲れさまでした。