Advertisement
Guest User

Untitled

a guest
Mar 12th, 2018
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 1.59 KB | None | 0 0
  1. import macros
  2.  
  3. {.experimental.}
  4.    
  5. proc `-`(a: pointer, b: pointer): int =
  6.   cast[int](a) - cast[int](b)
  7.  
  8. proc `+`(a: pointer, b: int): pointer =
  9.   cast[pointer](cast[int](a) + cast[int](b))
  10.  
  11. macro structural(con, inter, fieldDefs): untyped =
  12.   let dummySym = genSym(nskVar, "dummy")
  13.   let vtableType = newNimNode(nnkTupleTy)
  14.   let vtableVal = newNimNode(nnkPar)
  15.   let conTests = newNimNode(nnkStmtList)
  16.  
  17.   for fieldDef in fieldDefs.children:
  18.     let fname = fieldDef[0]
  19.     let ftype = fieldDef[1][0]
  20.  
  21.     var a = newNimNode(nnkIdentDefs)
  22.     a.add(fname)
  23.     a.add(quote do: tuple[offs: int, tmark: `ftype`])
  24.     a.add(newEmptyNode())
  25.     vtableType.add(a)
  26.    
  27.     var b = newNimNode(nnkExprColonExpr)
  28.     b.add(fname)
  29.     b.add(quote do: (addr(`dummySym`.`fname`) - addr(`dummySym`[]), `dummySym`.`fname`))
  30.     vtableVal.add(b)
  31.    
  32.     conTests.add(quote do: T.`fname` is `ftype`)
  33.  
  34.   let node = quote do:
  35.     type
  36.       `con` = concept g, type T
  37.         `conTests`
  38.  
  39.       `inter` = object
  40.         base: pointer
  41.         vtable: ptr[`vtableType`]
  42.    
  43.     converter conToInt[T: not typedesc and `con`](x: var T): `inter` =
  44.       var vt {.global.} = (proc(): `vtableType` =
  45.         var `dummySym` = T()
  46.         return `vtableVal`
  47.       )()
  48.  
  49.       `inter`(
  50.         base: addr x[],
  51.         vtable: addr vt
  52.       )
  53.  
  54.   let node2 = quote("@") do:
  55.     template `.`(x: @inter, field: untyped): untyped =
  56.       cast[ptr[(@vtableType).field.tmark]](x.base + x.vtable.field.offs)[]
  57.  
  58.   let node3 = newStmtList()
  59.  
  60.   node3.add(node)
  61.   node3.add(node2)
  62.   node3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement