A feture adjustment request and a syntax blasphemy

BCS BCS at pathlink.com
Mon Oct 30 17:45:24 PST 2006


BCS wrote:
> This is allowed:
> 
>   void foo(int[] ar){}
>   ...
>   static int[] i = [1,2,3];
>   i.foo();
> 
> And this is allowed:
> 
>   struct I
>   {
>     int[] v;
>     void foo(){}
>   }
>   ...
>   I i;
>   auto dg = &i.foo;
> 
> So why no this?
> 
>   void foo(int[] ar){}
>   ...
>   static int[] i = [1,2,3];
>   auto dg = &i.foo;
> 

FWIW I realized (at midnight this morning) why this doesn't work.

in the struct/class case the context is a pointer (32 bits) in the array 
case it is a pointer length pair (64 bits). It just doesn't fit in the hole.



and for the strong of will here is the working version using class 
literals. (The grammar comes from my CS homework, that, BTW is not the 
impetus for the program)

/*
Code ::=
  BlatA:b "@" Code:c = new Code(b,c)
  BlatA:b = new Code(b)

BlatA ::=
  Thunk:t Blat:b = new BlatA(t,b)

Blat ::=
  "!" Thunk:t Blat:b = new Blat(t,b)
  "*" Chunk:c Blat:b = new Blat(c,b)
  = new Blat()

Thunk ::=
  T:t Thunk:c T:u = new Thunk(t, c, u);
  B:b Thunk:c A:a = new Thunk(b, c, a);
  A:a Thunk:c B:b = new Thunk(a, c, b);
  W:w = new Thunk(w);

Chunk ::=
  T:t Chunk:c T:u = new Chunk(t, c, u);
  B:b Chunk:c B:d = new Chunk(b, c, d);
  A:a Chunk:c A:b = new Chunk(a, c, b);
  W:w = new Chunk(w);

T ::=
  "T":t = new T(t);

B ::=
  "B":b = new B(b);

A ::=
  "A":a = new A(a);

W ::=
  "W" = new W();
*/

import std.stdio;



void main()
{
  char[] str = "W*TWT*W at BAWBA!BBWAA!W at W".dup;
  auto ret = Parse_Code(str);
  if(ret is null)
   writef("false");
  else
   ret().val.dmp();
  writef(\n);
}


/********** some utils ****/

class Type{}
class TypeT(T)
{
  public T val;
  this(T v){val = v;}
}
alias Type delegate() ret_;

bool Peak(T)(inout T[] from, T[] match)
{
  if(from.length >= match.length && from[0..match.length] == match)
  {
   from = from[match.length..$];
   return true;
  }
  return false;
}


/*
Code ::=
  BlatA:b "@" Code:c = new Code(b,c)
  BlatA:b = new Code(b)
*/
alias TypeT!(Code) delegate() ret_Code;
ret_Code Parse_Code(inout char[] from)
{
  char[] data;


  data = from;
  if(auto b = Parse_BlatA(data))
  if(Peak!(char)(data, "@"))
  if(auto c = Parse_Code(data))
  {
   from = data;
   auto ret = new class
   {
    ret_BlatA dg_b;
    ret_Code dg_c;

    TypeT!(Code) action()
    {
     auto b = dg_b().val;
     auto c = dg_c().val;
     return new TypeT!(Code)(new Code(b,c));
    }
   };

   ret.dg_b = b;
   ret.dg_c = c;

   return &ret.action;
  }

  data = from;
  if(auto b = Parse_BlatA(data))
  {
   from = data;
   auto ret = new class
   {
    ret_BlatA dg_b;

    TypeT!(Code) action()
    {
     auto b = dg_b().val;
     return new TypeT!(Code)(new Code(b));
    }
   };

   ret.dg_b = b;

   return &ret.action;
  }


  return null;
}

