バックパッチしようぜ

みんなバックパッチ(backpatch)って知ってる?
ほらコンパイラとかでジャンプとかを作るときに使うやつだよ。gotoでもいいけどさ。

	a;
	b;
	goto LABEL; // <- ここを生成しているときは、LABELのアドレスが分からない
	c;
	d;
LABEL:  // <- ここでLABELのアドレスが決定する
	e;

これを関数型言語でやろうと思ったら、結構大変だったんだ。どれくらい大変だったかというと、ゴールデンウィーク中ずっとこのことを考えてるぐらい大変だった。
1パスでやりたいとか、たいれたことは考えてなくて、拡張がしやすくて見た目がシンプルな実装がしたかっただけなんだけど、結構むつかしい。
結局、http://www.itpl.co.jp/ocaml-nagoya/index.php?%A5%CD%A5%BF%B5%AD%CF%BF%B8%CB%2FHaskellを参考にしてそれらしいものができたので、貼っておきますね。

type t = Int of int | Label of string | Ref of string

(* val conv : int -> t list -> ((string * int) list -> int list) * (string * int) list = <fun> *)
let rec conv i =
  function
      [] ->
	(fun _ -> []),[]
    | (Int x)::xs ->
	let ys, map =
	  conv (i+1) xs in
	  (fun m -> x::ys m), map
    | (Ref x)::xs ->
	let ys, map =
	  conv (i+1) xs in
	  (fun m -> ((List.assoc x m) - i)::ys m),map
    | (Label x)::xs ->
	let ys,map =
	  conv (i+1) xs in
	  ys,(x,i)::map

(*  val backpatch : t list -> int list = <fun> *)
let backpatch xs =
  let xs,map =
    conv 0 xs in
    xs map
# backpatch [Int 1;Ref "foo"; Int 2; Int 3;Label "foo";Int 4];;
- : int list = [1; 3; 2; 3; 4]

モジュール名をcapitalizeに

モジュール名をOCaml風にcapitalizeにしてみた。

(define-class Main (Flash.Display.Sprite) ())
(define-method init ([self Main])
  (let [(t (new Flash.Text.TextField))]
    (. t (appendText "Hello,world!!"))
    (. self (addChild t))))

これがいいのか、迷っている。masterにマージせずに捨ててしまおうか。

HappyABC 0.5.0リリース

http://happyabc.org
久しぶりにリリースします。今回は、リリースを自動化するための仕組み作りに力をいれたため、リリースそのものが遅くなってしまいました。

今回の目玉は、external/external-class宣言の廃止です。なにも指定せずに、flash.display.Spriteなどが使えるようになりました。

;; 宣言せずにflash.display.Spriteが使える
(define-class Main (flash.display.Sprite) ())
(define-method init ([self Main])
  (let [(t (new flash.text.TextField))]
    (. t (appendText "Hello,world!!"))
    (. self (addChild t))))

新機能

  • モジュールの自動import
  • -c で中間形式を出力可能
  • -Iで自動importするディレクトリを指定可能
  • --width/--heightでswfのファイルを指定可能

さて次は?

  • いいかげんマニュアルを
  • バグを一掃したい