l-lang-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[L-lang-devel] Creators and accessers


From: Matthieu Lemerre
Subject: [L-lang-devel] Creators and accessers
Date: Sat, 10 Feb 2007 14:42:16 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

I added the support of creators and accessers yesterday.  

In short, creators are what allows the creation of new objects of a
certain type; accessers allows to select individual components in an
object. With the combination of creators and accessers, L becomes a
really usable strongly typed C-like programming language.

To see how it looks like, let's take the test file:

  //Test creators
  type Index = Int;
  type Point = struct { Int x; Int y;};
  type Int_Ptr = Int *;
  type Index2 = Index;
  type Point_Ptr = struct { Int x; Int y;} *;
  type Potato = Index *;
  type Potato_Ptr = Index **;
  
  Index test()
  {
    //Test basic creators.
    let Int i = Int( 3);
    let String s = String( "toto");
  
    //Test derived creators.
    let Index id = Index( 3);
    let Index2 id2 = Index2( Index( 4));
    let Point p = Point( x:3, y:4);
  
    //Test automatic allocation of pointers.
    let Int_Ptr ip2 = Int_Ptr( 7);
    let Point_Ptr pp = Point_Ptr( x:24, y:43);
    print( "pp.x:", pp.x, "pp.y:", pp.y);
  
    //Test explicit allocation.
    let Int_Ptr ip = Int_Ptr( alloc:auto, 3);
    let Point_Ptr pp2 = Point_Ptr( alloc:malloc, x:24, y:43);
    print( "pp2.x:", pp2.x, "pp2.y:", pp2.y);
  
    //Dereferencing a derived type does not work for now.
    print( "Ip pointe sur:", *( cast( pointer( Int),
                                    ip)));
    print( "Ip2 pointe sur:", *( cast( pointer( Int),
                                     ip2)));
  
    let Potato p2 = Potato( Index( 8));
  
    //Test multiple pointers allocation.
    let Potato_Ptr p_ptr = Potato_Ptr( alloc:malloc, alloc:auto, Index( 9));
    print( "p_ptr pointe sur:", **( cast( pointer( pointer( Int)),
                                        p_ptr)));
  
    Index( p.x + p.y)
  }
  

Here we define a bunch of types, and when these types are defined they
are associated with a creator.  The creator expands a form 
like Point( x:3, y:4); to performs the actual allocation.

The accessers transforms forms like p.x into ((struct { Int x; Int y;}
*) p).x, and performs also automatic pointer dereferencing: 
that means that:

  let struct { Int x; Int y;} * point;
  ...
  point.x
  
is expanded into:
  
  let struct { Int x; Int y;} * point;
  ...
  (*point).x
  
No need for arrows anymore.  There are many situations where using the
same notation for structs and pointers to structs is useful; consider
for instance the case where you embed a structure into another, and
later decide to use a pointer to the structure instead (because the
embedded structure is shared for instance).  Without it, you would
have to rewrite all your code that accessed the embedded structure;
here you only have to change the type definition.

More info on creators can be found in the file src/std/creator.c

I think L really begins to be usable; and I'm getting closer to the
goal of writing the compiler for outputing GNU C code from L code in
L, which will be the first step towards L self-hosting.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]