/*
BlatA ::=
  Thunk:t Blat:b = new BlatA(t,b)
*/
alias TypeT!(BlatA) delegate() ret_BlatA;
ret_BlatA Parse_BlatA(inout char[] from)
{
  char[] data;


  data = from;
  if(auto t = Parse_Thunk(data))
  if(auto b = Parse_Blat(data))
  {
   from = data;
   auto ret = new class
   {
    ret_Thunk dg_t;
    ret_Blat dg_b;

    TypeT!(BlatA) action()
    {
     auto t = dg_t().val;
     auto b = dg_b().val;
     return new TypeT!(BlatA)(new BlatA(t,b));
    }
   };

   ret.dg_t = t;
   ret.dg_b = b;

   return &ret.action;
  }
  return null;
}


/*
Blat ::=
  "!" Thunk:t Blat:b = new Blat(t,b)
  "*" Chunk:c Blat:b = new Blat(c,b)
  = new Blat()
*/
alias TypeT!(Blat) delegate() ret_Blat;
ret_Blat Parse_Blat(inout char[] from)
{
  char[] data;


  data = from;
  if(Peak!(char)(data, "!"))
  if(auto t = Parse_Thunk(data))
  if(auto b = Parse_Blat(data))
  {
   from = data;
   auto ret = new class
   {
    ret_Thunk dg_t;
    ret_Blat dg_b;

    TypeT!(Blat) action()
    {
     auto t = dg_t().val;
     auto b = dg_b().val;
     return new TypeT!(Blat)(new Blat(t, b));
    }
   };

   ret.dg_t = t;
   ret.dg_b = b;

   return &ret.action;
  }

  data = from;
  if(Peak!(char)(data, "*"))
  if(auto c = Parse_Chunk(data))
  if(auto b = Parse_Blat(data))
  {
   from = data;
   auto ret = new class
   {
    ret_Chunk dg_c;
    ret_Blat dg_b;

    TypeT!(Blat) action()
    {
     auto c = dg_c().val;
     auto b = dg_b().val;
     return new TypeT!(Blat)(new Blat(c, b));
    }
   };

   ret.dg_c = c;
   ret.dg_b = b;

   return &ret.action;
  }

  data = from;
  if(true)
  {
   from = data;
   auto ret = new class
   {

    TypeT!(Blat) action()
    {
     return new TypeT!(Blat)(new Blat());
    }
   };


   return &ret.action;
  }


  return null;
}


/*
Thunk ::=
  T:t Thunk:c T:u = new Thunk(t, c, u);
  B:b Thunk:c A:a = new Thunk(b, c, a);
  A:a Thunk:c B:b = new Thunk(a, c, b);
  W:w = new Thunk(w);
*/

alias TypeT!(Thunk) delegate() ret_Thunk;
ret_Thunk Parse_Thunk(inout char[] from)
{
  char[] data;

  data = from;
  if(auto t = Parse_T(data))
  if(auto c = Parse_Thunk(data))
  if(auto u = Parse_T(data))
  {
   from = data;
   auto ret = new class
   {
    ret_T dg_t;
    ret_Thunk dg_c;
    ret_T dg_u;

    TypeT!(Thunk) action()
    {
     auto t = dg_t().val;
     auto c = dg_c().val;
     auto u = dg_u().val;
     return new TypeT!(Thunk)(new Thunk(t, c, u));
    }
   };

   ret.dg_t = t;
   ret.dg_c = c;
   ret.dg_u = u;

   return &ret.action;
  }

  data = from;
  if(auto b = Parse_B(data))
  if(auto c = Parse_Thunk(data))
  if(auto a = Parse_A(data))
  {
   from = data;
   auto ret = new class
   {
    ret_B dg_b;
    ret_Thunk dg_c;
    ret_A dg_a;

    TypeT!(Thunk) action()
    {
     auto b = dg_b().val;
     auto c = dg_c().val;
     auto a = dg_a().val;
     return new TypeT!(Thunk)(new Thunk(b, c, a));
    }
   };

   ret.dg_b = b;
   ret.dg_c = c;
   ret.dg_a = a;

   return &ret.action;
  }

  data = from;
  if(auto a = Parse_A(data))
  if(auto c = Parse_Thunk(data))
  if(auto b = Parse_B(data))
  {
   from = data;
   auto ret = new class
   {
    ret_A dg_a;
    ret_Thunk dg_c;
    ret_B dg_b;

    TypeT!(Thunk) action()
    {
     auto a = dg_a().val;
     auto c = dg_c().val;
     auto b = dg_b().val;
     return new TypeT!(Thunk)(new Thunk(a, c, b));
    }
   };

   ret.dg_a = a;
   ret.dg_c = c;
   ret.dg_b = b;

   return &ret.action;
  }

  data = from;

  if(auto w = Parse_W(data))
  {
   from = data;
   auto ret = new class
   {
    ret_W dg_w;

    TypeT!(Thunk) action()
    {
     auto w = dg_w().val;
     return new TypeT!(Thunk)(new Thunk(w));
    }
   };

   ret.dg_w = w;

   return &ret.action;
  }

  return null;
}

