cadence icon indicating copy to clipboard operation
cadence copied to clipboard

Incorrect parsing (as function call) when something in braces is in line next to expression

Open uhbif19 opened this issue 4 years ago • 4 comments

Instructions

Please fill out the template below to the best of your ability and include a label indicating which tool/service you were working with when you encountered the problem.

Problem

This code

pre {
    (royaltyReceiver == nil) == (royaltyPercent == nil)
    (royaltyPercent == nil ) || (royaltyPercent! <= self.maxRoyaltyPercent)
}

raises error:

error: cannot call type: `Bool`
E             --> f8d6e0586b0a20c7.XXX:57:13
E              |
E           57 |             (royaltyReceiver == nil) == (royaltyPercent == nil)
E              |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

While other code with same meaning works without interpreter errors:

 pre {
    payment.balance == self.priceFor(tokenID: tokenID)
    self.isNFTStored(tokenID: tokenID)
}

Steps to Reproduce

Version of emulator used:

flow version  
Version: v0.25.0
Commit: 9afd7938ebf603611d7b159278a259c850e0adda

Acceptance Criteria

To me it looks like parsing ambiguity bug, I think code should be accepted.

uhbif19 avatar Aug 19 '21 10:08 uhbif19

Trying to minimise case. This triggers error:

pre {
    (royaltyReceiver == nil) == (royaltyPercent == nil)
    (royaltyPercent == nil )
}

But if I take out == it works:

pre {
    (royaltyReceiver == nil)
    (royaltyPercent == nil)
}

uhbif19 avatar Aug 19 '21 10:08 uhbif19

Also, this ones work.

pre {
    ((royaltyReceiver == nil) == (royaltyPercent == nil))
    (royaltyPercent == nil )
}

pre {
    (royaltyReceiver == nil) == (royaltyPercent == nil)
    royaltyPercent == nil 
}

pre {
    (royaltyReceiver == nil) == (royaltyPercent == nil)  royaltyPercent == nil 
}

and this doesn't work:

pre {
    (royaltyReceiver == nil) == (royaltyPercent == nil)  (royaltyPercent == nil)
}

so I guess the problem is not at pre :

this one made me think to try:

log    ("ok")

which works, but I think it shouldn't. Whitespace between function name and ( should fail I guess.

bluesign avatar Aug 19 '21 10:08 bluesign

@bluesign

Whitespace after function is allowed in most PL, I guess. For example, Python allows it: abs ( 2 + 3 ).

My guess is that the problem is in syntax ambiguity, which arises from usage of newline as statement separator in some cases, while allowing to split statement to multiple lines in another. Python handles this by requiring explicit usage \ in multiline cases not related to unclosed braces. Like this:

print \
   ( 1 + 2 )

This example works in Cadence:


log

("ok")

log

    ("ok")

uhbif19 avatar Aug 19 '21 11:08 uhbif19

Last example shouldn't, they are 2 statements

bluesign avatar Aug 19 '21 11:08 bluesign