Fri Dec 9 15:27:48 EST 2011

Toplevel definitions

I've added (Topdef Var Term) to Term.  This can represent toplevel
definitions such as variable and function definitions.

To make this work, each function should be compiled to 2 parts: an
update function and an init constant (or an init method).  The
following should compile the update function.  It typechecks but gives
problems when it's actually used.

  compileLoopTop update = _lambda funBody where
    funBody (state, 
            (Atom arri,
            (Atom arro,
             Atom arrn))) =
      _letrec loopExpr initExpr
          initExpr loop = _app loop (state, Atom $ lit 0)        
          loopExpr loop = _lambda loopBody  
              loopBody (s, Atom n) = do
                i <- _get arri n
                (s', Atom o) <- update (s, Atom i)
                _set arro n o
                more <- lt n arrn
                _if more 
                      n' <- add n (lit 1)
                      _app loop (s', Atom n'))

The arrays seem to be the problem:

  *Main> :t compileLoopTop f
  compileLoopTop f
    :: (Array (StateCont.SC Code.CompState Term) Code a Tfloat,
        Array (StateCont.SC Code.CompState Term) Code a1 Tfloat,
        TMLprim (a Tfloat),
        TMLprim (a1 Tfloat)) =>
            ((Atom Tfloat, (Atom (a Tfloat), (Atom (a1 Tfloat), Atom Tint)))
             -> StateCont.SC Code.CompState Term Tint))

Two things: the array type should probably have a fundep.  It's fixed
by the representation.  Then the TMLprim (a Tfloat) is probably not
right.  Inded, after fixing the r -> a fundep, I get:

  *Main> :t compileLoopTop f

      No instance for (TMLprim (ACode Tfloat))
        arising from a use of `compileLoopTop'
      Possible fix:
        add an instance declaration for (TMLprim (ACode Tfloat))
      In the expression: compileLoopTop f

Actually, an array is a TMLprim: it's a machine word (pointer).
TMLprim is a bit of an awkward name.  It means "non-divisable".
Primitives can be stored in Atom leaf nodes of a Struct binary tree.

Trouble here is that I want a primType that's not just a TypeName but
also a pointer order.  So it might be better to rearrange the classes
a bit to express this in a different way.

Where is TMLprim used as a constraint?

  _set   :: TMLprim t => r (a t) -> r Tint -> r t ->  m (r ())

There's another one somewhere, I can't find it right away.  The
workaround below doesn't work because _get will try to "pop" the
pointer order, which results in a pattern error.

  instance TMLprim t => TMLprim (ACode t) where
    primType _ = primType (undefined :: t)

EDIT: I removed the TMLprim t constrained here and replaced it with
TypeOf (Code t).  So conceptually, TypeOf represents machine words
while TMLprim represent primtive values, not pointers.  TypeOf is not
defined for StructPrim.

  instance TypeOf (Code t) => StructPrim Term Code t where
    primCompile (Code t) = t
    primVariable = codeVar $ typeOf (undefined :: Code t) where
      codeVar t n = Code $ Ref $ Var t n
Hmm it's not that easy.  The problem is that it's not possible at this
point to recursively define primitives (higher order pointers) because
Array and Struct dosn't allow this.  I.e. the 'r' and 't' are naked.

So the classes aren't sitting well.  Maybe this is really a symptom of
a conceptual error?  Needs some thought.