この記事も、plaintextでコーディングされています。詳しくはリンク先の記事を参照してください。
きっかけ
FizzBuzz問題を1文字で実行できるgs2というプログラミング言語があるらしいので、0バイトでFizzBuzzもHello, World!も実行できるプログラミング言語を作ってやろうということになった。
実行してみる
main.ll
これを実行すると、
実行結果
Hello, world!
そして、
main.ll
これを実行すると、
実行結果
1
2
Fizz
4
Buzz
Fizz
7
8
(中略)
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz
となる。
...は?
ネタバレ
これはインタープリタ側でコードを実行しているだけ。
インタープリタのオプションでどちらを実行するか指定して、ファイルが空なら指定した方を実行するだけである。実装はPythonで行われており、以下の通りである。
lazylang.py
import sys
import argparse
def fizzbuzz():
for i in range(1, 101):
if i % 3 == 0 and i % 5 == 0:
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
def hello_world():
print("Hello, World!")
def interpret_file(file_path, mode):
try:
with open(file_path, "r", encoding="utf-8") as file:
code = file.read().strip()
if code == "":
# ファイルが空の場合は選択されたモードに応じたデフォルト動作を実行
if mode == "fizzbuzz":
fizzbuzz()
elif mode == "hello":
hello_world()
else:
# ファイルに内容があれば、そのコードをPythonコードとして実行
try:
exec(code)
except Exception as e:
print(f"エラー: {e}")
except FileNotFoundError:
print(f"エラー: ファイル '{file_path}' が見つかりません。")
except IOError as e:
print(f"エラー: ファイル '{file_path}' の読み取り中にエラーが発生しました: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="FizzBuzzまたはHello, World!の実行を選択できるインタープリタ"
)
parser.add_argument("file", help="実行するファイルのパス")
parser.add_argument(
"--mode",
choices=["fizzbuzz", "hello"],
default="fizzbuzz",
help="デフォルト動作を選択します(デフォルトはFizzBuzz)",
)
args = parser.parse_args()
interpret_file(args.file, args.mode)
これをpyinstallerで実行可能ファイルにし、それに--mode fizzbuzzを指定すればfizzbuzzが、--mode helloを指定すればソースコード自体は0バイトでfizzbuzzもHello, world!も実行できる。