hydromatic / morel

Standard ML interpreter, with relational extensions, implemented in Java
Apache License 2.0
291 stars 15 forks source link

In compilation environment, use name + ordinal as the key, not just name, to accommodate variable copies caused by inlining #179

Closed julianhyde closed 1 year ago

julianhyde commented 1 year ago

In the compilation environment (net.hydromatic.morel.compile.Environment) the key for values was previously a String (the name of the variable) but is now a Core.NamedPat (the name plus an ordinal). This accommodates duplicate names, which can occur by certain kinds of inlining.

For example, if you inline

from e in (from e in emps yield {e.deptno, e.ename})
where e.deptno = 30

you get

from e in emps
  yield {e.deptno, e.name}
  yield {e_1 = e}
  where e_1.deptno = 30

(where e_1 is a variable whose name is "e" and ordinal is 1 and e is a variable whose name is "e" and ordinal is 0). The variables shadow each other before inlining but they need to coexist after inlining.

As part of this change we add class RefChecker, to check that variables referenced are in scope. If, in the above, we changed where e_1.deptno = 30 to where e.deptno = 30, RefChecker would notice that the output bindings of the yield {e_1 = e} step contained e_1 and not e, and. therefore where e.deptno = 30 is invalid.

And we fix EnvShuttle and EnvVisitor for problems found by RefChecker.