[<<][meta][>>][..]
Sat Dec 31 07:55:56 EST 2011

What is a a virtual struct?

Note that this is still functional programm, so we really should have
referential transparency.  That means that it should be possible to
replace a variable with its value at all times.

However, once we start making a distinction between Var and Term this
seems to disappear.

So.  What is the difference between a VarTree and a Term encoding a
structure?

It seems that the only problem to solve is the Unpack problem above,
and it just needs to know the difference between a reference to a
reified struct, and a bunch of variable names.

Some issues:

- Conceptually separate Tree of binders from Tree of terms.  This was
  separate in the original approach (binders where lists of variables.

  This solves the Unpack issue: if Unpack's argument is a single
  variable reference, it's implemented by a C struct.  If it's a Term
  representing a tree terminated in variable references, it's a
  virtual struct.

- Since both trees are isomorphic, encode this isomorphism explicitly
  in Term.


Conclusion: both are needed as they represent different things, but
there is an embedding from one (VarTree) to the other (Term).

So, making this changes seems to go well up to now.  First thing I run
into is that Get / Set should take a Term as first argument, not a
Var.  This can probably be generalized to other places where just Var
appears, since we're now allowing structured variable references ala:

   (Car (Cdr (Ref v)))

Ok.. Working my way down to PrettyC.hs it seems that the main problem
with that file and its heavy facotorization is: are things represented
as Term subrees or AST subtrees?  It's quite arbitrary, and seems to
be a problem that is intrinsic in complex tree transformations,
related to the order of recursion.

Next error: t20

  *** Exception: _unatom Car (Ref (Var {varType = Type (AStruct (Type AFloat 1,Type (AStruct (Type AFloat 1,Type AFloat 1)) 0)) 0, varName = "a0"}))

  Type (AStruct (Type AFloat 1,
                 Type (AStruct (Type AFloat 1,
                                Type AFloat 1)) 0))

Makes no sense.  Is there anything else that works all the way down to
C code generation?

Yes.  0test_integration.hs : t18 works, and t15 generates code but
still has the 1-element struct vs float problem.

t19 gives a similar error.

What does it mean?

First that type error.  I suspect it's because of this typeOf call:


  instance TMLword t 
           => StructVar Term (L (Code t)) where  
    structVar prefix id = (id + 1, Atom $ t, L (Code $ t)) where
      t = term $ typeOf (undefined :: Code t) where
        term typ = Ref $ Var typ $ prefix ++ show id


Maybe it's even deeper.  Is there a primitive difference between
struct of 1 and base type?  Don't think so.

Maybe it's even deeper.  TypeName doesn't reflect the same binary tree
structure as VarTree

Ok, fixing that as:

  data TypeName   = AFloat | AInt | ABool | AVoid  -- atomic
                  | ATree TypeTree                 -- composite 
                  | AType Int                      -- indexed type (see PrettyC.hs)
                  deriving (Eq,Show)

  data TypeTree   = AAtom Type
                  | ANil 
                  | ACons Type Type
                  deriving (Eq,Show)

  data Type       = Type TypeName TypeOrder
                  deriving (Eq,Show)

And propagating this change down the chain, I get the following which
has an explicit representation of atoms as singleton structs.

  struct tuple_f0 {
      float m0;
  };
  struct tuple_f00f00 {
      struct tuple_f0 {
          float m0;
      } m0;
      struct tuple_f0 {
          float m0;
      } m1;
  };
  int fun(struct tuple_f00f00 * a0,
          struct tuple_f0 * a1,
          struct tuple_f0 * a2,
          int a3)
  {
      {
          float fun4_0;
          float fun4_1;
          int fun4_2;
          {
              const int t8 = 0;
              const struct tuple_f00f00 t9 = a0[t8];
              const float s10 = t9.m0;
              const float s11 = t9.m1;
              const int t12 = 0;
              fun4_0 = s10;
              fun4_1 = s11;
              fun4_2 = t12;
              goto fun4;
          }
      fun4:
          {
              const float a5 = fun4_0;
              const float a6 = fun4_1;
              const int a7 = fun4_2;
              const struct tuple_f0 t8 = a1[a7];
              const float s9 = t8.m0;
              const float t10 = a6 + s9;
              const float t11 = a5 + t10;
              const struct tuple_f0 t12 = { t11 };
              a2[a7] = t12;
              const _Bool t13 = a7 < a3;
              if (t13)
              {
                  const int t14 = 1;
                  const int t15 = a7 + t14;
                  fun4_0 = t11;
                  fun4_1 = t10;
                  fun4_2 = t15;
                  goto fun4;
              }
              else
              {
                  const struct tuple_f00f00 t14 = { t11, t10 };
                  const int t15 = 0;
                  a0[t15] = t14;
                  const int t16 = 0;
                  return t16;
              }
          }
      }
  }


Trouble with this though is that inner structs should not be named.
These are not necessary and they cause conflicts.

Fixing this I run into a problem that the recursion patterns in
PrettyC are becoming pretty unwieldy.  I'm trying to fix the point
where the struct name needs to be dropped.

cTupleType' -> cVarDecl / cTupleType
cVarDecl -> cType
cType -> cType'
cType' -> cTypleType'

It's getting to a point where a monad would probably be better.  Or a
configuration structure that records recursion options and is passed
down the tree..  Passing down multiple flags doesn't seem like a good
idea.

Done



[Reply][About]
[<<][meta][>>][..]