Skip to content

Instantly share code, notes, and snippets.

@Yardanico
Created September 2, 2017 15:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yardanico/0318e54afe7527ab1e74b101c24bd78e to your computer and use it in GitHub Desktop.
Save Yardanico/0318e54afe7527ab1e74b101c24bd78e to your computer and use it in GitHub Desktop.
import macros
type
SmallType = object
z: float
MyType = object
a: int
b: int
c: string
d: SmallType
macro toWith(obj: typed, body: untyped): untyped =
result = body
# Get type for this object
let typImpl = obj.getTypeInst().symbol.getImpl()
# Get this object' fields
var fields: seq[NimNode] = @[]
for field in typImpl[2][2]:
fields.add field[0]
proc modifyRecursive(ast, obj: NimNode, fields: seq[NimNode]): NimNode =
if ast.isNil(): return # Don't touch empty AST
result = ast.copyNimNode() # Copy AST (because we'll need to modify it)
# If this ast is an ident and it's in our fields seq
if ast.kind == nnkIdent and ast in fields:
# Change someIdent to obj.someIdent
result = quote do:
`obj`.`ast`
if ast.len > 0:
# If AST has children, modify them too!
for child in ast:
result.add(modifyRecursive(child, obj, fields))
result = modifyRecursive(result, obj, fields)
var myobj = MyType()
toWith(myobj):
a = 5
b = 35
c = "Hello world"
echo "Hmm, can I still write normal nim code here?"
echo "Look, I've changed myobj.c and I can use it here: ", c, " !"
toWith(myobj.d):
z = 531.0
echo myobj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment