Skip to content

Instantly share code, notes, and snippets.

@hsk
Created July 4, 2014 06:10
Show Gist options
  • Save hsk/25338a2f6521ff60d7cb to your computer and use it in GitHub Desktop.
Save hsk/25338a2f6521ff60d7cb to your computer and use it in GitHub Desktop.
var traits = {};
var insts = {};
function trait(name, methods) {
traits[name] = methods;
insts[name] = {};
}
function struct(typeName, params, traitNames, bodys) {
// 登録チェック用オブジェクト
var adds = {};
// トレイト名でループ
for (var i = 0; i < traitNames.length; i++) {
// トレイト名取得
var traitName = traitNames[i];
// メンバオブジェクト作成
var members = {};
if (!(traitName in traits)) {
throw ("not found trait " + traitName);
}
// トレイト
var trait = traits[traitName];
// メンバ登録
for (var traitMemberName in trait) {
if (!(traitMemberName in bodys)) {
throw ("not found trait member in " + typeName + " trait:" + traitName + " member:" + traitMemberName);
}
members[traitMemberName] = bodys[traitMemberName];
// 登録チェック用
adds[traitMemberName] = 1;
}
// インスタンス登録
insts[traitName][typeName] = members;
}
// コンストラクタ
var constructor = function() {
var i = 0;
for (var x in params) {
this[x] = arguments[i];
i++;
}
};
// 型名保存
constructor.prototype.typeName = typeName;
for (var name in bodys) {
if (!(name in adds)) {
// 通常メンバ
constructor.prototype[name] = bodys[name];
}
}
return constructor;
}
trait("Eq1", {
eq1: ["fun", ["self", "self"], "bool"]
});
trait("Eq2", {
eq2: ["fun", ["self", "self"], "bool"],
inc: ["fun", ["self"], "int"]
});
var N = struct("N", {
"x": "int"
}, ["Eq1", "Eq2"], {
"eq1": function(s, a) {
return s.x == a.x;
},
"eq2": function(s, a) {
return s.x == a.x;
},
"inc": function(s) {
s.x++;
return s.x;
},
"getX": function() {
return this.x;
}
});
var i = new N(20);
var j = new N(20);
console.log(i.x);
console.log(insts.Eq1[i.typeName].eq1(i, j));
console.log(insts.Eq2[i.typeName].eq2(i, j));
insts.Eq2[i.typeName].inc(i);
console.log(i.x);
console.log(insts.Eq2[i.typeName].eq2(i, j));
insts.Eq2[j.typeName].inc(j);
console.log(insts.Eq2[i.typeName].eq2(i, j));
console.log(i.getX());
var N2 = struct("N2", {
"x": "int"
}, ["Eq1"], {
"eq1": function(s, a) {
return s.x == a.x;
},
"getX": function() {
return this.x;
}
});
console.log("koko");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment