implemented 'bind' for macros
This commit is contained in:
parent
bdf3bee055
commit
c7ba6f5eb6
7 changed files with 83 additions and 15 deletions
|
|
@ -91,7 +91,7 @@ type
|
|||
const
|
||||
nnkLiterals* = {nnkCharLit..nnkNilLit}
|
||||
nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
|
||||
nnkCallStrLit}
|
||||
nnkCallStrLit}
|
||||
|
||||
# Nodes should be reference counted to make the `copy` operation very fast!
|
||||
# However, this is difficult to achieve: modify(n[0][1]) should propagate to
|
||||
|
|
@ -185,6 +185,10 @@ proc newIdentNode*(i: string): PNimrodNode {.compileTime.} =
|
|||
## creates an identifier node from `i`
|
||||
result = newNimNode(nnkIdent)
|
||||
result.ident = !i
|
||||
|
||||
proc bindSym*(ident: string): PNimrodNode {.magic: "NGetBoundSym".}
|
||||
## creates a node that binds `ident` to a symbol node. The bound symbol
|
||||
## needs to be predeclared in a ``bind`` statement!
|
||||
|
||||
proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
## converts the AST `n` to the concrete Nimrod code and wraps that
|
||||
|
|
@ -249,6 +253,14 @@ proc expectLen*(n: PNimrodNode, len: int) {.compileTime.} =
|
|||
## compilation aborts with an error message. This is useful for writing
|
||||
## macros that check its number of arguments.
|
||||
if n.len != len: error("macro expects a node with " & $len & " children")
|
||||
|
||||
proc newCall*(theProc: PNimrodNode,
|
||||
args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
|
||||
## produces a new call node. `theProc` is the proc that is called with
|
||||
## the arguments ``args[0..]``.
|
||||
result = newNimNode(nnkCall)
|
||||
result.add(theProc)
|
||||
result.add(args)
|
||||
|
||||
proc newCall*(theProc: TNimrodIdent,
|
||||
args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
|
||||
|
|
|
|||
|
|
@ -319,23 +319,22 @@ proc isatty*(f: TFile): bool =
|
|||
|
||||
result = isatty(fileHandle(f)) != 0'i32
|
||||
|
||||
# XXX:
|
||||
# These should be private, but there is no yet
|
||||
# facility for binding local symbols within macros
|
||||
proc styledEchoProcessArg*(s: string) = write stdout, s
|
||||
proc styledEchoProcessArg*(style: TStyle) = setStyle({style})
|
||||
proc styledEchoProcessArg*(style: set[TStyle]) = setStyle style
|
||||
proc styledEchoProcessArg*(color: TForegroundColor) = setForeGroundColor color
|
||||
proc styledEchoProcessArg*(color: TBackgroundColor) = setBackGroundColor color
|
||||
proc styledEchoProcessArg(s: string) = write stdout, s
|
||||
proc styledEchoProcessArg(style: TStyle) = setStyle({style})
|
||||
proc styledEchoProcessArg(style: set[TStyle]) = setStyle style
|
||||
proc styledEchoProcessArg(color: TForegroundColor) = setForeGroundColor color
|
||||
proc styledEchoProcessArg(color: TBackgroundColor) = setBackGroundColor color
|
||||
|
||||
macro styledEcho*(m: stmt): stmt =
|
||||
bind styledEchoProcessArg, write, resetAttributes, stdout
|
||||
|
||||
result = newNimNode(nnkStmtList)
|
||||
|
||||
for i in countup(1, m.len - 1):
|
||||
result.add(newCall(!"styledEchoProcessArg", m[i]))
|
||||
result.add(newCall(bindSym"styledEchoProcessArg", m[i]))
|
||||
|
||||
result.add(newCall(!"write", newIdentNode("stdout"), newStrLitNode("\n")))
|
||||
result.add(newCall(!"resetAttributes"))
|
||||
result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n")))
|
||||
result.add(newCall(bindSym"resetAttributes"))
|
||||
|
||||
when isMainModule:
|
||||
system.addQuitProc(resetAttributes)
|
||||
|
|
@ -347,3 +346,5 @@ when isMainModule:
|
|||
setForeGroundColor(fgBlue)
|
||||
writeln(stdout, "ordinary text")
|
||||
|
||||
styledEcho("styled text ", {styleBright, styleBlink, styleUnderscore})
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue