右も左も分からん

オタクの雑記,自宅の食器

プログラミング言語「4zy0」

この記事は、

www.adventar.org

17日目の記事です.

 

はじめに

こんにちは,こっそり歩くちゃんこと歩くです.作曲が趣味の17歳JKです.

本来ギターやDTM関連について書く(書いてない)ブログですが,OIT Advent CalendarということでITに関することを書きました.

 

みなさんは好きなプログラミング言語はありますか?

C,JavaC++HaskellPHPjavascriptpythonと色んな言語を好きな人がいますよね.

それらは偉大な技術者たちの設計により最適化され,現代のありとあらゆる場所で使われていますね.

そこでぼくは思いました.

 

ぼくもなんかすごい言語が作りたい!!!!!!!!!!!

 

しかしどうやってプログラミング言語なんて作るんや……

そんなときに見つけた本がこれでした.

 

f:id:walk_to_work:20161217181826j:plain

タイトルからいいですよね,スタンドとか出そう(下の方のシミは醤油).

 

ということで作りました,プログラミング言語「4zy0」.

 

作った 

まずはサンプルコードです.

 

helloworld.lo


ふえぇ…こんにちわだよぉ…
ふえぇ…ふえぇ…
ふえぇ…おしっこもらしちゃったよぉ…
ふえぇ…ふえぇ…
ふえぇ…おにいちゃん…

「えーと…ふえぇ…このぷろぐらむゎさんぷるこーどだよぉ…
ふえぇ…このげんごゎ…ふえぇ…おんなのこのことばで…ふえぇ…
こーでぃんぐしないといけないんだよぉ…ふえぇ…
ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇぇ…はわわ…」

えーと…ふえぇ…ふえぇ…!

ぇ…ふえぇ…ふえぇ…ふえぇ…
「えーと…ふえぇ…むずかしいことゎわからないけど…
ふえぇ…このげんごゎ…ふえぇ…ちゅーりんぐまちーんのげんりで…ふえぇ…
うごいてるんだよぉ…ふえぇ…
ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇぇ…はわわ…」

えーと…すきなものはぷいきゅあです!

ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…!!
ふえぇ…ふえぇ…ふえぇ…!

ぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…
「えーと…このこーどは…はわわ…はろーわーるどって…
はわわ…かくぷろぐらむなんだよぉ…ぇ…はわわ…」

えーと…5しゃいです!

ぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…ふえぇ…
「えーと…ぷいきゅあがすきです…ふえぇ…
ふえぇ…ふえぇ…おふとんあったかいよぉ…ぇ…はわわ…」

えーと…!ふえぇ…ふえぇ…ふえぇ…!
はわわ…はわわ…はわわ…はわわ…はわわ…はわわ…!
はわわ…はわわ…はわわ…はわわ…はわわ…はわわ…はわわ…はわわ…!


 

このコードを実行すると

f:id:walk_to_work:20161217175854p:plain

出ました!!!!!HelloWorld!!!!すごい!!!!!

 

「4zy0」の特徴

この言語の特徴ですが,仕様の都合によりコード量が他の言語に比べ圧倒的に多く読みにくいことが挙げられるでしょう……

しかしょぅι゛ょ言葉でプログラミングするにあたり,他のCやpythonなどの追従を許しません.

以上です.

「4zy0」の仕様

このプログラミング言語ですが,Brainf*ckという言語,そしてその派生系であるmisa(公式サイト閉鎖?)をパクり参考につくりました.

Brainf*ckの仕様についてはググってください.

4zy0の場合,Brainf*ckの『+,-,>,<,.,,,[,]』が『ふ,は,え,ぇ,!,?,「,」』に対応しており,それをインタープリタである4zy0.rbが解析し,出力しているわけですね.

以上です.

最後に

4zy0.rbのコードを公開しておきます.

PATH通したり拡張子の関連付けとかすれば*.loに対応できると思います.

それではみなさま,善き4zy0ライフを!

>|ruby|
"# -*- encoding: utf-8 -*-"
require "kconv"

class Youzyo
class ProgramError < StandardError
end

def initialize(src)
@tokens = src.chars.to_a
@jumps = analyze_jumps(@tokens)
end

def run
tape = []
pc = 0
cur = 0

while pc < @tokens.size
case @tokens[pc]
when "ふ"
tape[cur] = tape[cur] || 0
tape[cur] += 1
when "は"
tape[cur] = tape[cur] || 0
tape[cur] -= 1
when "え"
cur += 1
when "ぇ"
cur -= 1
raise ProgramError , "開始地点より左には移動できません" if cur < 0
when "!"
tape[cur] = tape[cur] || 0
print tape[cur].chr
#print n.chr
when "?"
tape[cur] = $stdin.getc.ord
when "「"
if tape[cur] == 0
pc = @jumps[pc]
end
when "」"
if tape[cur] != 0
pc = @jumps[pc]
end
end
pc += 1
#puts tape[cur]
#puts pc
#print( cur , @tokens[pc])
#puts ""
end
end

private
def analyze_jumps(tokens)
jumps = {}
starts = []

tokens.each_with_index do |c , i|
if c == "「"
starts.push(i)
elsif c == "」"
raise ProgramError , "「」」が多すぎます" if starts.empty?
from = starts.pop
to = i
jumps[from] = to
jumps[to] = from
end
end
raise ProgramError , "「「」が多すぎます" unless starts.empty?
jumps
end
end
Youzyo.new(ARGF.read).run ||<