dimitriv / Ziria

A domain-specific-language and compiler for low-level bitstream processing.
92 stars 18 forks source link

Issue passing an expression block with a single let #56

Closed bradunov closed 9 years ago

bradunov commented 9 years ago

This is similar to issue #53. Again, I am fine with the parsing rules, I just want to understand/clarify the error messages. For example, consider the following example: fun test() { var i : int; let s = 5 in let t = s; i := t; } in read[int] >>> do{test()} >>> write[int]

Firstly, the example itself won't parse because let s = 5 in has to be followed by an expression, and not by another let-bound which is finished by ; . The message is confusing - says: unexpected ";", expecting computation , I suppose it should read expression.

So if I remove the let s = 5 in line, it compiles. But if I remove the i := t; line, then it doesn't compile again. This is similar, but again says expecting computation . I guess it should read expecting expression .

edsko commented 9 years ago

The additional information that the parser now maintains as part of the solution to #53 also applies here; for example, if you now do

fun comp f() {
  let x = 5; 
}

you get

A block must end on a computation, it cannot end on a declaration.
The declaration for "x" appears unused?

and if you do (with a minor variation on the example in the ticket above):

fun f() {
  var i : int; 
  let s = 5 in { let t = s }; 
  i := t;
}

you get

A block must end on an expression, it cannot end on a declaration.
The declaration for "t" appears unused?

As mentioned in the ticket, however, if you left out the braces in that second example you would get a different error message, which is perhaps confusing. So I've made a further change to the parser so that we can give the same error message in both cases: the example

  var i : int; 
  let s = 5 in let t = s; 
  i := t; 

now gives precisely the same error message. Note also that the error message now mentions that t appears unused, which might be a valuable clue for the programmar: the explicit in for the binding for s introduces a local scope for s, and hence t is only defined in that local scope. Once we get to the assignment, t is no longer in scope.