metaborg / nabl

Spoofax' Name Binding Language
Apache License 2.0
7 stars 12 forks source link

Consider what should happen to annotations on explicated terms #98

Closed molenzwiebel closed 2 years ago

molenzwiebel commented 2 years ago

Short description

I recently got bit because I was accidentally setting properties on explicated (A2B) nodes, which disappear during implication. I feel like this may be a pitfall that can come to bite others in the future, so I'm writing a feature request/issue to get some discussion going on possible ways to make this clearer.

Problem description.

In my case, my grammar looked something like this:

Literal.Int = <<INT>>
Exp.Var = <<ID>>
Exp = Literal

I then had a statix rule that looked like this:

  boxIfNeeded : Exp * TYPE * TYPE
  boxIfNeeded(x, INT(), OBJECT()) :- @x.box += "int".
  boxIfNeeded(x, BOOL(), OBJECT()) :- @x.box += "bool".
  boxIfNeeded(x, STRING(), OBJECT()) :- @x.box += "str".
  boxIfNeeded(x, _, _).

Which was used somewhat like this:

  stmtOk(s, Return(e)) :-
    typeOfExp(s, e) == T,
    lookupReturnType(s) == RT,
    assignableTo(T, RT) | error $[Cannot return values of type [T] in a function declared with [RT] as return type.],
    boxIfNeeded(e, T, RT).

The intention here is to attach the box annotation on any expressions that must first be boxed when executed in a runtime that has separate representations for primitives and objects (e.g. Java).

However, when testing this with return 3, the actual AST that Statix processes is Return(Literal2Exp(Int("3")), which in return results in boxIfNeeded attaching annotations to Exp2Literal, which disappear after implication.

Possible approaches

There are some approaches we could consider. The ones that come to mind are:

AZWN commented 2 years ago

Good to bring this up, I've heard other people having this problem as well.

I decided to go with your last option, which is implemented in 3efc21d764e171e911b8868f880332b3167ded03.