Re: any html parser with d binding

2009-05-21 Thread Frank Benoit
Robert Fraser schrieb:
 reimi gibbons wrote:
 2) how reliable is bcd to create binding for c libraries?
 
 C? Very reliable (unless it uses weird compiler directives). C++ is a
 bit trickier.

Last time I used BCD, it had no support for bitfields and generated
struct definition that do not match in size with their original.

So in general when doing C bindings, i do a check of struct sizes by
writing a C and a D program outputting the sizes and compare the outputs
with kdiff3 for manual tweaking the structs in D.


Re: going beyond your bounds

2009-05-21 Thread Derek Parnell
On Thu, 21 May 2009 04:51:16 -0400, MLT wrote:

 After a discussion on digitalmars.D I played with arrays a bit. Look at the 
 following code:
   int[] a = [1,2,3,4,5,6,7,8,9] ;
   int[] b = a ;
   a ~= 10 ;
 b ~= 11 ;
   b[0] = 12 ;
   Stdout(b).newline ;
   Stdout(a).newline ;
 
 The result is:
 [12, 2, 3, 4, 5, 6, 7, 8, 9, 11]
 [12, 2, 3, 4, 5, 6, 7, 8, 9, 11]
 
 Which means that even though b was set only to a[0..10], after expanding b, 
 also has direct access to element a[10]. But
   int[] a = [1,2,3,4,5,6,7,8,9] ;
   int[] b = a ;
   a ~= 10 ;
   b.length = b.length+1 ;
   b[0] = 11 ;
   Stdout(b).newline ;
   Stdout(a).newline ;
 
 Gives 
 [11, 2, 3, 4, 5, 6, 7, 8, 9, 0]
 [11, 2, 3, 4, 5, 6, 7, 8, 9, 0]
 
 Now b is expanded in length, but a side effect is that a[10] is set to 0 
 (i.e. initialized).
 
 In the end, I think b can only see things that happen to a[10] after it 
 expanded, but not before. It seems there is no way for the following to work:
   int[] a = [1,2,3,4,5,6,7,8,9] ;
   int[] b = a ;
   a ~= 10 ;
 
 At this point, element a[10]=10 will never be visible to b. b can expand to 
 it, but by doing that, a[10] will be overwritten.
 
 Is this on purpose? It could also be useful to have b.length=b.length+1 which 
 only initializes memory that has not been initialized before.

Yes it is on purpose.

Here is what is happening ...
The contents of the array variable is actually a 2-element struct {addr,
length}. When you assign one array to another, that struct is what is
copied, not the array data itself.

 int[] a = [1,2,3,4,5,6,7,8,9] ;
 // Now 'a' contains {adr, 9}

 int[] b = a ;
 // Now 'b' contains {adr, 9}

 a ~= 10 ;
 // Now 'a' contains {adr, 10} -- The address doesn't change
   -- because the buffer allocation
   -- still enough room for another element.

 b ~= 11 ;
 // Now 'b' contains {adr, 10} -- The address doesn't change
   -- because the buffer allocation
   -- still enough room for another element
   -- And that new element overwrote the '10'
   -- appended to 'a'.

 b[0] = 12 ;
 // The element at address 'adr' is modified. 
 // As both 'a' and 'b' point to the same area 
 // it appears that updating 'b' changes 'a'.


The safe way to copy the data of an array is to do ...
 int[] a = [1,2,3,4,5,6,7,8,9] ;
 int[] b = a.dup ; // COPY a's data to to b.
 a ~= 10 ;
 b ~= 11 ;
 b[0] = 12 ;

The result should now be:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[12, 2, 3, 4, 5, 6, 7, 8, 9, 11]


So remember, assigning one array to another is just creating an alias to
the original array. You end up with two arrays pointing to the same data
buffer.

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell


Re: going beyond your bounds

2009-05-21 Thread MLT

 Because new elements are pre-initialized in D.
 
 Just by increasing the length, you 'create' a new element (from the 'b'
 point of view) so D initializes it.

(We were talking about something like
int a[] = [1,2,3,4,5] ;
b = a ;
a ~= 6 ;
b.length = b.length+1;)


Hmmm... yes, that has some logic to it.

D does keep track of the actual array of integers that both a and b point to
and knows when to allocate new memory for the array. So in theory it could be 
possible that when b.length increases, initialization only happens if this 
memory is uninitialized.
On the other hand, I guess that if you get an array, say b, in a function, you 
might rely on the fact that when you extend b.length, the area will be 
initialized...




Re: going beyond your bounds

2009-05-21 Thread Derek Parnell
On Thu, 21 May 2009 05:58:04 -0400, MLT wrote:

 Because new elements are pre-initialized in D.
 
 Just by increasing the length, you 'create' a new element (from the 'b'
 point of view) so D initializes it.
 
 (We were talking about something like
 int a[] = [1,2,3,4,5] ;
 b = a ;
 a ~= 6 ;
 b.length = b.length+1;)
 
 Hmmm... yes, that has some logic to it.
 
 D does keep track of the actual array of integers that both a and b point to

Not really. The original data is a literal so it is supposed to be
unmodifiable (I think Linux enforces it but not sure). 

 and knows when to allocate new memory for the array. 

It allocates new RAM when the current buffer allocation will not be large
enough to hold the new elements. When it does this, it allocates the new
buffer and copies the old data to it. This means that you cannot rely on
the alias 'feature' to work all the time.

For example ...

  int[] a = [ some data ];
  int[] b = a; // Ok, so both 'a' and 'b' point to the data now.

  a ~= newone; // This can't fit in so an allocation occurs
   // and the data copied, then 'a' is set to the
   // the new buffer.
  // BUT 'b' still points to the old buffer.


So in theory it could be possible that when b.length increases,
 initialization only happens if this memory is uninitialized.

Theoreticaly yes, but it isn't going to happen.

 On the other hand, I guess that if you get an array, say b,
 in a function, you might rely on the fact that when you
 extend b.length, the area will be initialized...

This is also a trap. If the function increases the length of the array
passed to it, there will be so initialization happening, but when the
function returns, the array variable passed to the function is unchanged.
Its length is not modified so the new initialized data is not part of the
array. This is because when you pass an array to a function, it's that
small struct that is passedon the stack, so changing that will not change
the argument's properties.

eg.

  void func(int[] x)
  {
 x.length = x.length + 1;
  }
  int a[] = [1,2,3];
  func(a);
  writefln(%s, a) //-- [1,2,3] and not [1,2,3,0]

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell


Re: DMD Modifications

2009-05-21 Thread Daniel Keep

white_man wrote:
 Does it possible to modify DMD and publish it in that form. Of course with 
 full information about authors. Does it legal? 

It depends.  If you ONLY modify the front-end (front-end files are
identified as being licensed under GPL [1]), then you can distribute the
modified front-end.

However, if you modify the back end, you cannot redistribute those
files.  You also cannot distribute a compiled version.

To be safe, it's probably best to just distribute any changes you make
as a patch.

  -- Daniel


[1] There's another license involved, but I forget what it's called.


Re: any html parser with d binding

2009-05-21 Thread Christopher Wright

BCS wrote:

Hello reimi,


i have 2 question here:

1) can anyone suggest good html parser with d binding?



IIRC ANTLR can generate D


