-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Captures not working inside of proc with generic arguments #68
Comments
Well, I'm flabbergasted about this one - I'll spend some time trying to understand what is happening, but I would not be surprised if this is a Nim bug. |
That was my suspicion as well but I thought I should start here. |
I have it minimized to this: import macros
macro foo*(n: untyped): untyped =
echo "foo 1 ", n.astGenRepr
macro foo*(n, n2: untyped): untyped =
echo "foo 2 ", n.astGenRepr, " ", n2.astGenRepr
proc test[T](v: T, str: string) =
foo >"test"
test("", "Test") Take away the second @disruptek: you are a smart man, any clue? |
Indeed, there is a Nim bug, which seems to have been there since always. Funny that his never popped up before for anyone while using NPeg. Workaround for now would be to define your own
Let's see if the bug gets a fix anytime soon. |
Thanks for digging into this. I'm encountering another problem now. The proposed work around does make the original example work though! This works:
However, adding an additional rule causes an error:
The template doesn't interfere at all with the non-generic case though:
|
Hm your second example compiles fine for me on latest devel; What Nim version are you on? |
I encounter the error with 2.0.0 as well as devel on a mac amd64. Here's the stack trace: |
Well that;'s not making any sense, I must be doing something wrong here. I just have this one file # Error: Expected PEG rule name but got nnkSy
import npeg
proc test2(T: typedesc, str: string) =
template `>`(a: untyped): untyped = discard
let p = peg "start":
test <- >"test"
start <- test
var m = p.match(str)
test2(int, "test") And then
Same with my 2.0:
|
My file was called But now there is another problem. It seems to be due to using a recursive rule. And it happens regardless of the
|
Yeah, things like that happened to me more than once. Check if you have a stray
I guess this is the same Nim bug as the
Our Nim bug is now one of the other many bugs and slowly moving down in the list, so not sure if this will get fixed anytime soon. I had the nasty plan of adding your snippet to the NPeg test suite - since NPeg is part of Nims "important packages", its tests are ran as part of Nim's CI; deliberately breaking Nim CI might speed things up, but I will not be making any friends with that I guess. |
Thanks for the tip!
This was indeed the case! And now my parser is working! I had to define a template like that for every operator that is being used. This felt like a nice way to keep it a bit out of the way and have clarity about why it's there.
Haha! I'll let you be the judge of that. I'm content with the workaround and can move forward. Maybe just a note in the docs somewhere for now? I really don't have a good sense for how high of a priority that bug should be. Thanks for your efforts in helping me find a solution! And also for the work you've done making this fantastic tool. |
Well, the least I can do: 049b4ca import npeg
proc parse*(T: typedesc, str:string) =
nimBug22740()
let p = peg "parser":
elem <- > internal
internal <- '(' * ?elem * ')'
parser <- internal
let r = p.match(str)
parse(int, "(())") |
I may have spoken too soon. It was working when I wasn't trying to import the parser into another module. When I do that I am encountering more errors. # a.nim
import npeg
proc parse*(T: typedesc, str:string) =
let p = peg "parser":
parser <- "test"
let r = p.match(str)
Returns # a.nim
import npeg
proc parse*(T: typedesc, str:string) =
template `>`(a: untyped): untyped = discard
let p = peg "parser":
parser <- >"test"
let r = p.match(str)
Returns |
I'll spend some time this evening to see if I can understand what is happening here. Also, I now remember - vividly - why I left Nim behind and moved on to other languages... |
Unmatched `immediate` `macro`s and `template`s within a generic context no longer result in a compiler error. ## Details Immediate macros and templates are not dispatched via `sigmatch` and instead `semgnrc` directly calls `evaltempl.evalTemplate`, in turn `evalTemplateArgs` is called which can produce an error if an incorrect number of arguments are provided. `evalTemplateArgs` is also used by `semMacroExpr`, so similar issues would also exist for macros. Now the error from `evalTemplateArgs` is immediately returned by `evalTemplate` and treated as a mismatch in `semgnrc.semGenericStmt`. Doing so prevents a compiler crash, attempt to access the sons of an error node. A test has been added as part of this change, which was originally from: zevv/npeg#68 (comment)
I'm sorry @kerrycobb, but it seems I can't get this to work, nor can I find a feasible workaround. It seems that we have again hit some limit of Nim's macro system. I hope NPeg is still usable to you it its current form. I'll leave this issue open, maybe someone else will come by and find a way to get this done. |
@zevv, thank you for trying! That is unfortunate. Maybe I can create a macro or template that generates a parser for each of the types that I wish to be able to use with the parser as a workaround for now. I'm not going to have time to try that out for a few weeks though. I'll post here if I am successful. Have you gained any incite that could be shared over in nim-lang/Nim#22740 or perhaps as a new issue if more appropriate? I'll likely still find uses for Npeg aside from my current project but this throws a pretty big wrench into the plans I had. It's not for anything real important though. Just an exploration into the utility of Nim for some application. I remain optimistic for it eventually. |
Well, this is rather ridiculous. Change # a.nim
import npeg
discard patt "test"
proc parse*(T: typedesc, str:string) =
let p = peg "parser":
parser <- "test"
let r = p.match(str) |
I've managed to get everything working! Here is a minimal example that should be expandable to most use cases: # a.nim
import npeg
proc parse*(T: typedesc, str:string) =
template `*`(a: untyped): untyped = discard
template `-`(a: untyped): untyped = discard
template `+`(a: untyped): untyped = discard
template `$`(a:untyped): untyped = discard # Only useful if all code is in a single module
let p = peg "parser":
parser <- >"test":
echo capture[1].s # Syntactic sugar `$` does not work
let r = p.match(str)
proc workAround() =
parse(string, "") # Any valid type used here will make this work with all other valid types. # b.nim
import ./a
parse(int, "test") The operators defined with the templates above are the ones that I've found need to have declarations. I previously mentioned The |
Glad to hear you got it all to work, that was quite a journey! If it's ok with you I'll close the issue for now, but I'll add a link to it from the documentation in case anyone else runs into the same problem. |
Sounds good to me. Thanks again for your efforts! |
## Summary Unmatched `immediate` `macro`s and `template`s within a generic context no longer result in a compiler error. ## Details Immediate macros and templates are not dispatched via `sigmatch` and instead `semgnrc` directly calls `evaltempl.evalTemplate`, in turn `evalTemplateArgs` is called which can produce an error if an incorrect number of arguments are provided. `evalTemplateArgs` is also used by `semMacroExpr`, so similar issues would also exist for macros. Now the error from `evalTemplateArgs` is immediately returned by `evalTemplate` and treated as a mismatch in `semgnrc.semGenericStmt`. Doing so prevents a compiler crash, attempt to access the sons of an error node. A test has been added as part of this change, which was originally from: zevv/npeg#68 (comment)
The
>
symbol used in an expression inside of a proc causes the following error:Error: wrong number of arguments
. It seems like it is being recognized as the system operator rather than part of the expression.Two examples of it not working:
If the '>' is removed, things work. But of course I cannot use the matched element. This is the only symbol that is causing me problems and the parser I've been trying to write is using almost all of them.
The text was updated successfully, but these errors were encountered: