Уважаемый 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;
.
Надеюсь, что смог помочь.
С уважением, Алексей.