May 03, 2008
OR : Lisp like List in D Take 2

Andrew McKinley from Axxon / Suneido Software was gentle enough to allow me to show his C++ code to discuss what is (or what is actually not) possible in D2.

I'll attach his source as reference however the most interesting parts are :
How you work around for reference return values ?
Copy constructor ...
Some C++ specific operator overloads

...I am not asking you to to my homework... it is just that I can't find a satisfying solution regarding a D port of this specific software.

--
Okay a Lisp list is based on a CONS CELL
a CONS CELL defined in C  will look like :
typedef void   *POINTER;      /* General purpose pointer */


typedef struct                /* A CONS is two pointers  */
    {
    POINTER  car;
    POINTER  cdr;
    } CONS;
typedef CONS    *LIST;        /* A LIST is a pointer to  */
                               /* a CONS
// which becomes in D

alias void*  POINTER;
struct CONS
{
    POINTER  car;
    POINTER  cdr;
}
alias CONS* LIST;

which is nonsense (sorry reg. the mess I've published before Bearophile)

So :
struct CONS(T)
{
    T value;
    CONS* next;
}
//makes a bit more sense

A Q and Dirty implementation of LispList is :

class Lisp(T)
{
   this(T) {}


   scope class Cons(T) //erm
   {
      this(T)
       {}
   }


}

Well we have to look at the attached source now :
You'll find a lot of stuff -< which is not doable in D. Workarounds ?
just have a look at
T& operator[](int i)
{ return nth(i); }

const T& operator[](int i) const
	{ return nth(i); }


Yummie

Back to the cons cell. I really wonder if array slicing is an option
here . Let's say :
//INSTEAD OF
struct CONS(T)
{
    T value;
    CONS* next;
}


struct CONS(T)
{
    T value;
    CONS*[] cons;
}

???????
Just for me it seems that porting C++ is not a stringent task.

What do yopu think ?






May 04, 2008
On Sun, 04 May 2008 03:16:04 +0400, Bjoern <nanali@nospam-wanadoo.fr> wrote:

> OR : Lisp like List in D Take 2
>
> Andrew McKinley from Axxon / Suneido Software was gentle enough to allow
> me to show his C++ code to discuss what is (or what is actually not)
> possible in D2.
>
> I'll attach his source as reference however the most interesting parts are :
> How you work around for reference return values ?
> Copy constructor ...
> Some C++ specific operator overloads
>
> ...I am not asking you to to my homework... it is just that I can't find
> a satisfying solution regarding a D port of this specific software.
>
> --
> Okay a Lisp list is based on a CONS CELL
> a CONS CELL defined in C  will look like :
> typedef void   *POINTER;      /* General purpose pointer */
>
>
> typedef struct                /* A CONS is two pointers  */
>     {
>     POINTER  car;
>     POINTER  cdr;
>     } CONS;
> typedef CONS    *LIST;        /* A LIST is a pointer to  */
>                                /* a CONS
> // which becomes in D
>
> alias void*  POINTER;
> struct CONS
> {
>     POINTER  car;
>     POINTER  cdr;
> }
> alias CONS* LIST;
>
> which is nonsense (sorry reg. the mess I've published before Bearophile)
>
> So :
> struct CONS(T)
> {
>     T value;
>     CONS* next;
> }
> //makes a bit more sense
>
> A Q and Dirty implementation of LispList is :
>
> class Lisp(T)
> {
>    this(T) {}
>
>
>    scope class Cons(T) //erm
>    {
>       this(T)
>        {}
>    }
>
>
> }
>
> Well we have to look at the attached source now :
> You'll find a lot of stuff -< which is not doable in D. Workarounds ?
> just have a look at
> T& operator[](int i)
> { return nth(i); }
>
> const T& operator[](int i) const
> 	{ return nth(i); }
>
>
> Yummie
>
> Back to the cons cell. I really wonder if array slicing is an option
> here . Let's say :
> //INSTEAD OF
> struct CONS(T)
> {
>     T value;
>     CONS* next;
> }
>
>
> struct CONS(T)
> {
>     T value;
>     CONS*[] cons;
> }
>
> ???????
> Just for me it seems that porting C++ is not a stringent task.
>
> What do yopu think ?
>
>
>
>

Now that we have opDot() and other features, you can implement Ref!(T) template that would behave just like T&.
Quick and Dirty implementation is as follows (code amount could be reduced by using string mixins):

// helper templates
template OpNegRes(T)
{
    static if (is(T t)) {
        alias typeof(-t) OpNegRes;
    } else {
        static assert(false);
    }
}

template OpPosRes(T)
{
    static if (is(T t)) {
        alias typeof(+t) OpPosRes;
    } else {
        static assert(false);
    }
}

template OpComRes(T)
{
    static if (is(T t)) {
        alias typeof(~t) OpComRes;
    } else {
        static assert(false);
    }
}

struct Ref(T)
{
    public OpNegRes!(T) opNeg()
    {
        return -(*value);
    }

    public OpPosRes!(T) opPos()
    {
        return +(*value);
    }

    public OpComRes!(T) opCom()
    {
        return ~(*value);
    }

    public T* opDot()
    {
        return value;
    }

    private T* value;
}

// small test
int main()
{
    int i = 1;
    auto reference = Ref!(int)(&i);
    assert(-reference == -i);
    assert(+reference == +i);
    assert(~reference == ~i);

    return 0;
}


Other operators are implementable in a similar way.
Note that opDot() is D2.0 only (as of now).

If you know of other ways to achieve the same goal, please share your knowledge!
May 05, 2008
Thanks!
Have no D2 on board... Probabely this works ???
struct Ref(T)
{
     public opDot!(T)
     {
       static if(is(typeof(T.opDot))
          {
            return value;
          }
    }
    private T* value;
}
Bjoern
PS hope Walter will spend us ref return values soon
Top | Discussion index | About this forum | D home