入力した式を C に変換後、コンパイルして実行するスクリプト


そういえば Lightweight Language Day and Night 2005 で、どんなテーマにしたらよいかを皆さんが考えてくださったときに、

Masashi Umezawa wrote:
> 今回プログラミングを担当されるのは鷲見さんですが、「応用編」に関しては
> いろいろな人のアイデアを集めておいた方が有利かと思います。
> 
> 例: 
> - 解を出すまでの過程が視覚的に見える(パースツリー、3Dポリゴン)
> - 意味もなく解を読み上げる
> - ロボットが動き出し、達筆で答えを書く
> 
> などなど、「応用編」にふさわしい「見せ方」といったものがありましたら、
> このMLにどしどしお寄せください。
> 
> それではよろしくお願い申し上げます。

ビジュアルではないですが、客層的には

1) 入力を受け取る
2) 解を返す Slang 文を生成する
3) VMMaker で C に変換
4) gccコンパイル
5) プラグインとして Squeak から呼び出して答えを表示

と言うのは如何でしょうか。

http://www.smalltalk.jp/pipermail/squeak-ja/2005-July/002532.html

なんてな id:propella さんのアイデアがあったなぁ…とふと思い出したので、遅まきなががらようやく Squeak VM 外部プラグインの作り方も分かったことだしと、さっそく簡単なところで試してみました。

| expression vmMaker newPluginFile pjDir vmDir |

expression := FillInTheBlank request: 'expression:' initialAnswer: '3 + 4'.

AdhocPlugin compile: '
primitiveCalc
   | ret |
   self primitive: ''primitiveCalc''.
   ret := ', expression,'.
   ^ ret asOop: SmallInteger' classified: 'primitives'.

vmMaker := VMMaker default.
vmMaker initializeInternal: #() external: #(AdhocPlugin).
vmMaker deleteEntireGeneratedTree.
vmMaker generateExternalPlugins.

pjDir := 'Mac OS X:Users:yourhome:AdhocPlugin:'.

Applescript doIt: '
   tell application "Xcode"
      activate
      open alias "', pjDir, 'AdhocPlugin.xcode"
      clean
      build
      quit
   end tell'.

newPluginFile := FileStream oldFileNamed:
   pjDir, 'build:AdhocPlugin.bundle:Contents:MacOS:AdhocPlugin'.
vmDir := FileDirectory on: SmalltalkImage current vmPath, 'AdhocPlugin.bundle:Contents:MacOS'.
vmDir deleteFileNamed: 'AdhocPlugin'.
vmDir putFile: newPluginFile named: 'AdhocPlugin'.

Smalltalk unloadModule: #AdhocPlugin.

^ AdhocPluginChecker calc

まず、最初の a FillInTheBlank で入力した式を含む Slang コード(AdhocPlugin >> #primitiveCalc)が a VMMaker により C 言語に(AdhocPlugin.c)。それを Xcodeコンパイル後、SqueakVM 外部プラグインとしてビルド(AdhocPlugin.bundle)。さらに VM がこれを(機能的に)取り込むことで、スクリプトの最後にある AdhocPluginChecker class >> #calc を介したプリミティブ(原始メソッド。簡単にはネイティブコードで書かれたメソッド)としての評価が可能になる、というカラクリです。途中、Xcode の起動やプラグインのビルド作業には AppleScript を使っています。


なお、このスクリプトを機能させるためには、前のエントリーでとりあげた VM 外部プラグインの生成環境を整えるほかに、次のようなタネをあらかじめ仕込んでおく必要があります。

  • AdhocPlugin を SmartSyntaxInterpreterPlugin のサブクラスとして定義
  • AdhocPluginChecker と AdhocPluginChecker class >> #calc を定義
AdhocPluginChecker class >> calc
   <primitive: 'primitiveCalc' module: 'AdhocPlugin'>
   self primitiveFailed
  • Xcode の AdhocPlugin プロジェクトをホームディレクトリに作っておく
    • ビルド可能なように必要なファイルの追加や設定を済ませておく
  • 一度ビルドに成功した AdhocPlugin.bundle を VM と同じディレクトリに置く
  • TestOSAPlugin.bundle を入手し VM と同じディレクトリに置く
  • ApplescriptAppleScript スクリプトを実行するためのモジュール)のインストール
  • AEDesc >> #createFromText: に、次の修正
    • (aString class = String) ifFalse: ... → (aString isKindOf: String) ifFalse: ...