write('Testing stack ...\n\n');
t := time();

oldstack := stack.selected();

defaultslots := 128;

to 1 do

   stack.resetd();

   pushd(1, 2, 3);

   if cell(-1) <> 3 or cell(-2) <> 2 or cell(-3) <> 1 or cell(-4) <> null or cell(3) <> null then
      print('Error, pushd')
   fi;

   if popd() <> 3 or popd() <> 2 or popd() <> 1 then
      print('Error, pushd, 1')
   fi;

   pushd(1, 2, 3);

   if popd(3) <> 1 then
      print('Error, popd, 2')
   fi;

   if allotted() <> null then
      print('Error, allotted, 1')
   fi;

   a, b := stack.sized();

   if a <> 0 or b <> defaultslots then
      print('Error, stacks.sized, 1')
   fi;

   pushd(1, 2, 3);
   stack.resetd();
   if allotted() <> null then
      print('Error, allotted, 2')
   fi;

   if stack.dumpd() <> null then
      print('Error, dumpd, 1')
   fi;

   pushd(1, 2, 3);
   if stack.dumpd() <> seq(1, 2, 3) then
      print('Error, dumpd, 2')
   fi;
   if allotted() <> null then
      print('Error, allotted, 3')
   fi;

   pushd(1, 2, 3);
   stack.insertd(-1, 4);

   if cell(-1) <> 3 or cell(-2) <> 4 or cell(-3) <> 2 or cell(-4) <> 1 then
      print('Error, insertd, 1')
   fi;

   stack.resetd();
   pushd(1, 2, 3);
   stack.rotated(3);
   if cell(-1) <> 3 or cell(-2) <> 2 or cell(-3) <> 1 then
      print('Error, rotated, 1')
   fi;

   stack.reversed();
   if cell(-1) <> 1 or cell(-2) <> 2 or cell(-3) <> 3 then
      print('Error, reversed, 1')
   fi;

   stack.pushvalued(-2);
   if cell(-1) <> 2 then
      print('Error, pushvalued, 1')
   fi;

   if popd() <> 2 then
      print('Error, popd, 3')
   fi;

   stack.removed(-2);
   if cell(-1) <> 1 or cell(-2) <> 3 then
      print('Error, removed, 1')
   fi;

   stack.resetd()
   pushd(seq(1, 2, 3, 4, 5, 6, 7));
   stack.reversed(4);
   if stack.dumpd(4) <> seq(7, 6, 5, 4) then
      print('Error, reversed, 2')
   fi

od;

to 1024 do
   pushd(1)
od;
stack.resetd();
stack.shrinkd();
a, b := stack.sized();
if b <> defaultslots then
   print('Error, shrinkd')
fi;

stack.resetd();

to 100 do
   local a;
   for i to 100 do
      pushd(i);
      a := cell(-1);
      switchd(2);
      pushd(i);
      a := cell(-1);
      switchd(1)
   od;
   stack.resetd(1);
   stack.resetd(2)
od;

stack2 := 'stack' : 2;

to 100 do
   for i to 100 do
      pushd(i);
      pushd(i, stack2);
   od;
   stack.resetd(1);
   stack.resetd(2)
od;


switchd(4);

stack.resetd();

pushd(seq('a', 'b', 'c'));

if cell(-1) <> 'c' then
   print('Error in cell, 1')
fi;

if cell(-2) <> 'b' then
   print('Error in cell, 2')
fi;

if cell(-3) <> 'a' then
   print('Error in cell, 3')
fi;

if cell(-4) <> null then
   print('Error in cell, 4')
fi;

pushd('d', 'e', 'f');

if cell(-1) <> 'f' then
   print('Error in cell, 5')
fi;

if cell(-2) <> 'e' then
   print('Error in cell, 6')
fi;

if cell(-3) <> 'd' then
   print('Error in cell, 7')
fi;

if cell(-4) <> 'c' then
   print('Error in cell, 8')
fi;

if popd() <> 'f' then
   print('Error in popd, 1')
fi;

if popd() <> 'e' then
   print('Error in popd, 2')
fi;

if popd() <> 'd' then
   print('Error in popd, 3')
fi;

if popd() <> 'c' then
   print('Error in popd, 4')
fi;

if popd() <> 'b' then
   print('Error in popd, 5')
fi;

if popd() <> 'a' then
   print('Error in popd, 6')
fi;

if popd() <> null then
   print('Error in popd, 7')
fi;

switchd(4)

pushd('a', 'b', 'c')

if popd(3) <> 'a' then
   print('Error in popd, 8')
fi;

if allotted() <> null then
   print('Error in allotted, 1')
fi;

pushd('a', 'b', 'c')

if allotted() <> 3 then
   print('Error in allotted, 2')
fi;

popd(3);

switchd 4

stack.pushstringd(strings.repeat('0', defaultslots))

if stack.explored() <> strings.repeat('0', defaultslots) then
   print('Error in stack.explored, 1')
fi

if size stack.explored() <> defaultslots then
   print('Error in stack.explored, 2')
fi;

if stack.replaced(0, 1) <> '0' then
   print('Error in stack.replaced, 1')
fi;

if stack.explored() <> '1' & strings.repeat('0', 127) then
   print('Error in stack.replaced, 2')
fi;

if stack.replaced(-1, 1) <> '0' then
   print('Error in stack.replaced, 3')
fi;

if stack.replaced(-2, 2) <> '0' then
   print('Error in stack.replaced, 4')
fi;

if stack.explored() <> '1' & strings.repeat('0', 125) & '21' then
   print('Error in stack.replaced, 5')
fi;

if stack.dumpd() <> '1' & strings.repeat('0', 125) & '21' then
   print('Error in stack.dumpd, 1')
fi;

str := 'Die Würde des Menschen ist unantastbar.';
stack.pushstringd(str);
if stack.dumpd() <> str then
   print('Error in stack.pushstringd/stack.dumpd, 1')
fi;

pushd('a', 'b');
stack.swapd(0, 1);
if stack.explored() <> 'ba' then
   print('Error in stack.swapd, 1')
fi;

stack.swapd(-2, -1);
if stack.explored() <> 'ab' then
   print('Error in stack.swapd, 2')
fi;

stack.insertd(0, 'z');
if allotted() <> 3 then
   print('Error in stack.insertd, 1')
fi;

if stack.explored() <> 'zab' then
   print('Error in stack.insertd, 2')
fi;

stack.removed(-3);
if stack.explored() <> 'ab' then
   print('Error in stack.removed, 1')
fi;

stack.removed(1);
if stack.explored() <> 'a' then
   print('Error in stack.removed, 2')
fi;

str := 'Die Würde des Menschen ist unantastbar.';

for i from 4 to 6 do
   switchd i;
   stack.resetd();
   n := int(defaultslots/size str + 1);
   to n do
      stack.pushstringd(str);
   od;
   if stack.dumpd() <> strings.repeat(str, n) then
      print('Error in stack.pushstringd, 2')
   fi;

   a, b := stack.sized();
   if a <> 0 or b <> 256 then
      print('Error with internal memory management, 1')
   fi;

   stack.shrinkd();
   a, b := stack.sized();
   if a <> 0 or b <> defaultslots then
      print('Error with internal memory management, 2')
   fi
od;

switchd 4
pushd 1
stack.pushvalued(0);
if stack.dumpd() <> '11' then
   print('Error in stack.pushvalued, 1')
fi;


writeline('\nDone in ' & time()-t & ' seconds');

switchd oldstack;

clear a, b, defaultslots, n, stack2, str, oldstack;
