gracelang / minigrace

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

Compiler crash when case arms have no paramaters #284

Closed IsaacOscar closed 5 years ago

IsaacOscar commented 5 years ago

When I forget to put an "->" in my case blocks, e.g. with:

match (done) case { done }

The compiler crashes with the following error:

BoundsError: index 1 but list has size 0
  raised at list.at(_) at line 512 of collectionsPrelude
  requested from list.first at line 415 of collectionsPrelude
  requested from block.apply at line 1377 of parser
  requested from while(_)do(_) in native code
  requested from matchcase at line 1328 of parser
  requested from term at line 1446 of parser
  requested from expression(_) at line 1500 of parser
  requested from block.apply at line 3000 of parser
  requested from successfulParse(_) at line 262 of parser
  requested from statement at line 3000 of parser
  requested from block.apply at line 3217 of parser
  requested from while(_)do(_) in native code
  requested from parse(_) at line 3198 of parser
  requested from block.apply at line 35 of compiler
  requested from module initialization at line 19 of /usr/bin/compiler.js
  requested on line 19 of . 511:         method at(n) { 512:             native "js" code ‹var idx = var_n._value; 513:                 var result = this._value[idx-1];

Naturally I can fix this by writing

match (done) case { _ -> done }

But it would be nice to have a more helpful error message.

apblack commented 5 years ago

Obviously, the compiler should not crash. But what should the correct behaviour be? Should we compile code that will always generate a NoSuchMethod error? Or raise a type error statically — which is not something that minigrace does anywhere else.

KimBruce commented 5 years ago

The language requires an anonymous function taking a single argument after the keyword case. If a literal block occurs there it seems easy enough to detect syntactically whether or not it has a single parameter and to declare an error immediately. If it is not a literal block, then it is likely undecidable and should just be ignored in the base language.

It seems parallel to the issue of putting curly braces around the condition in a while loop (there it requires a zero-ary function, so a unary function would be an error), so it seems they should both be handled similarly (and I don't know how it is handled for while loops now).