しょぼいマシンで自作プログラミング言語を作ってみる (1)
しょぼいしょぼいっていうけど、どんだけ?
機種名: MacBook Pro
機種ID: MacBookPro11,1
プロセッサ名: デュアルコアIntel Core i5
プロセッサ速度: 2.6 GHz
プロセッサの個数: 1
コアの総数: 2
二次キャッシュ(コア単位): 256 KB
三次キャッシュ: 3 MB
ハイパー・スレッディング・テクノロジ: 有効
メモリ: 8 GB
随分としょぼいマシンである。ちょっとこれで自作プログラミング言語を作ってみましょうか。
LLVMは入れました。バージョンはこちら
$ clang++ -v
Homebrew clang version 19.1.2
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /usr/local/Cellar/llvm/19.1.2/bin
随分としょぼいマシンである。ちょっとこれで自作プログラミング言語を作ってみましょうか。
事前準備
$ brew install llvm
LLVMは入れました。バージョンはこちら。
$ clang++ -v
Homebrew clang version 19.1.2
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /usr/local/Cellar/llvm/19.1.2/bin
そもそも、なんでプログラミング言語作ろうとした?
なんとなくです。Go言語をいじってみて、ちょっととっつきにくい部分もあるなと。
特にオプショナル引数の扱いが面倒くさいなと……。
AFOPパターンを使わなければならないのはなんか面倒でした。
なので、ちょっとオプショナル引数も扱いやすいようなプログラミング言語を作ってみたいですねぇ。
というわけで始めてみましょうか。
っと、その前にプログラミング言語名は?
そうですね。プログラミング言語の名前は……。
Gallop
にしましょうか。
LLVMの動作の理解
始めるにしてもLLVMの動きがわからないことには始まらないので、そこからですね。
C++でHello world!
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
こいつはllvm_ir0_cpp.cppとして名付けました。
これをLLVM IRの形に吐き出しますか。
$ clang++ -S -emit-llvm -O3 llvm_ir0_cpp.cpp
llvm_ir0_cpp.llができたので、見てみましょう……。
………………。でかっ!
いや、これはこれは。ここに貼るにもはばかられますね。
$ llc llvm_ir0_cpp.ll
$ clang++ llvm_ir0_cpp.s -o llvm_ir0_cpp.o
$ ./llvm_ir0_cpp.o
Hello, World!
おお、動きました。
CでHello world!
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
こいつはllvm_ir0_c.cとして名付けました。
これもLLVM IRの形に吐き出しますか。
$ clang -S -emit-llvm -O3 llvm_ir0_c.c
llvm_ir0_c.llができたので、見てみましょう……。
………………。C++版に比べたら小さいですが、ここに貼るにもはばかられますね。
$ llc llvm_ir0_c.ll
$ clang llvm_ir0_c.s -o llvm_ir0_c.o
$ ./llvm_ir0_c.o
Hello, World!
おお、動きました。
CとC++の出力の違いは?
$ ls -la
total 320
drwxr-xr-x 10 sunmoonlav staff 320 10 18 15:10 .
drwxr-xr-x 3 sunmoonlav staff 96 10 18 14:47 ..
-rw-r--r-- 1 sunmoonlav staff 79 10 18 15:09 llvm_ir0_c.c
-rw-r--r-- 1 sunmoonlav staff 1150 10 18 15:10 llvm_ir0_c.ll
-rwxr-xr-x 1 sunmoonlav staff 49424 10 18 15:10 llvm_ir0_c.o
-rw-r--r-- 1 sunmoonlav staff 628 10 18 15:09 llvm_ir0_c.s
-rw-r--r-- 1 sunmoonlav staff 97 10 18 14:49 llvm_ir0_cpp.cpp
-rw-r--r-- 1 sunmoonlav staff 21962 10 18 14:51 llvm_ir0_cpp.ll
-rwxr-xr-x 1 sunmoonlav staff 51544 10 18 15:02 llvm_ir0_cpp.o
-rw-r--r-- 1 sunmoonlav staff 15356 10 18 14:59 llvm_ir0_cpp.s
これ、けっこう違いますね。ファイルサイズが。
特に拡張子がllのファイルのサイズや拡張子がsのファイルのサイズを見ると、CとC++で結構違いがあるように見えます。
C++の方が冗長なんですかね?
ひとまずはここで、この記事は区切りにしますか。