gracelang / minigrace

Self-hosting compiler for the Grace programming language
39 stars 22 forks source link

Indenting inconsistency #152

Closed KimBruce closed 7 years ago

KimBruce commented 9 years ago

The rules for indenting seem to be inconsistent. Compare the following pieces of code:

def x = 2 +
    3 + 
    4
print(x)

def x = 2 +
    3  
    + 4
print(x)

The first of these results in an error message: Syntax error: A valid expression must follow '+'. This is often caused by a new line in the middle of an expression. in "test" (line 2, column 8)

This error can be fixed by indenting the "4" by one more space. The second is fine.

I'm unable to come up with a rule that explains this. I had expected both to be legal continuations of the def statement.

kjx commented 9 years ago

On 23/09/2015, at 17:05pm, Kim Bruce notifications@github.com wrote:

I'm unable to come up with a rule that explains this. I had expected both to be legal continuations of the def statement.

Kernan:

silverbeast7:sample code kjx$ grace

def x = 2 +
... 3 +
... 4
print(x)
9

def x = 2 +
... 3

  • 4
    Uncaught exception: LookupError: R2000: Method «prefix+» not found in object «Number[4]» from «prefix+», at line 1 of source code print(x)
    5
apblack commented 9 years ago

The rule that explains this is that minigrace doesn't understand continuation lines. It is checking to see if the remainder of the expression is on the same logical line as the start of the expression, whereas it should be checking to see if it is on the same logical line as the start of the statement (i.e., the def token). That is why adding additional indentation, which effectively makes the + 4 a continuation of the expression, works in minigrace.

There is now a known-failing test tests/known-failing/continuationLines_test.grace that illustrates the problem:

//  The minigrace parser doen't understand continuation lines correctly.
//  It parses line 17 as a continuation of line 10, but lines 18 and 19 are
//  parsed as separate requests of url() and on().  Line 20 is flagged as being
//  at the wrong indentation.

import "objectdraw" as od

class atX(highwayCenterX:Number)   below(highwayBottom:Number)
      laneWidth(laneWidth:Number) on(canvas:od.DrawingCanvas) {
    def frogHeight = 40
    def frogWidth = 50
    def frogSpacing: Number = (laneWidth - frogHeight) / 2  // confidential
    def startPoint: Point =
          highwayCenterX @ (highwayBottom + frogSpacing)

    def frogImage:od.Graphic2D =
          od.drawableImage.at(startPoint)size(frogWidth,frogHeight)
          url("http://www.cs.pomona.edu/~kim/CSC051GF14/Images/froggy.png")
          on(canvas)
    def hopDistance:Number = laneWidth

    var isAlive:Boolean is readable := true
}

Unfortunately, I don't see a simple way of fixing this in the minigrace parser. Its unfortunate that kernan seems to fail on this input too. I thought that Grace's rules for continuation lines were simple: that an increase in indentation that did not correspond to an increase in brace-depth signaled a continuation line, and that successive lines at the same indentation continued the continuation. The continuation is ended by any outdent.

apblack commented 7 years ago

This bug was fixed in commit bd5174a