summary refs log tree commit diff stats
path: root/tests/accept/run/toop1.nim
blob: a925642e816e572d181fedd440aed788f34557bc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
discard """
  file: "toop1.nim"
  output: "34[]o 5"
"""
# Test the stuff in the tutorial
import macros

type
  TFigure = object of TObject    # abstract base class:
    draw: proc (my: var TFigure) # concrete classes implement this proc
  
proc init(f: var TFigure) = 
  f.draw = nil

type
  TCircle = object of TFigure
    radius: int
  
proc drawCircle(my: var TCircle) = stdout.writeln("o " & $my.radius)

proc init(my: var TCircle) = 
  init(TFigure(my)) # call base constructor
  my.radius = 5
  my.draw = drawCircle

type
  TRectangle = object of TFigure
    width, height: int

proc drawRectangle(my: var TRectangle) = stdout.write("[]")

proc init(my: var TRectangle) = 
  init(TFigure(my)) # call base constructor
  my.width = 5
  my.height = 10
  my.draw = drawRectangle

macro `!` (n: expr): stmt = 
  result = newNimNode(nnkCall, n)
  var dot = newNimNode(nnkDotExpr, n)
  dot.add(n[1])    # obj
  if n[2].kind == nnkCall:
    # transforms ``obj!method(arg1, arg2, ...)`` to
    # ``(obj.method)(obj, arg1, arg2, ...)``
    dot.add(n[2][0]) # method
    result.add(dot)
    result.add(n[1]) # obj
    for i in 1..n[2].len-1:
      result.add(n[2][i])
  else:
    # transforms ``obj!method`` to
    # ``(obj.method)(obj)``
    dot.add(n[2]) # method
    result.add(dot)
    result.add(n[1]) # obj

type
  TSocket* = object of TObject
    FHost: int # cannot be accessed from the outside of the module
               # the `F` prefix is a convention to avoid clashes since
               # the accessors are named `host`
               
proc `host=`*(s: var TSocket, value: int) {.inline.} = 
  ## setter of hostAddr
  s.FHost = value

proc host*(s: TSocket): int {.inline.} =
  ## getter of hostAddr
  return s.FHost
  
var 
  s: TSocket
s.host = 34  # same as `host=`(s, 34)
stdout.write(s.host)

# now use these classes:
var
  r: TRectangle
  c: TCircle
init(r)
init(c)
r!draw
c!draw() 

#OUT 34[]o 5