Hello,
I'm currently doing some more advanced "macro magic", and have stumbled upon a weird error:
type
TokenKind* = enum
rtLParen, rtRParen # ()
rtLBracket, rtRBracket # []
rtLBrace, rtRBrace # {}
Token* = object
kind: TokenKind
template token(name: untyped, stmts: untyped): untyped {.dirty.} =
proc name(input: string): Token =
stmts
template literal(lit: string, kind: untyped): untyped {.dirty.} =
if input == lit: result = Token(kind: kind)
token lParen:
literal("(", rtLParen)
For some reason the compiler fails:
../src/rod/tokenizer.nim(24, 39) Error: undeclared field: 'rtLParen'
Even though rtLParen clearly is defined.
I want to achieve a template that expands like so:
literal("(", rtLParen)
# into:
if input == "(": result = Token(kind: rtLParen)
literal(")" rtRParen)
# into:
if input == ")": result = Token(kind: rtRParen)
# etc
What am I doing wrong?
The problem lies in this template:
template literal(lit: string, kind: untyped): untyped {.dirty.} =
if input == lit: result = Token(kind: kind)
For both occurences of kind the parameter kind is inserted, which obviously isn't right.
This should fix it.
template literal(lit: string, litKind: untyped): untyped {.dirty.} =
if input == lit: result = Token(kind: litKind)