ponyc icon indicating copy to clipboard operation
ponyc copied to clipboard

Confusion with " and """ in syntax and parsing.

Open redvers opened this issue 2 years ago • 3 comments

Not a huge deal, but this confused me a lot. Should this fail to compile instead of having this behaviour?

actor Main
  new create(env: Env) =>
    var somevar: String = "Content of somevar"
    env.out.print("""
                    Line 1:
                  """ + somevar + "
                    Line 3
                  """ + someFun())
                    
  fun someFun(): String =>
    "Result of someFun"

It may just very well be that I don't fully understand how """ are supposed to be used?

Results in the following output (from playground):

0.43.2-825937ca [release]
Compiled with: LLVM 12.0.1 -- Clang-10.0.0-x86_64
Defaults: pic=true

Result of someFun

redvers avatar Sep 01 '21 16:09 redvers

It is probably interpretting the """ """ not as a string literal but as a docstring.

This gives you what I think you were expecting:

actor Main
  new create(env: Env) =>
    var somevar: String = "Content of somevar"
    let x = """
    Line 1:
    """
    
    let y = """
    Line 3:
    """
    
    env.out.print(x + somevar + y + someFun())
                    
  fun someFun(): String =>
    "Result of someFun"

If someone can dump the AST for @redvers' example, we'd know for sure.

SeanTAllen avatar Sep 01 '21 16:09 SeanTAllen

Here's the AST output, taken using ponyc --pass=parse --ast:

  (package:scope
    (module:scope
      (actor:scope
        (id Main)
        x
        x
        x
        (members
          (new:scope
            x
            (id create)
            x
            (params (param (id env) (nominal x (id Env) x x x) x))
            x
            x
            (seq
              (=
                (var (id somevar) (nominal x (id String) x x x))
                "Content of somevar"
              )
              (call
                (. (. (reference (id env)) (id out)) (id print))
                (positionalargs
                  (seq
                    (+
                      (+ "Line 1:
" (reference (id somevar)) x)
                      "
                    Line 3
                  "
                      x
                    )
                    (+ "" (call (reference (id someFun)) x x x) x)
                  )
                )
                x
                x
              )
            )
            x
          )
          (fun:scope
            x
            (id someFun)
            x
            x
            (nominal x (id String) x x x)
            x
            (seq "Result of someFun")
            x
          )
        )
        x
        x
      )
    )
  )

jemc avatar Sep 07 '21 18:09 jemc

The parsing bug here is that it is treating the following expression:

                  """
                    Line 1:
                  """ + somevar + "
                    Line 3
                  """ + someFun()

As if it were the following two separate expressions:

                  """
                    Line 1:
                  """ + somevar + "
                    Line 3
                  "
                  
                  "" + someFun()

The bug is that it's not requiring a newline or semicolon to separate the end of the single-" string literal from the next two quotes, which are being treated as a separate,empty string literal.

The right behavior would be to have the parser complain upon encountering the second " character on that line, which is invalid syntax to have it be immediately following the "Line 3" string literal.

This would hopefully alert the user as to what the problem was with using a single " character to start the "Line 3" literal instead of """ as they likely intended.

jemc avatar Sep 07 '21 18:09 jemc