Skip to content
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

Nim fails to parsecommand invocation syntax in block as part of expression list #22051

Open
tersec opened this issue Jun 8, 2023 · 2 comments
Labels

Comments

@tersec
Copy link
Contributor

tersec commented Jun 8, 2023

Description

# stmt -> complexOrSimpleStmt -> simpleStmt -> discardStmt
# where "discardStmt = 'discard' optInd expr?", and optInd
# is "optInd = COMMENT? IND?" so matches nothing here.
#
# Then all the non-simpleExpr cases of expr require some non-'(' initial
# token so expr -> simpleExpr, which scans through the precedence order,
# and eventually reaches primary -> identOrLiteral -> tupleConstr:
#
# tupleConstr = '(' optInd (exprColonEqExpr comma?)* optPar ')'
#
# Still no optInd, so exprColonEqExpr = expr (':'|'=' expr)?
#
# expr matches "ifExpr = 'if' condExpr" and "literal = | INT_LIT",
# which is '0'.
#
# https://nim-lang.org/docs/manual.html#procedures-command-invocation-syntax
# "Routines can be invoked without the () if the call is syntactically a
# statement. This command invocation syntax also works for expressions, but
# then only a single argument may follow. This restriction means
# `echo f 1, f 2` is parsed as `echo(f(1), f(2))` and not as
# `echo(f(1, f(2)))`.
#
# is satisfied here. `f()` takes one argument and is used with one argument.

proc f(x: int): int = 0

discard (
  if true:
    f 0
  else:
    f 0,
  1)
f(try:
    0
  finally:
    int 0,
  0)

shows a similar issue and basically analogous parsing/grammar.

f(try:
    0
  except CatchableError:
    int 0,
  0)

does as well.

Nim Version

Current devel

Nim Compiler Version 1.9.3 [Linux: amd64]
Compiled at 2023-06-08
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: ea91cfb3050bac5c808ed8ab08e12cd33f1dc8ff
active boot switches: -d:release
Nim Compiler Version 1.6.12 [Linux: amd64]
Compiled at 2023-06-06
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: 1aa9273640c0c51486cf3a7b67282fe58f360e91
active boot switches: -d:release

Current Output

ifelse.nim(32, 3) Error: invalid indentation

Similar errors for other variations (try/finally, try/except, et cetera)

Expected Output

Successful compilation

Possible Solution

No response

Additional Information

No response

@metagn
Copy link
Collaborator

metagn commented Jun 8, 2023

Some effort related to this was in #20994 (these diffs: terminate command parsing on unindent, test for successful parsing of a similar case). Maybe on p.tok.indent >= 0 and p.tok.indent < baseIndent, it should return and not break. There might be a deeper problem though.

@metagn metagn added the Parser label Aug 28, 2023
@metagn
Copy link
Collaborator

metagn commented Aug 28, 2023

As noted in #21655, condExpr does not actually parse expr, it parses stmt, so it attempts to parse f 0, 1 which consumes the comma but quits after the comma due to the unindent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants