Add tests for examples from Nim in Action.

This commit is contained in:
Dominik Picheta 2017-10-01 17:17:40 +01:00
commit 7889c03cbc
34 changed files with 1213 additions and 0 deletions

View file

@ -0,0 +1,84 @@
import macros
proc createRefType(ident: NimIdent, identDefs: seq[NimNode]): NimNode =
result = newTree(nnkTypeSection,
newTree(nnkTypeDef,
newIdentNode(ident),
newEmptyNode(),
newTree(nnkRefTy,
newTree(nnkObjectTy,
newEmptyNode(),
newEmptyNode(),
newTree(nnkRecList,
identDefs
)
)
)
)
)
proc toIdentDefs(stmtList: NimNode): seq[NimNode] =
expectKind(stmtList, nnkStmtList)
result = @[]
for child in stmtList:
expectKind(child, nnkCall)
result.add(newIdentDefs(child[0], child[1][0]))
template constructor(ident: untyped): untyped =
proc `new ident`(): `ident` =
new result
proc createLoadProc(typeName: NimIdent, identDefs: seq[NimNode]): NimNode =
var cfgIdent = newIdentNode("cfg")
var filenameIdent = newIdentNode("filename")
var objIdent = newIdentNode("obj")
var body = newStmtList()
body.add quote do:
var `objIdent` = parseFile(`filenameIdent`)
for identDef in identDefs:
let fieldNameIdent = identDef[0]
let fieldName = $fieldNameIdent.ident
case $identDef[1].ident
of "string":
body.add quote do:
`cfgIdent`.`fieldNameIdent` = `objIdent`[`fieldName`].getStr
of "int":
body.add quote do:
`cfgIdent`.`fieldNameIdent` = `objIdent`[`fieldName`].getNum().int
else:
doAssert(false, "Not Implemented")
return newProc(newIdentNode("load"),
[newEmptyNode(),
newIdentDefs(cfgIdent, newIdentNode(typeName)),
newIdentDefs(filenameIdent, newIdentNode("string"))],
body)
macro config*(typeName: untyped, fields: untyped): untyped =
result = newStmtList()
let identDefs = toIdentDefs(fields)
result.add createRefType(typeName.ident, identDefs)
result.add getAst(constructor(typeName.ident))
result.add createLoadProc(typeName.ident, identDefs)
echo treeRepr(typeName)
echo treeRepr(fields)
echo treeRepr(result)
echo toStrLit(result)
# TODO: Verify that we can export fields in config type so that it can be
# used in another module.
import json
config MyAppConfig:
address: string
port: int
var myConf = newMyAppConfig()
myConf.load("myappconfig.cfg")
echo("Address: ", myConf.address)
echo("Port: ", myConf.port)