Уважаемый glupo.
Давайте попробуем разобраться:
Итак, в начальный момент времени Вы создаёте переменную 
Tree, поэтому при первом вызове процедуры 
AddLeaf переменная 
a заведомо не равна Nil, но при этом значение её полей не определено (вернее, зависит от компилятора: может быть "куча мусора" или все нули). Что уже приводит к нежелательным последствиям: как минимум, у Вас в выходном массиве будет на 1 элемент больше, если же компилятор не обнуляет вновь созданную переменную, то возможны как ошибки доступа, так и "вечные" циклы (одна случайная непустая область памяти даст ссылку на другую, которая ...).
Далее,
- Код: Выделить всё
- while y <> nil do begin
 if x^.data < y^.data then y := y^.left else y := y^.right;
 end;
в общем случае не работает. 
Представьте, что у Вас в некий момент времени в дереве хранятся 4 числа: 1, 2, 4, 5. Корень дерева — 2. А Вам нужно в дерево вставить число 3. 
Тогда: 3>2 => y=4, цикл не завершен, на следующем шаге 3<4 => y=2, цикл не завершен, повторять пока не надоест...
Но, даже если Вам повезло, и число нужно вставить в начало или конец дерева, Вы строкой
- Код: Выделить всё
- x := y;
 приравниваете 
x Nil, ведь, по условию, цикл завершается только при y=Nil.
Я тут вчерне набросал вариант решения:
- Код: Выделить всё
- procedure AddLeaf(var a : ptr; b : integer); {добавление эл-та}
 var
 p, x:Ptr;
 StepRight:Boolean;
 begin
 if a=nil then begin
 //    Writeln('First =', b);
 New(a);
 a^.Data:=b;
 a^.Left:=nil;
 a^.Right:=nil
 end else begin
 if a^.Data<b then StepRight:=True else StepRight:=False;
 p:=a;
 if StepRight then begin
 While p^.Data<b do begin
 //        writeln(p^.Data,' < ',b);
 if p^.Right=nil then begin
 StepRight:=not(StepRight);
 Break
 end else p:=p^.Right;
 end;
 end else begin
 While p^.Data>=b do begin
 //        writeln(p^.Data,' >= ',b);
 if p^.Left=nil then begin
 StepRight:=not(StepRight);
 Break
 end else p:=p^.Left;
 end;
 end;
 New(x);
 x^.Data:=b;
 if StepRight then begin
 x^.Left:=p^.Left;
 if p^.Left<>nil then p^.Left^.Right:=x;
 x^.Right:=p;
 p^.Left:=x
 end else begin
 x^.Right:=p^.Right;
 if p^.Right<>nil then p^.Right^.Left:=x;
 x^.Left:=p;
 p^.Right:=x
 end;
 {      Write('Вставим ', x^.Data, ' между ');
 if x^.Left=nil then Write ('Nil и ') else Write (x^.Left^.Data,' и ');
 if x^.Right=nil then WriteLn ('Nil') else WriteLn (x^.Right^.Data);}
 end;
 //  PrintTree(a)
 end;
.
Теперь о выводе дерева на экран: задумка несомненно красивая, однако, в том виде, который Вы предложили — гарантированно не работоспособная (дерево уже из 2 элементов будет распечатываться вечность, поскольку из процедуры печати первого будет вызвана процедура печати второго, из которой будут вызвана процедура печати первого, из которой...).
Рискну предложить такой вариант
- Код: Выделить всё
- procedure PrintTree(a : ptr); {обход дерева в обратном порядке}
 var
 x:ptr;
 begin
 x:=a;
 While x^.Left<>Nil do x:=x^.Left;
 while x<>Nil do begin
 if x=a then Write('[',x^.Data,'] ') else Write(x^.Data,' ');
 x:=x^.Right
 end;
 WriteLn
 end;
.
Надеюсь, что смог помочь.
С уважением, Алексей.