From aa68f7be50056f90bababcd5681776b61191db6b Mon Sep 17 00:00:00 2001 From: Andrea Ferretti Date: Sat, 4 Jul 2015 15:01:43 +0200 Subject: [PATCH] Added == tests and doc --- README.md | 14 +++++++++++++- patty.nim | 9 ++------- test.nim | 21 ++++++++++++++++++++- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9964c2c..de99529 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,18 @@ type of UnitCircleE: nil +proc `==`(a: Shape; b: Shape): bool = + if a.kind == b.kind: + case a.kind + of CircleE: + return a.r == b.r + of RectangleE: + return a.w == b.w and a.h == b.h + of UnitCircleE: + return true + else: + return false + proc Circle(r: float; x: float; y: float): Shape = Shape(kind: CircleE, r: r) @@ -108,7 +120,7 @@ proc UnitCircle(side: int): Shape = Shape(kind: UnitCircleE) ``` -Notice that the macro also generates three convenient constructors (`Circle` ,`Rectangle` and `UnitCircle`), and in fact the names in the enum are `CircleE`, `RectangleE` and `UnitCircleE` to avoid a name conflict. +Notice that the macro also generates three convenient constructors (`Circle` ,`Rectangle` and `UnitCircle`), and in fact the names in the enum are `CircleE`, `RectangleE` and `UnitCircleE` to avoid a name conflict. Also, a proper definition of equality based on the actual contents of the record is generated. A couple of limitations fo the `adt` macro: diff --git a/patty.nim b/patty.nim index 9bd572c..3fcfa41 100644 --- a/patty.nim +++ b/patty.nim @@ -145,9 +145,9 @@ proc defineEquality(tp, body: NimNode): NimNode {. compileTime .} = ) result = newProc( - name = ident("`==`"), + name = ident("=="), params = [ident("bool"), newIdentDefs(ident("a"), tp), newIdentDefs(ident("b"), tp)], - body = body + body = newStmtList(body) ) # result = getAst(compare(condition, tp)) @@ -159,11 +159,6 @@ macro adt*(e: expr, body: stmt): stmt {. immediate .} = when defined(pattydebug): echo toStrLit(result) -adt Shape: - Circle(r: float, x: float, y: float) - Rectangle(w: float, h: float) - Square(side: int) - macro match*(e: expr, body: stmt): stmt {. immediate .} = # A fresh symbol used to hold the evaluation of e let sym = genSym() diff --git a/test.nim b/test.nim index 98048e6..c983401 100644 --- a/test.nim +++ b/test.nim @@ -41,7 +41,7 @@ suite "adt construction": let c = UnitCircle() check c.kind == UnitCircleE - test "recusive types": + test "recursive types": adt IntList: Nil Cons(head: int, tail: ref IntList) @@ -54,6 +54,25 @@ suite "adt construction": check d.head == 3 check d.tail.head == 2 + test "generated equality": + adt Shape: + Circle(r: float, x: float, y: float) + Rectangle(w: float, h: float) + Square(side: int) + UnitCircle + + let + c1 = Circle(r = 3, x = 2, y = 5) + c2 = Circle(r = 3, x = 2, y = 5) + c3 = Circle(r = 2, x = 3, y = 5) + s = Square(3) + u1 = UnitCircle() + u2 = UnitCircle() + check c1 == c2 + check c1 != c3 + check c1 != s + check u1 == u2 + suite "pattern matching": type ShapeKind = enum