File: tvarargsuntyped.nim

package info (click to toggle)
nim 0.19.4-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 462,356 kB
  • sloc: sh: 11,089; ansic: 4,699; makefile: 706; python: 309; sql: 297; asm: 141; xml: 13
file content (109 lines) | stat: -rw-r--r-- 2,648 bytes parent folder | download
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
discard """
  output: '''Let's go!
(left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8)
(left: 2, r: 7, x: 8, height: 4, s: text, width: 3, y: 9, top: 1, g: 7, b: 8)
(left: 2, r: 7, x: 8, height: 4, s: text, width: 3, y: 9, top: 4, g: 7, b: 8)
(left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8)
10
hello 18.0'''
"""

import macros

proc internalBar(top, left, width, height: cint, s: string, x, y: int, r,g,b: int) =
  echo "(left: ", left, ", r: ", r, ", x: ", x, ", height: ", height, ", s: ", s,
    ", width: ", width, ", y: ", y, ", top: ", top, ", g: ", g, ", b: ", b, ")"

# we need these dummy constructors due to the wrong implementation
# of 'varargs[untyped]' in the compiler:

proc point(x, y: int): int = discard
proc color(r, g, b: int): int = discard
proc rect(a, b, c, d: int): int = discard

template declareUnpackingMacro(nimname,extname) =
  macro nimname(n: varargs[untyped]): untyped =
    var s: string = astToStr(extname) & "("
    var first = true
    echo repr n
    for x in n.children:
      var unpack = false
      if x.kind in nnkCallKinds:
        case $x[0]
        of "point":
          expectLen(x, 3)
          unpack = true
        of "rect":
          expectLen(x, 5)
          unpack = true
        of "color":
          expectLen(x, 4)
          unpack = true
        else: discard
      if unpack:
        for i in 1..<x.len:
          if first:
            first = false
          else:
            add(s, ", ")
          add(s, repr(x[i]))
      else:
        if first:
          first = false
        else:
          add(s, ", ")
        add(s, repr(x))

    add(s, ")")
    echo s
    result = parseStmt(s)

declareUnpackingMacro(bar,internalBar)

type MyInt = distinct int

proc myInt(i: int): MyInt = cast[MyInt](i)

converter toCInt(mi: MyInt): cint = cast[cint](mi)

echo "Let's go!"

bar(rect(1, 2, 3, 4), "test", point(8, 9), color(7,7,8))

bar(1,2,3,4,"text",8,9,7,7,8)

bar(myInt(4),2,3,4,"text",8,9,7,7,8)

let top: cint = 1
let left: cint = 2
let width: cint = 3
let height: cint = 4

bar(rect(top, left, width, height), "test", point(8, 9), color(7,7,8))


# bug #10075

import macros

proc convert_hidden_stdconv(args: NimNode): NimNode =
  var n = args
  while n.len == 1 and n[0].kind == nnkHiddenStdConv:
    n = n[0][1]
  return n

macro t2(s: int, v: varargs[untyped]): untyped =
  let v = convert_hidden_stdconv(v)
  echo v.treeRepr
  let (v1, v2) = (v[0], v[1])
  quote do:
    echo `v1`, " ", `v2`

template t1(s: int, v: varargs[typed]) =
  #static:
  #   dumpTree v
  echo s
  t2(s, v)

when isMainModule:
  t1(10, "hello", 18.0)