// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Tests of loops.

import 'package:expect/expect.dart';

fact(n) {
  var f = BigInt.one;
  while (n > 1) {
    f *= BigInt.from(n);
    --n;
  }
  return f;
}

fib(n) {
  if (n == 0) return 0;
  var previous = 0, current = 1;
  while (n > 1) {
    var temp = current;
    current += previous;
    previous = temp;
    --n;
  }
  return current;
}

mkTrue() => true;
mkFalse() => false;

check(b) {
  Expect.isTrue(b);
  return b;
}

test0() {
  while (mkTrue()) {
    Expect.isTrue(true);
    return;
  }
  Expect.isTrue(false);
}

test1() {
  while (mkFalse()) {
    Expect.isTrue(false);
  }
  Expect.isTrue(true);
}

test2() {
  do {
    Expect.isTrue(true);
  } while (mkFalse());
  Expect.isTrue(true);
}

test3() {
  do {
    Expect.isTrue(true);
    return;
  } while (check(false));
  Expect.isTrue(false);
}

main() {
  Expect.isTrue(fact(0) == BigInt.one);
  Expect.isTrue(fact(1) == BigInt.one);
  Expect.isTrue(fact(5) == BigInt.from(120));
  Expect.isTrue(fact(42) ==
      BigInt.parse("1405006117752879898543142606244511569936384000000000"));
  Expect.isTrue(fact(3.14159) == BigInt.from(6));

  Expect.isTrue(fib(0) == 0);
  Expect.isTrue(fib(1) == 1);
  Expect.isTrue(fib(2) == 1);
  Expect.isTrue(fib(3) == 2);
  Expect.isTrue(fib(4) == 3);
  Expect.isTrue(fib(5) == 5);
  Expect.isTrue(fib(6) == 8);
  Expect.isTrue(fib(7) == 13);
  Expect.isTrue(fib(42) == 267914296);
  Expect.isTrue(fib(3.14159) == 3);

  test0();
  test1();
  test2();
  test3();
}
