背景
最近は少なくなったIT系雑誌が無料で読めます。IT雑誌を紙で買ってきた世代としては素晴らしいサービスだと思っています。
授業などで勧めてきたのですが、恐らく、実際に読んだり、読むことを習慣にした方はたぶんいなかったのだと思います。
という自分もネット上にある普段は目に触れない記事をわざわざ見に行くことはほぼないので。。。いいものだとは知っていてもスルーしていました。
たまたまスクリプト言語を自作する記事を見つけて、それが日経ソフトウェアの記事と知り、大学で契約しているので簡単に入手することができた体験がありました。
もっと面白い記事があるかもな。。。と思い、最近のエントリーで何回か自己参照していますが、以下のエントリーに至りました。
で、記事を読みたいな。。。と思いつつも日々の仕事に追われて時間が作れません。
そこで思い出したのは前職の先輩の言葉「学びたいなら教えなさい」でした。そうだよな、自分に読むことを課すためには誰かと学ぶ機会を作ればいいんだよな、と。
せっかく学生が身近にいますので、関心がありそうな学生さんに声かけしたところ参加してくれるとのこと。
で、始めました。
最初に選んだ記事は以下でした。これは上の記事でも参照しています。僕と皆さんの都合で木5限にしました。
特集1 スクリプト言語をゼロから作ろう Part1 言語処理系の作成は難しくない! | 日経ソフトウエア | 日経BP記事検索サービス
第1回(2023/5/11)
とりあえず、ゼミ室に10人くらいの学生さんが集まり、読み始めました。ただ読んでいくとこれでいいのかな。。。という雰囲気になり、説明を聞くよりまず手を動かしたらいいのかな?と感じて、とりあえずみんなでひたすら記事のコードを入力し始めました。1時間はあっという間で結局、1つのファイルも入力を終えることができませんでした。。。これは失敗かもという感じでした。
とりあえず私は入力を終えたかったので翌日くらいに夜に時間を見つけて入力を終えました。以下に置いています。
第2回(2023/5/18)
そして昨日。場所をゼミ室から図書館に変えて開催しました。7,8人くらいが集まってくれました。ほぼ教室でしたので、プロジェクタに私の画面を投影して、そこで僕が一人しゃべりながら進めました。上記の記事の出だしを紹介したあと、パーザはあとにしてまず仮想マシンを動かしてみることにしました。この記事で提示されているmini_mvm.cというやつです。このコードも既に僕の方で入力済みでしたので、それをダウンロードしてもらい、それをRepl.itで動作してもらいました。
で、人が入力したコードを眺めていてもたぶん理解できないだろうと思ったのと、僕もやってみたいと思ったので、このコードを学生さんらも経験のあるPythonに置き換えてみました。トランスパイラではないですが言語変換をしてみると言語の機能をよく理解する必要があり、今回、参加者の多くが大学1年生なのでたぶん完全には理解できないだろうけど「流れ」を知る機会になるだろうな、ということでやってみました。あまり声はあがらなかったですが、僕としてはその場で変換できて面白い体験だったのでヨシとしています。次回はparserをやります。単に記事を読むだけを1とするなら、その記事を見て実際に動かす体験は5くらいになります。さらにそのコードを自分なりに変更してみると10や30になるでしょう。単位は不明ですが。。。あくまで感覚的なものです。さらにここから新しい言語を作ってみたら100とか1000になるでしょう。こういう体験は恐らく若くて経験の浅い学生さんには想像がつかないでしょうし飽き飽きすることかもしれませんが、そこに面白さがあることをぜひ実感してもらったらいいなと思っています。こういうことをやりたかったんだな。。。と自分でも実際に進めながら自分を理解しているところです。
参考まで以下はPython版のmini_mvmです。
#define STACK_SIZE_MAX (65536)
#(10 + 2 * 4) / 2
#オペコードを列挙型で定義
OP_PUSH_INT = 0
OP_ADD = 1
OP_MUL = 2
OP_DIV = 3
OP_PRINT = 4
#バイトコードを格納する配列(オペコードの列挙型を整数に変換している)
g_bytecode = [
OP_PUSH_INT,
10,
OP_PUSH_INT,
2,
OP_PUSH_INT,
4,
OP_MUL,
OP_ADD,
OP_PUSH_INT,
2,
OP_DIV,
OP_PRINT,
]
st_stack = [None] * 10
def mvm_execute():
pc = 0 #プログラムカウンタ
sp = 0 #スタックポインタ
while (pc < len(g_bytecode)):
#バイトコードを読み取って処理を振り分ける
if g_bytecode[pc] == OP_PUSH_INT: #整数をスタックに積む
st_stack[sp] = g_bytecode[pc + 1]
sp += 1
pc += 2
elif g_bytecode[pc] == OP_ADD: #加算
st_stack[sp - 2] = st_stack[sp - 2] + st_stack[sp - 1] #スタック上での加算
sp -= 1
pc += 1
elif g_bytecode[pc] == OP_MUL: #乗算
st_stack[sp - 2] = st_stack[sp - 2] * st_stack[sp - 1] #スタック上での乗算
sp -= 1
pc += 1
elif g_bytecode[pc] == OP_DIV: #除算
st_stack[sp - 2] = st_stack[sp - 2] / st_stack[sp - 1] #スタック上での乗算
sp -= 1
pc += 1
elif g_bytecode[pc] == OP_PRINT: #表示
print(st_stack[sp - 1])
sp -= 1
pc += 1
else:
exit(0)
mvm_execute()
ちなみに著作権が気になる人もいるかと思いますが、前述のとおり、大学でこの電子書籍?サービスを利用していますので、所属員である学生はそれぞれで読む権利?があります。なので、この記事を一緒に勉強するときにそれぞれでダウンロードして読んでいますので問題はない、というのが私の認識です。何か問題があれば教えて下さい。