toop1.nim 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. discard """
  2. output: "34[]o 5"
  3. """
  4. # Test the stuff in the tutorial
  5. import macros
  6. type
  7. TFigure = object of RootObj # abstract base class:
  8. draw: proc (my: var TFigure) {.nimcall.} # concrete classes implement this
  9. proc init(f: var TFigure) =
  10. f.draw = nil
  11. type
  12. TCircle = object of TFigure
  13. radius: int
  14. proc drawCircle(my: var TCircle) = stdout.writeLine("o " & $my.radius)
  15. proc init(my: var TCircle) =
  16. init(TFigure(my)) # call base constructor
  17. my.radius = 5
  18. my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawCircle)
  19. type
  20. TRectangle = object of TFigure
  21. width, height: int
  22. proc drawRectangle(my: var TRectangle) = stdout.write("[]")
  23. proc init(my: var TRectangle) =
  24. init(TFigure(my)) # call base constructor
  25. my.width = 5
  26. my.height = 10
  27. my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle)
  28. macro `!` (n: varargs[untyped]): typed =
  29. let n = callsite()
  30. result = newNimNode(nnkCall, n)
  31. var dot = newNimNode(nnkDotExpr, n)
  32. dot.add(n[1]) # obj
  33. if n[2].kind == nnkCall:
  34. # transforms ``obj!method(arg1, arg2, ...)`` to
  35. # ``(obj.method)(obj, arg1, arg2, ...)``
  36. dot.add(n[2][0]) # method
  37. result.add(dot)
  38. result.add(n[1]) # obj
  39. for i in 1..n[2].len-1:
  40. result.add(n[2][i])
  41. else:
  42. # transforms ``obj!method`` to
  43. # ``(obj.method)(obj)``
  44. dot.add(n[2]) # method
  45. result.add(dot)
  46. result.add(n[1]) # obj
  47. type
  48. TSocket* = object of RootObj
  49. FHost: int # cannot be accessed from the outside of the module
  50. # the `F` prefix is a convention to avoid clashes since
  51. # the accessors are named `host`
  52. proc `host=`*(s: var TSocket, value: int) {.inline.} =
  53. ## setter of hostAddr
  54. s.FHost = value
  55. proc host*(s: TSocket): int {.inline.} =
  56. ## getter of hostAddr
  57. return s.FHost
  58. var
  59. s: TSocket
  60. s.host = 34 # same as `host=`(s, 34)
  61. stdout.write(s.host)
  62. # now use these classes:
  63. var
  64. r: TRectangle
  65. c: TCircle
  66. init(r)
  67. init(c)
  68. r!draw
  69. c!draw()
  70. #OUT 34[]o 5