7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pascalでかんたんな自作言語のコンパイラを書いた

Last updated at Posted at 2021-05-22

かんたんな自作言語のコンパイラをいろんな言語で書いてみるシリーズ 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 コンパイラを作る方がハードルが低そう(コンパイラというか主に構文解析部分?)

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 演算子」など。

参考

他の言語への移植

記事 リポジトリ 日付
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
7
4
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
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?