| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- package unit;
- enum Constant<T> {
- CString(s:String):Constant<String>;
- CInt(s:String):Constant<Int>;
- CFloat(s:String):Constant<Float>;
- }
- enum Binop<S,T> {
- OpAdd:Binop<Float,Float>;
- OpEq:Binop<S,Bool>;
- }
- enum Expr<T> {
- EConst(c:Constant<T>):Expr<T>;
- EBinop<C>(op:Binop<C,T>, e1:Expr<C>, e2:Expr<C>):Expr<T>;
- }
- class TestGADT extends Test {
- function testBasic() {
- var ti = 1.22;
- var tb = false;
- var e1 = EConst(CFloat("12"));
- var e2 = EConst(CFloat("8"));
- var e3 = EConst(CFloat("12"));
- var eadd = EBinop(OpAdd,e1,e2);
- var s = eval(eadd);
- TestType.typedAs(s, ti);
- eq(s,20);
- var eeq = EBinop(OpEq,e1,e2);
- var s = eval(eeq);
- TestType.typedAs(s, tb);
- eq(s,false);
- var eeq = EBinop(OpEq,e1,e3);
- var s = eval(eeq);
- TestType.typedAs(s, tb);
- eq(s,true);
- }
- static function evalConst<T>(c:Constant<T>):T {
- return switch (c) {
- case CString(s): s;
- case CInt(i): Std.parseInt(i);
- case CFloat(f): Std.parseFloat(f);
- }
- }
- static function evalBinop<T,C>(op:Binop<C,T>, e1:Expr<C>, e2:Expr<C>):T {
- return switch(op) {
- case OpAdd: eval(e1) + eval(e2);
- case OpEq: eval(e1) == eval(e2);
- }
- }
- static function eval<T>(e:Expr<T>):T {
- return switch(e) {
- case EConst(c): evalConst(c);
- case EBinop(_op,_e1,_e2): evalBinop(_op,_e1,_e2); // TODO: this generates some unused variable warnings in macro context (issue #1675?)
- }
- }
- }
|