Skip to content

Instantly share code, notes, and snippets.

@mratsim
Last active April 28, 2018 16:24
Show Gist options
  • Save mratsim/df6d09745d18c391e73ada98525aaf1e to your computer and use it in GitHub Desktop.
Save mratsim/df6d09745d18c391e73ada98525aaf1e to your computer and use it in GitHub Desktop.
import macros
type Conv2DLayer[T] = object
data: T
type Context[T] = ref object
data: T
####################################
# This works fine, directly generating
# The type section from the input data
####################################
macro genModel(modelType, subtype: untyped): untyped =
var records = nnkRecList.newTree
let field_type = nnkBracketExpr.newTree(
ident("Conv2DLayer"), subtype
)
records.add nnkIdentDefs.newTree(
newIdentNode("field_name"),
field_type,
newEmptyNode()
)
result = nnkStmtList.newTree(
nnkTypeSection.newTree(
nnkTypeDef.newTree(
newIdentNode($modelType),
newEmptyNode(),
nnkObjectTy.newTree(
newEmptyNode(),
newEmptyNode(),
records
)
)
)
)
expandMacros:
genModel(FooType, seq[int])
## Output:
# type
# FooType = object
# field_name: Conv2DLayer[seq[int]]
####################################
# This part doesn't work
# I want to extract the type needed
# from another type
####################################
macro ctxSubtype(context: Context): untyped =
## Extract the subtype from a Context
echo context.getTypeInst.treerepr
result = context.getTypeInst[1]
macro ctxSubtype(context: Context): untyped =
## Extract the subtype from a Context
echo context.getTypeInst.treerepr
result = context.getTypeInst[1]
macro genModelFromCtx(modelType: untyped, context: Context): untyped =
var records = nnkRecList.newTree
let subtype = getAST(ctxSubtype(context))
let field_type = nnkBracketExpr.newTree(
ident("Conv2DLayer"), subtype
)
records.add nnkIdentDefs.newTree(
newIdentNode("field_name"),
field_type,
newEmptyNode()
)
result = nnkStmtList.newTree(
nnkTypeSection.newTree(
nnkTypeDef.newTree(
newIdentNode($modelType),
newEmptyNode(),
nnkObjectTy.newTree(
newEmptyNode(),
newEmptyNode(),
records
)
)
)
)
var ctx: Context[seq[int]]
expandMacros:
genModelFromCtx(FooType2, ctx)
## Output:
# Error: cannot instantiate Conv2DLayer
# got: <seq[int]>
# but expected: <T>
import macros
type Conv2DLayer[T] = object
data: T
type Context[T] = ref object
data: T
proc replaceNodes*(ast: NimNode): NimNode =
# Args:
# - The full syntax tree
proc inspect(node: NimNode): NimNode =
case node.kind:
of {nnkIdent, nnkSym}:
return ident($node)
of nnkEmpty:
return node
of nnkLiterals:
return node
else:
var rTree = node.kind.newTree()
for child in node:
rTree.add inspect(child)
return rTree
result = inspect(ast)
####################################
# This works fine, directly generating
# The type section from the input data
####################################
macro genModel(modelType, subtype: untyped): untyped =
var records = nnkRecList.newTree
let field_type = nnkBracketExpr.newTree(
ident("Conv2DLayer"), subtype
)
records.add nnkIdentDefs.newTree(
newIdentNode("field_name"),
field_type,
newEmptyNode()
)
result = nnkStmtList.newTree(
nnkTypeSection.newTree(
nnkTypeDef.newTree(
newIdentNode($modelType),
newEmptyNode(),
nnkObjectTy.newTree(
newEmptyNode(),
newEmptyNode(),
records
)
)
)
)
expandMacros:
genModel(FooType, seq[int])
## Output:
# type
# FooType = object
# field_name: Conv2DLayer[seq[int]]
####################################
# This part doesn't work
# I want to extract the type needed
# from another type
####################################
macro ctxSubtype(context: Context): untyped =
## Extract the subtype from a Context
echo context.getTypeInst.treerepr
result = replaceNodes(context.getTypeInst[1])
macro genModelFromCtx(modelType: untyped, context: Context): untyped =
var records = nnkRecList.newTree
let subtype = getAST(ctxSubtype(context))
let field_type = nnkBracketExpr.newTree(
ident("Conv2DLayer"), subtype
)
records.add nnkIdentDefs.newTree(
newIdentNode("field_name"),
field_type,
newEmptyNode()
)
result = nnkStmtList.newTree(
nnkTypeSection.newTree(
nnkTypeDef.newTree(
newIdentNode($modelType),
newEmptyNode(),
nnkObjectTy.newTree(
newEmptyNode(),
newEmptyNode(),
records
)
)
)
)
var ctx: Context[seq[int]]
expandMacros:
genModelFromCtx(FooType2, ctx)
## Output:
# type
# FooType2 = object
# field_name: Conv2DLayer[seq[int]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment