Skip to content

Make defaults work on generic types #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions src/constructor/defaults.nim
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,30 @@ macro defaults*(genFlags: static set[DefaultFlag], tdef: untyped): untyped =
objDef = objectDef(tdef).copy() # This is just the object definiton (type Obj = object ...)
name = $objDef.name
innerIdent = genSym(nskType, ident = "Inner") # Inner type identificator
innerIdentTypedesc = newTree(nnkBracketExpr, ident("typedesc"), innerIdent) # typedesc[InnerType]
procIdentBase =
if tdef[2].kind == nnkRefTy:
"new"
else:
"init"
emptyNode = newEmptyNode()
innerIdentGeneric = newTree(nnkBracketExpr, innerIdent) # This is innerIdent with the generic parameters of objDef
procGenericParams = newTree(nnkGenericParams) # These are the generic params for the init/new procedures

# Here we collect all the names for the generic params [A, B: int = 1, C] -> [A, B, C]
for identdef in objDef.genericParams:
procGenericParams.add NimNode identdef
for name in identdef.names:
innerIdentGeneric.add NimNode name

let
# Inner//Inner[T]
innerIdent2 = # I know, horrible name
if procGenericParams.len > 0: innerIdentGeneric
else: innerIdent
innerIdentTypedesc = newTree(nnkBracketExpr, ident("typedesc"), innerIdent2) # typedesc[InnerType]

var
params = @[innerIdent] # First parameter is the return type
params = @[innerIdent2] # First parameter is the return type
constrParams = params # Object constructor parameters, first param is the constructor type
typeProcIdent = ident(procIdentBase)
procIdent = ident(procIdentBase & name)
Expand Down Expand Up @@ -72,7 +86,10 @@ macro defaults*(genFlags: static set[DefaultFlag], tdef: untyped): untyped =

let newTypeProc = newProc(typeProcIdent, params, objCStr)

# This procedure checks for instantiation errors
newProc[2] = procGenericParams
newTypeProc[2] = procGenericParams

# This procedure checks for instantiation errors when defTypeConstr or defBothConstr
let checkProc = newProc(genSym(nskProc, "checker"), body = newTree(nnkDiscardStmt, newCall(ident(procIdentBase), innerIdentTypedesc)))

var body = newStmtList(newTree(nnkTypeSection, NimNode objDef))
Expand Down