C言語でJavaScript風prototypeを作ってみた。

JavaScriptのプロトタイプってこんな感じかなぁと思って、C言語JavaScript風プロトタイブを再現してみた。

配列だけど。

#include <stdio.h>
#include <stdlib.h>

struct p2d {
    double  x;
    double  y;
    double (**prototype)(struct p2d *);
};
typedef struct p2d Point2D;

typedef double (*Point2D_method)(Point2D *); // メソッド型

enum {GET_X, GET_Y, END};                    // 名前テーブル

Point2D_method *point2d_prototype;           // メソッドの配列としてプロトタイプの内容を宣言

// コンストラクタ
Point2D *point2d_new(double x, double y)
{
    Point2D *p = (Point2D *) malloc(sizeof (Point2D));
    p->x = x;
    p->y = y;
    p->prototype = point2d_prototype;
    return p;
}
void point2d_delete(Point2D *p) { free(p); }

// メソッドたち
double point2d_get_x(Point2D *p) { return p->x; }
double point2d_get_y(Point2D *p) { return p->y; }

// プロトタイプの登録
void point2d_init_prototype(void)
{
    point2d_prototype = (Point2D_method *) malloc((sizeof (Point2D_method)) * END);
    point2d_prototype[GET_X] = point2d_get_x;
    point2d_prototype[GET_Y] = point2d_get_y;
}
// プロトタイプの削除
void point2d_delete_prototype(void) { free(point2d_prototype); }

// テスト
void test(void)
{
    Point2D *p1 = point2d_new(1.0, 2.0);
    Point2D *p2 = point2d_new(3.0, 4.0);

    printf("p1 = (%f, %f)\n", p1->prototype[GET_X](p1), p1->prototype[GET_Y](p1));
    printf("p2 = (%f, %f)\n", p2->prototype[GET_X](p2), p2->prototype[GET_Y](p2));

    point2d_delete(p1);
    point2d_delete(p2);
}

int main(void)
{
    point2d_init_prototype();

    test();

    point2d_delete_prototype();
    exit(EXIT_SUCCESS);
}

うっは、ポインタだらけ。

プロトタイプのの型は、double (*)(Point2D *)固定です。

では、実行〜。

% ./prototype
p1 = (1.000000, 2.000000)
p2 = (3.000000, 4.000000)

配列だけどプロトタイプを再現出来ました。

構造体や配列をハッシュにすれば、JavaScript完成!?

まとめ

  • コンストラクタがプロトタイプに出来ない理由がわかった。
  • typedefを展開すると泣ける。これ以上は組みたくない気分(笑
  • ハッシュ=リストなので、JavaScriptエンジンのコアな部分はSchemeとほぼ同じだと思う。
  • あくまで想像。