The last supported version was 2.7.something. It depends on phobos, 
possibly a rather old version of it (I don't know).


Re: DMD Modifications

2009-05-21 Thread Spacen Jasset

Daniel Keep wrote:

white_man wrote:
Does it possible to modify DMD and publish it in that form. Of course with full information about authors. Does it legal? 


It depends.  If you ONLY modify the front-end (front-end files are
identified as being licensed under GPL [1]), then you can distribute the
modified front-end.

However, if you modify the back end, you cannot redistribute those
files.  You also cannot distribute a compiled version.

To be safe, it's probably best to just distribute any changes you make
as a patch.

  -- Daniel


[1] There's another license involved, but I forget what it's called.
Presumably you can modify and distribute LDC (under the GPL terms if it 
is GPL. I forget)?


LDC = Front End + LLVM


Class allocation from tuple

2009-05-21 Thread bearophile
I have a tuple of classes (D1 language), I'd like to instantiate one of them 
directly with new, but it seems I can't:

template Tuple(T...) { alias T Tuple; }

class Foo { static void foo(){} }
class Bar {}
alias Tuple!(Foo, Bar) ClassTuple;

void main() {
alias ClassTuple[0] Foo0;
new Foo0; // OK

ClassTuple[0].foo(); // OK

new ClassTuple[0]; // Not OK
new (ClassTuple[0]); // Not OK
}

Can you tell me what the problem is?

Thank you and bye,
bearophile


Re: Class allocation from tuple

2009-05-21 Thread bearophile
Jarrett Billingsley:

 When it tries to parse
 the type following 'new', it interprets the brackets as meaning an
 array type,

I agree. But not even this works:
new (ClassTuple[0]);

Bye,
bearophile


Re: Class allocation from tuple

2009-05-21 Thread Jarrett Billingsley
On Thu, May 21, 2009 at 11:13 AM, bearophile bearophileh...@lycos.com wrote:
 Jarrett Billingsley:

 When it tries to parse
 the type following 'new', it interprets the brackets as meaning an
 array type,

 I agree. But not even this works:
 new (ClassTuple[0]);

 Bye,
 bearophile

Have you tried reading the errors?

dtest.d(187): basic type expected, not ;

It's parsing the parenthesized expression as an argument to new, then
wondering where your type is (like if you were doing new(blah)
ClassName()).


Re: Class allocation from tuple

2009-05-21 Thread Robert Fraser

bearophile wrote:

I have a tuple of classes (D1 language), I'd like to instantiate one of them 
directly with new, but it seems I can't:

template Tuple(T...) { alias T Tuple; }

class Foo { static void foo(){} }
class Bar {}
alias Tuple!(Foo, Bar) ClassTuple;

void main() {
alias ClassTuple[0] Foo0;
new Foo0; // OK

ClassTuple[0].foo(); // OK

new ClassTuple[0]; // Not OK
new (ClassTuple[0]); // Not OK
}

Can you tell me what the problem is?

Thank you and bye,
bearophile


alias


Theory question

2009-05-21 Thread BCS

Are there any cases where the following cases both compile but are not 
identical?

A a;
B b;

a = b;
a.Foo();

 and

A a;
B b;

a = b;
b.Foo();

The reason I ask is I'm wondering if making the type (and value) of an assignment 
expression the right hand side rather than the left hand side would silently 
break code. It would be handy for cases like this because it avoids the need 
for a temp variable:


class C { }
class D : C { int i();}

D newD();

C c;

void main()
{
  (c = newD()).i();
}




Determine if template argument is an array

2009-05-21 Thread Fractal
Hello

Any body can explan me how to determine if a template argument is an array?

Thanks


Re: Determine if template argument is an array

2009-05-21 Thread Fractal
Fractal Wrote:

 Hello
 
 Any body can explan me how to determine if a template argument is an array?

...And also if is an associative array

 Thanks


Re: Theory question

2009-05-21 Thread BCS

Reply to Frits,


BCS wrote:


Are there any cases where the following cases both compile but are
not identical?

A a;
B b;
a = b;
a.Foo();
 and

A a;
B b;
a = b;
b.Foo();

struct A {
int i;
void Foo() { i = 42; }
}
alias A B;

The first case will set a.i to 42, the second will set b.i.



I wasn't looking for side effect cases  but I guess that is correct.


And with opAssign + different struct types they'd be calling two
completely different Foo()s.



Oh, forgot opAssign (darn)


Then there's array types + global function Foo(ref A), union types
(similar to struct types), class types + static Foo()s (different ones
for A and B), ...



ok looks like to much of a mess to make it work




Re: Determine if template argument is an array

2009-05-21 Thread Christopher Wright

Fractal wrote:

Hello

Any body can explan me how to determine if a template argument is an array?

Thanks


Have a look at std.traits or tango.core.Traits. The appropriate way to 
check is via the templates they define, since it's clearer. Looking at 
the source will tell you how to replicate the effect should you need to.