gracelang / minigrace

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

expression used in place of block parameter crashes compiler! #147

Closed apblack closed 7 years ago

apblack commented 9 years ago

If a student erroneously writes an expression rather than new identifier as a block parameter, the compiler will crash (while asking for its dType).

This happened during the final exam, so I didn't get to capture the program. But it was something like

{ input.substringFrom 2 -> ... }

where input was a method parameter.

apblack commented 8 years ago

Here is a program that provokes the bug:

method valueOf (nullaryBlock) {
    nullaryBlock.apply
}

def y = "foobar"
var x := valueOf {
    match("foo")
          case {17->1}
          case {19->2}
          case {y.substringFrom 1 size 3 -> "it's foo"}
}

print(x)

It's in svn (.../Bugs/expressionMatch.grace). This seems to be the same bug as #159.

petercowal commented 8 years ago

Here's something weird: the following program

method valueOf (nullaryBlock) {
    nullaryBlock.apply
}

def y = "21"
var x := valueOf {
    match(21)
          case {17->1}
          case {19->2}
          case {y.asNumber -> "it's 21"}
          case {_ → "no match"}
}

print(x)

outputs it's 21 without complaint! It seems that the compiler only complains when an expression with a parameter is used.

apblack commented 8 years ago

I think that this bug is caused by the block-rewriting pass in identifierresolution. It thinks that method requests in the pattern-position are "destructuring matches", no longer in Grace.

I think that the solution is to remove that rewriting pass, and fix the parser to parse the input correctly in the first place. I think that "correctly" means that

apblack commented 7 years ago

The block-rewriting pass has gone, and so has this bug. Because blocks are patterns, some legal code may give surprising results, but the compiler does not crash! For example:

var x := "foo"
for (1..10) do { x*2 → print(x) }

The block is legal, but produces the run-time error:

RequestError on line 2 of #147: argument to block.apply(_) does not match pattern.

because the argument is 1, and the pattern "foofoo".

Perhaps a beginningStudent dialect ought to make patterns illegal?