3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonで自作言語

Last updated at Posted at 2023-02-22

自己紹介

初投稿なので自己紹介します。
SUPERFIRE777です。
こう書いて「スーパーファイヤートリプルセブン」と読みます。
twitterYouTubeでも活動していて、趣味でPythonを触ってます。
よろしくお願いします。

どんな言語?

スタックを使ってプログラムを組んでいきます。
プログラムを実行するプログラムはPythonで書いていて、中身は240行くらいあります。

環境

Windows11
Python 3.11.2

match-case構文を使っているので、Python 3.10以上でしか動かないと思います。

言語仕様

表内のA, B, ...はスタックからpopした値です。

スタック操作

命令 意味
数値 数値をPush
{ ... } ...を文字列としてPush
A dup Aを2個Pushする
clear スタックをクリアする

特殊命令

命令 意味
A # 何もしない
A exec Aをプログラムとして実行

#はコメントアウトなどの用途で使えます。
例えば、{ hogehogeを実行 } #などです。

標準入出力

命令 意味
input 文字列で入力を受け取ってPush
A print Aに何もつけず表示
A printsp Aに半角スペースをつけて表示
A println Aに改行をつけて表示
stack スタックの中身を表示

つまりinput printでオウム返しができます。

数値計算

命令 意味
A B + A+BをPush
A B - A-BをPush
A B * A*BをPush
A B / A÷BをPush
A B % AをBで割った余りをPush
A B ** $ A^B $をPush

例えば、
5 2 +7.0に、
5 2 -3.0
なります。

比較命令

命令 意味
A B > $A > B$なら1.0を、そうでなければ0.0をPush
A B < $A < B$なら1.0を、そうでなければ0.0をPush
A B >= $A \ge B$なら1.0を、そうでなければ0.0をPush
A B <= $A \le B$なら1.0を、そうでなければ0.0をPush
A B == $A = B$なら1.0を、そうでなければ0.0をPush
A B != $A \ne B$なら1.0を、そうでなければ0.0をPush

型変換

命令 意味
A tofloat Aをfloat型に変換
A toint Aをint型に変換
A tostr Aをstr型に変換

例えば、input tointで整数で入力を受け取ることができます。

変数

このプログラミング言語では、変数を使用することができます。

命令 意味
A B set AにBを代入
A get Aの値を取得してPush
A delete 変数Aを削除

定義されていない変数やdeleteで削除された変数の値はundefinedになります。

例えば、

a 5 set
a a get 1 + set

でPythonの

a = 5
a = a + 1

に相当することができます。

条件分岐

命令 意味
A B if $A \ne 0$ならBをプログラムとして実行
A B unless $A=0$ならBをプログラムとして実行

例えば、

{ 年齢: } printsp
age input tofloat set
age get 18 >= dup
	{ { 成人 } println } if
	{ { 未成年 } println } unless

で成人判定ができます。

このifunlessはネストできます。
例えば、

FizzBuzz
{ i get 15 % 0 == dup
	{ FizzBuzz println } if
	{ i get 3 % 0 == dup 
		{ Fizz println } if 
		{ i get 5 % 0 == dup
			{ Buzz println } if
			{ i get println } unless 
		} unless
	} unless
} set

でFizzBuzzのループの中身を変数FizzBuzzに代入することができます。

繰り返し

命令 意味
A B C D for 変数AをBからCまで1ずつ増やしながらDをプログラムとして実行
A B while 変数Aが$A \ne 0$を満たす間Bをプログラムとして実行

例えば、前定義したFizzBuzzを使って
i 1 100 { FizzBuzz get exec } for
と書くことによってFizzBuzzを実行できます。

以下は、whileを使ったプログラムの例です。

x 1 set

sum 0 set

x {
	{ 整数入力: } printsp
	x input toint set
	sum sum get x get + set 
} while

{ 合計は } print
sum get toint println

このプログラムは0が入力されるまで入力された整数を足し続け、0が入力されたら合計を表示するというプログラムです。

変数が0にならなければループが回り続けるので、

x 1 set
x { { Infinite Loop } println } while

で「Infinite Loop」を無限に出力させることができます。

文字列関連

命令 意味
space 半角スペースをPush
A B strcat AとBが両方文字列ならAとBを文字列結合したものを、そうでなければ"undefined"をPush
A B C replace AのBをCに置換したものをPush

例えば、

string
	{ Hello } space strcat
	{ World } strcat 
set
string get println
string
	string get space { - } replace
set
string get println

上記のプログラムの実行結果は、

Hello World
Hello-World

になります。

おわりに

ここまで見てくださってありがとうございます。
言語に要素を付け足していって、それがうまく動いた時の達成感は凄くありました。
ところで、Python 3.10の新機能であるmatch-caseを使うと、いちいち条件分岐でtoken == ...って書かなくていいので便利ですね。
こういう言語とかを作るときに再帰が有用であることも学べました。
他にもdefaultdictundefinedの仕様が簡単に作れることとか、変数のありがたみとか。
言語を作ることで色んなことが学べるので、皆さんも是非作ってみてください!

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?