かんたんな自作言語のコンパイラをいろんな言語で書いてみるシリーズ 17番目の言語は Pascal です。
Pascal 初めて書きました。処理系は Free Pascal です。いつもの通りでライフゲームのコンパイルが通ったのでヨシ、という程度の雑なものです。
移植元
ライフゲームのプログラムだけコンパイルできればOKという簡単なコンパイラです。Ruby 版だとコンパイラ部分だけで 1000行くらい。
ベースになっているバージョンは ステップ 58 のあたり。
(2021-11-29 追記) ステップ 62 の変更まで反映しました。
作り方はここに全部書いています(Ruby 版のものですが): vm2gol v2 製作メモ
動かし方の例
# ビルド ... bin/ 以下に実行ファイルが生成される
$ rake build-all
$ echo '
func add(a, b) {
return a + b;
}
func main() {
call add(1, 2);
}
' | bin/lexer | bin/parser | bin/codegen
# ↓アセンブリが出力される
call main
exit
label add
push bp
cp sp bp
cp [bp:2] reg_a
push reg_a
cp [bp:3] reg_a
push reg_a
pop reg_b
pop reg_a
add_ab
cp bp sp
pop bp
ret
label main
push bp
cp sp bp
cp 2 reg_a
push reg_a
cp 1 reg_a
push reg_a
_cmt call~~add
call add
add_sp 2
cp bp sp
pop bp
ret
# ... snip ...
メモ
主な部分のサイズ(行数)はこんな感じ。
$ wc -l *.pas lib/{types,utils}.pas
482 codegen.pas
154 lexer.pas
520 parser.pas
222 lib/types.pas
195 lib/utils.pas
1573 合計
※ VB はほとんど書いたことがなく、一方 LibreOffice Basic の方は多少書いたことあるので、以下では LibreOffice Basic を挙げていますが、たぶん VB でも大体似た感じだと思います。
ちなみに少し前に LibreOffice Basic で書いたもの:
- 自分が知っているものの中では C と LibreOffice Basic の中間みたいな印象
- Pascal + 動的型 → (VB) → LibreOffice Basic という流れ?
- string 型があって文字列の扱いは C より楽
- Emacs に pascal-mode をインストール……しなくてもすでに入っていた(インストールした記憶がないので最初から入ってた?)
- デフォルト設定だとインデントがスペース3つ
- 今回は fpc をインストールした Docker イメージを使うようにしてみた
- 処理系に配慮された整理された文法になっていて、たとえば C コンパイラを作るより Pascal コンパイラを作る方がハードルが低そう(コンパイラというか主に構文解析部分?)
- 教育的、というか元々教育目的として生まれた言語だそう
- 言語処理系自作に興味がある人は触れておいて損はなさそう
- 書籍『コンパイラ 作りながら学ぶ』の PL/0' も Pascal 系の言語
Pascal は今まで触れる機会がなくて全然知らない文化圏という意識でいたのですが、実際触ってみると完全に異文化ということもなくて、自分が書いたことのある言語でいえば LibreOffice Basic が近いです(とりあえず見た目は)。
たとえば整数を2つ受け取って足した結果を返す関数は次のようになります。
// Pascal
function add(a : integer; b : integer) : integer;
begin
add := a + b;
end;
' LibreOffice Basic
function add(a, b)
add = a + b
end function
-
return 返り値
ではなく関数名 = 返り値
と書く - 返り値の有無で
sub
(Pascal ではprocedure
) とfunction
を使い分ける - 関数・プロシージャ呼び出し時に引数がない場合は括弧を省略可
といったあたりが Pascal 由来と思われます。構造体の扱いも似ているような?
書いているときの感触としては「LibreOffice Basic の変数に型が付いて、文法はなんとなく似ていて、低水準の操作ができる」みたいな感じでした。
LibreOffice Basic 以外でも、JavaScript の with
も Pascal 由来かな? とか、Go の :=
も Pascal 由来かな? とか、 Scala や Rust、Zig など、コロンで区切って型を後置するのも Pascal 由来かな? といった感じで、他の言語への影響と思われる(※確認はしていなくて、あくまで「思われる」という程度)要素がいろいろあって面白かったです。
(204-04-29 追記)3. JavaScript 1.0 と JavaScript 1.1 - JavaScript: 最初の 20 年 (翻訳) - inzkyk.xyz によれば、JavaScript の with は AWK 由来だそうです。
Kuin の言語仕様の解説にも Pascal への言及がちらほら出てきますね。たとえば「Kuin言語仕様3 演算子」など。
参考
-
Pascal入門 (全18回) - プログラミングならドットインストール
- とりあえず最初にこれを見るのがおすすめ
- 変数の代入演算子と等価演算子について - Qiita
- (2019) 世界のプログラミング言語(22) 今も改良が続くPascal/Delphi言語の栄枯盛衰 | TECH+
- (2015) Pascalは過小評価されている | スラド デベロッパー
他の言語への移植
記事 | リポジトリ | 日付 |
---|---|---|
Haskell | github | 2021-06-28 |
OCaml | github | 2021-06-26 |
Julia | github | 2021-05-03 |
Rust | github | 2021-04-07 |
Crystal | github | 2021-03-27 |
Kotlin | github | 2021-01-14 |
Zig | github | 2021-01-07 |
LibreOffice Basic | github | 2020-12-14 |
Go | github | 2020-09-25 |
PHP | github | 2020-09-18 |
C♭ | github | 2020-09-13 |
Perl | github | 2020-09-08 |
C | github | 2020-09-06 |
Java | github | 2020-08-30 |
Dart | github | 2020-08-22 |
Python | github | 2020-08-19 |
TypeScript (Deno) | github | 2020-08-15 |