Created
July 4, 2014 06:10
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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