/*
Chunk ::=
  T:t Chunk:c T:u = new Chunk(t, c, u);
  B:b Chunk:c B:d = new Chunk(b, c, d);
  A:a Chunk:c A:b = new Chunk(a, c, b);
  W:w = new Chunk(w);
*/

alias TypeT!(Chunk) delegate() ret_Chunk;
ret_Chunk Parse_Chunk(inout char[] from)
{
  char[] data;


  data = from;
  if(auto t = Parse_T(data))
  if(auto c = Parse_Chunk(data))
  if(auto u = Parse_T(data))
  {
   from = data;
   auto ret = new class
   {
    ret_T dg_t;
    ret_Chunk dg_c;
    ret_T dg_u;

    TypeT!(Chunk) action()
    {
     auto t = dg_t().val;
     auto c = dg_c().val;
     auto u = dg_u().val;
     return new TypeT!(Chunk)(new Chunk(t, c, u));
    }
   };

   ret.dg_t = t;
   ret.dg_c = c;
   ret.dg_u = u;

   return &ret.action;
  }

  data = from;
  if(auto b = Parse_B(data))
  if(auto c = Parse_Chunk(data))
  if(auto d = Parse_B(data))
  {
   from = data;
   auto ret = new class
   {
    ret_B dg_b;
    ret_Chunk dg_c;
    ret_B dg_d;

    TypeT!(Chunk) action()
    {
     auto b = dg_b().val;
     auto c = dg_c().val;
     auto d = dg_d().val;
     return new TypeT!(Chunk)(new Chunk(b, c, d));
    }
   };

   ret.dg_b = b;
   ret.dg_c = c;
   ret.dg_d = d;

   return &ret.action;
  }

  data = from;
  if(auto a = Parse_A(data))
  if(auto c = Parse_Chunk(data))
  if(auto b = Parse_A(data))
  {
   from = data;
   auto ret = new class
   {
    ret_A dg_a;
    ret_Chunk dg_c;
    ret_A dg_b;

    TypeT!(Chunk) action()
    {
     auto a = dg_a().val;
     auto c = dg_c().val;
     auto b = dg_b().val;
     return new TypeT!(Chunk)(new Chunk(a, c, b));
    }
   };

   ret.dg_a = a;
   ret.dg_c = c;
   ret.dg_b = b;

   return &ret.action;
  }

  data = from;
  if(auto w = Parse_W(data))
  {
   from = data;
   auto ret = new class
   {
    ret_W dg_w;

    TypeT!(Chunk) action()
    {
     auto w = dg_w().val;
     return new TypeT!(Chunk)(new Chunk(w));
    }
   };

   ret.dg_w = w;

   return &ret.action;
  }

  return null;
}




/*
T ::= "T":t = new T(t);
*/
alias TypeT!(T) delegate() ret_T;
ret_T Parse_T(inout char[] from)
{
  char[] data = from;
  if(Peak(data, "T"))
  {
   from = data;
   auto ret = new class
   {
    TypeT!(T) action()
    {
     return new TypeT!(T)(new T());
    }
   };
   return &ret.action;
  }
  return null;
}



