lojikil / coastML

a tiny experimental ML dialect combining Yeti & CarML
ISC License
12 stars 0 forks source link

Lifting a `case` form errors #4

Closed lojikil closed 1 year ago

lojikil commented 1 year ago

lifting a case form with some type constructors errors out:

The minimal test case:

type List
| DCons is [string List]
| Nil
epyt

iter-show = fn l {
    case l
        | (List.DCons _ _) {
            print "x is" (_0 l);
            iter-show (_1 l)
        }
        | _ { 
            ()
        }
    esac
}

and the result:

% ./coastml compile ../sandcity/t0.coast
# compiling: ../sandcity/t0.coast
in is_accessor with: _0
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/local/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/Users/lojikil/Code/coastML/carpet/__main__.py", line 29, in <module>
    for p in c.compile():
  File "/Users/lojikil/Code/coastML/carpet/cg/compiler.py", line 140, in compile
    subl = self.sub_compile(new_assign)
  File "/Users/lojikil/Code/coastML/carpet/cg/compiler.py", line 368, in sub_compile
    tmp = self.sub_compile(ast.value, env.copy())
  File "/Users/lojikil/Code/coastML/carpet/cg/compiler.py", line 447, in sub_compile
    body = self.sub_compile(ast.body, fn_env)
  File "/Users/lojikil/Code/coastML/carpet/cg/compiler.py", line 475, in sub_compile
    new_progn += self.sub_compile(b, block_env)
  File "/Users/lojikil/Code/coastML/carpet/cg/compiler.py", line 431, in sub_compile
    new_then = self.sub_compile(then, env.copy())
  File "/Users/lojikil/Code/coastML/carpet/cg/compiler.py", line 475, in sub_compile
    new_progn += self.sub_compile(b, block_env)
  File "/Users/lojikil/Code/coastML/carpet/cg/compiler.py", line 405, in sub_compile
    env.variables += ast.name.identvalue
  File "/Users/lojikil/Code/coastML/carpet/util/spaghetti.py", line 104, in __iadd__
    raise NotImplemented("__iadd__ only works on list frames")
TypeError: 'NotImplementedType' object is not callable

The it's definitely an assumption from when I was building the original case code after lifting the form to a binding, and it's an interaction with how we handle both case forms with a function call as the condition as well as case forms with constructor cases.

lojikil commented 1 year ago

Oh, I lied, it's an interaction with the tail call rewriter: # debugging: shadow_l = _1 l; which is clearly the function call -> while loop rewriter. Interesting.

lojikil commented 1 year ago

Ja, let's look at this around line 405 in carpet/cg/compiler as well as around line 397; the fix for both should be to actually just assign to the frame, and allow the spaghetti stack to take care of both.

lojikil commented 1 year ago

Interesting, the EnvironmentFrame is definitely getting a ton of garbage added to it:

# compiling: ../sandcity/list-test.coast
# in is_accessor with: _0
#  <class 'carpet.util.spaghetti.SpaghettiStack'> <class 'carpet.util.spaghetti.SpaghettiStack'>
#  [[[[[[[], []], {}], {}], {}], {}]]
lojikil commented 1 year ago

This makes me want to rewrite the whole thing in something else 😭

lojikil commented 1 year ago

A fair number of those are likely from us env.variables += ... the returns from other functions into the variable space, I wonder if that's part of the issue: something is returning a dict whereas we thought it would be returning a list...

lojikil commented 1 year ago

Honestly, thinking about this more, we probably should also separate out the two phases:

lojikil commented 1 year ago

This is definitely still an issue, but I've been using nopython for the self-hosting compiler, and probably would prefer to do that over digging into this here...