Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
Signed-off-by: George Lemon <[email protected]>
  • Loading branch information
georgelemon committed Apr 2, 2024
1 parent c4d2cb5 commit 6a613b3
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 69 deletions.
4 changes: 2 additions & 2 deletions src/voodoo.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
# (c) 2024 George Lemon | MIT License
# Made by Humans from OpenPeeps
# https://github.com/openpeeps/voodoo
import voodoo/getter
export getter
import voodoo/setget
export setget
67 changes: 0 additions & 67 deletions src/voodoo/getter.nim

This file was deleted.

106 changes: 106 additions & 0 deletions src/voodoo/setget.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Working with Nim's macros is just Voodoo
#
# (c) 2024 George Lemon | MIT License
# Made by Humans from OpenPeeps
# https://github.com/openpeeps/voodoo

import std/[macros, tables, strutils, sequtils]

var
genSetters {.compileTime.} = OrderedTable[string, NimNode]()
genGetters {.compileTime.} = OrderedTable[string, NimNode]()
excludeFields {.compiletime.}: seq[string]

proc genProcIdent(x: NimNode): NimNode {.compileTime.} =
let fieldName = $(x)
var procName = "get"
var i: int
add procName, fieldName[i].toUpperAscii
inc i
while i < fieldName.len:
case fieldName[i]
of '_':
while fieldName[i] == '_':
inc i
add procName, fieldName[i].toUpperAscii
inc i
else:
add procName, fieldName[i]
inc i
result = ident(procName)

#
# Setter
#
macro setter*(obj: untyped) =
## Generate setter procs from object fields
discard # todo

macro setter*(excludes: untyped, obj: untyped) =
## Optionally, you can exclude fields from generation
expectKind excludes, nnkBracket
excludeFields = excludes.mapIt($it)
echo obj[0].treeRepr
add obj[0][1], ident("setters")
obj

macro expandSetters* =
## Required to inject generated setters in your code
result = newStmtList()
for k, x in genSetters:
add result, x
clear(genSetters)

#
# Getter
#
macro getters*(obj: untyped) =
## Generate getter procs from object fields
let objident = obj[0][0][1]
let objf = obj[2][0][2]
obj[0] = obj[0][0]
expectKind objf, nnkRecList
genGetters[objident.strVal] = newStmtList()
for f in objf:
var procName: NimNode
var returnType = f[^2]
var fieldName: string
for x in f[0..^3]:
case x.kind
of nnkIdent, nnkAccQuoted:
if excludeFields.contains($x):
continue
fieldName = $x
procName = genProcIdent(x)
else: discard
var body = newStmtList()
add body, newCommentStmtNode("Getter handle to return `" & $fieldName & "`")
add genGetters[objident.strVal],
newProc(
nnkPostfix.newTree(ident("*"), procName),
params = [
returnType,
nnkIdentDefs.newTree(
ident(objident.strVal[0].toLowerAscii & objident.strVal[1..^1]),
objident,
newEmptyNode()
),
],
body = body
)
obj

macro getters*(excludes: untyped, obj: untyped) =
## Optionally, you can exclude fields from generation
expectKind excludes, nnkBracket
excludeFields = excludes.mapIt($it)
echo obj[0].treeRepr
add obj[0][1], ident("getters")
obj

macro expandGetters* =
## Required to inject the generated getters in your code
result = newStmtList()
for k, x in genGetters:
add result, x
clear(genGetters)

0 comments on commit 6a613b3

Please sign in to comment.