/*
B ::= "B":b = new B(b);
*/
alias TypeT!(B) delegate() ret_B;
ret_B Parse_B(inout char[] from)
{
  char[] data = from;
  if(Peak(data, "B"))
  {
   from = data;
   auto ret = new class
   {
    TypeT!(B) action()
    {
     return new TypeT!(B)(new B());
    }
   };
   return &ret.action;
  }
  return null;
}

/*
A ::= "A":a = new A(a);
*/
alias TypeT!(A) delegate() ret_A;
ret_A Parse_A(inout char[] from)
{
  char[] data = from;
  if(Peak(data, "A"))
  {
   from = data;
   auto ret = new class
   {
    TypeT!(A) action()
    {
     return new TypeT!(A)(new A());
    }
   };
   return &ret.action;
  }
  return null;
}
/*
W ::= "W" = new W();
*/
alias TypeT!(W) delegate() ret_W;
ret_W Parse_W(inout char[] from)
{
  char[] data = from;
  if(Peak(data, "W"))
  {
   from = data;
   auto ret = new class
   {
    TypeT!(W) action()
    {
     return new TypeT!(W)(new W());
    }
   };
   return &ret.action;
  }
  return null;
}








/*********** stuff for actions   ********/

class Code
{
  BlatA bl;
  Code co;
  this(BlatA b){bl=b; co=null;}
  this(BlatA b, Code c){bl=b; co=c;}

  void dmp()
  {
   writef("Code(");
   bl.dmp();
   if(co !is null)
   {
    writef(" @ ");
    co.dmp;
   }
   writef(")");
  }
}

class BlatA
{
  Thunk th;
  Blat bl;
  this(Thunk t, Blat b){th=t;bl=b;}
  void dmp()
  {
   writef(" BlatA(");
   th.dmp();
   bl.dmp();
   writef(")");
  }
}

class Blat
{
  Thunk th;
  Chunk ch;
  Blat bl;
  this(){th=null;ch=null;bl=null;}
  this(Thunk t, Blat b){th=t;bl=b;ch=null;}
  this(Chunk c, Blat b){ch=c;bl=b;th=null;}

  void dmp()
  {
   if(bl is null) return;
   writef(" Blat(");
   if(th !is null)
   {
    writef("! ");
    th.dmp();
    bl.dmp();
   }
   else
   {
    writef("* ");
    ch.dmp();
    bl.dmp();
   }
   writef(")");

  }
}

class Thunk
{
  char f;
  Thunk th;
  this(T v, Thunk t, T u){th=t;f='T';}
  this(B b, Thunk t, A a){th=t;f='B';}
  this(A a, Thunk t, B b){th=t;f='A';}
  this(W w){th=null;f='W';}
  void dmp()
  {
   writef(" Thunk(");
   switch(f)
   {
    case 'W':
     W.dmp();
     break;
    case 'T':
     T.dmp();
     th.dmp();
     T.dmp();
     break;
    case 'B':
     B.dmp();
     th.dmp();
     A.dmp();
     break;
    case 'A':
     A.dmp();
     th.dmp();
     B.dmp();
     break;
   }
   writef(")");
  }
}

class Chunk
{
  char f;
  Chunk ch;
  this(T t, Chunk c, T u){ch=c;f='T';}
  this(B b, Chunk c, B d){ch=c;f='B';}
  this(A a, Chunk c, A b){ch=c;f='A';}
  this(W w){ch=null;f='W';}
  void dmp()
  {
   writef(" Chunk(");
   switch(f)
   {
    case 'W':
     W.dmp();
     break;
    case 'T':
     T.dmp();
     ch.dmp();
     T.dmp();
     break;
    case 'B':
     B.dmp();
     ch.dmp();
     B.dmp();
     break;
    case 'A':
     A.dmp();
     ch.dmp();
     A.dmp();
     break;
   }
   writef(")");
  }
}

class T
{
  this(){}
  static void dmp(){writef(" T ");}
}
class A
{
  this(){}
  static void dmp(){writef(" A ");}
}
class B
{
  this(){}
  static void dmp(){writef(" B ");}
}
class W
{
  this(){}
  static void dmp(){writef(" W ");}
}



More information about the Digitalmars-d-learn mailing list