I am building a lexer where I have a case statement with many repeated cases where just the character changes and the resulting token.
Example:
case l.ch
of '+':
tok = Token( Type: tkPlus, Literal: $l.ch )
of '-':
tok = Token( Type: tkMinus, Literal: $l.ch )
...
I would like to have a macro like
( '-', tkMinus )
doing the work for me. How would I write such a macro? Tried with echo statements but it doesn't work. Also is there a compiler switch to quickly see the expanded macros?
Sorry for the beginner questions.
There exists a few macro tutorials...
But as I am not really good with macros I would try something like
let h =
case l.ch
of '+': tkPlus
of '-': tkMinus
...
tok = Token(h, Literal: $l.ch )
You may not even need a case statement, I think ascii characters are valid for array index, so you may use an array with tk*** content?
You're right, there might be better solutions here than a macro - this was just a quick porting of a Go code to Nim, and I was thinking of C preprocessor macros, so ...
But about the macros, I am pretty intrigued by but so far I don't understand them.. found some tutorials but so far no 1:1 macro -> expanded code samples out of which I'd learn best..
Thanks.
What I am specially looking for is how to (un)escape strings in macros. How to write like result = echo "of '$ch':" if we had a special $ for including characters in the string. Sorry, English's not my primary language..
But have to say in general that I begin to love nim. Have ported some code which I did previously to JavaScript and it's equally easy but more fun.
I get error: type expected when assigning buildAst to result ... ?
macro simpleToken( ch: char, typ: TokType ): untyped =
result = buildAst(ofBranch(newLit('l')):
asgn(ident"tok", objConstr(ident"Token", exprColonExpr(ident"Type", TokType))))
echo result.repr
I thought of writing the case by hand and having the macros just generating of branches, like:
case ch
of '!':
# handle special case
simpleToken( '-', tkMinus )
simpleToken( '+', tkPlus )
...
Agreed that here a table is more elegant and that's what I'm using now but still curious about how the macro solution would be to learn.. :)