Skip to content

Instantly share code, notes, and snippets.

@dom96
Last active October 19, 2019 12:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dom96/11305055 to your computer and use it in GitHub Desktop.
Save dom96/11305055 to your computer and use it in GitHub Desktop.
import macros, strutils
type
TokenKind = enum
FInt, FString, Text
Token = object
case kind: TokenKind
of FInt, FString: nil
of Text: c: String
iterator tokenize(format: string): Token =
var i = 0
while True:
case format[i]
of '%':
case format[i+1]
of 'd': yield Token(kind: FInt)
of 's': yield Token(kind: FString)
of '\0': break
else: error("Incorrect format string.")
i.inc
of '\0': break
else:
yield Token(kind: Text, c: $format[i])
i.inc
macro printf(format: Static[String], params: Varargs[Expr]): Stmt =
echo(treeRepr(params))
var i = 0
var stringLit = ""
for tok in tokenize(format):
case tok.kind
of FInt:
if i >= params.len: error("Too many arguments in format string.")
if params[i].kind != nnkIntLit: error("Expected Int got " & $params[i].kind)
stringLit.add($params[i].intVal)
i.inc
of FString:
if i >= params.len: error("Too many arguments in format string.")
if params[i].kind != nnkStrLit: error("Expected String got " & $params[i].kind)
stringLit.add(params[i].strVal)
i.inc
of Text: stringLit.add tok.c
if i < params.len: error("Too many arguments to printf.")
result = quote do:
echo(`stringLit`)
printf("test %d %s", 10, 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment