www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Associative array trouble

reply Justin Johansson <no spam.com> writes:
What's wrong with this simple symbol table class?

class Symbol
{
   private char[] id;
   private static Symbol[char[]] symtab;

   private this( string id) {
      this.id = id;
   }

   static Symbol opCall( char[] id) {
      Symbol sym = symtab[id];  // *** ArrayBoundsError here

      if (sym is null) {
         sym = symtab[id] = new Symbol( id);
      }

      return sym;
   }
}


void main() {
  auto sym = Symbol( "foo");
}

Running gives Error: ArrayBoundsError

Does symtab need to be initialized in, say, a static if.
The reference documentation on associative arrays does not suggest that it
needs to be.

Thanks for all help.
Justin
Oct 16 2009
parent reply Bill Baxter <wbaxter gmail.com> writes:
You query presence of a key in an AA using 'in'

  if (id in symtab) {
     Symbol sym =3D symtab[id];
     ...
  } else {
      ..
  }

Or this avoids a double lookup if the symbol is present:

  Symbol* pSym =3D id in symtab;
  if (pSym !is null) {
         Symbol sym =3D *pSym;
         ...
  } else {
         ...
  }

--bb

On Fri, Oct 16, 2009 at 1:37 PM, Justin Johansson <no spam.com> wrote:
 What's wrong with this simple symbol table class?

 class Symbol
 {
 =A0 private char[] id;
 =A0 private static Symbol[char[]] symtab;

 =A0 private this( string id) {
 =A0 =A0 =A0this.id =3D id;
 =A0 }

 =A0 static Symbol opCall( char[] id) {
 =A0 =A0 =A0Symbol sym =3D symtab[id]; =A0// *** ArrayBoundsError here

 =A0 =A0 =A0if (sym is null) {
 =A0 =A0 =A0 =A0 sym =3D symtab[id] =3D new Symbol( id);
 =A0 =A0 =A0}

 =A0 =A0 =A0return sym;
 =A0 }
 }


 void main() {
 =A0auto sym =3D Symbol( "foo");
 }

 Running gives Error: ArrayBoundsError

 Does symtab need to be initialized in, say, a static if.
 The reference documentation on associative arrays does not suggest that i=
t needs to be.
 Thanks for all help.
 Justin
Oct 16 2009
next sibling parent Justin Johansson <no spam.com> writes:
Bill Baxter Wrote:

 You query presence of a key in an AA using 'in'
Thank you Bill .. esp. the tip to avoid double lookup. JJ
Oct 16 2009
prev sibling next sibling parent reply "Manfred_Nowak" <svv1999 hotmail.com> writes:
Bill Baxter wrote:

   Symbol* pSym = id in symtab;
shouldn't the compiler sort this out? -manfred
Oct 16 2009
parent Bill Baxter <wbaxter gmail.com> writes:
On Fri, Oct 16, 2009 at 4:11 PM, Manfred_Nowak <svv1999 hotmail.com> wrote:
 Bill Baxter wrote:

 =A0 Symbol* pSym =3D id in symtab;
shouldn't the compiler sort this out?
I'm not really sure what you mean, but I think the answer is that there's a difference between an unset entry and one that's set to null. --bb
Oct 16 2009
prev sibling next sibling parent downs <default_357-line yahoo.de> writes:
Bill Baxter wrote:
 You query presence of a key in an AA using 'in'
 
   if (id in symtab) {
      Symbol sym = symtab[id];
      ...
   } else {
       ..
   }
 
 Or this avoids a double lookup if the symbol is present:
 
   Symbol* pSym = id in symtab;
   if (pSym !is null) {
          Symbol sym = *pSym;
          ...
   } else {
          ...
   }
 
 --bb
 
Slightly shorter form: if (auto pSym = id in symtab) { ... }
Oct 16 2009
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Bill Baxter:

Or this avoids a double lookup if the symbol is present:<
In LDC both forms (and several other ones, if the usage of the pointer is local, and it doesn't get passed away) get simplified to the same single lookup code :-) (but not in DMD). So much that you may even think of "in" to return just a boolean. You can tell I like LDC a lot, it's the best thing happened to D in a lot of time. Bye, bearophile
Oct 16 2009