# file      : tests/loop/for.testscript
# license   : MIT; see accompanying LICENSE file

# Test for-loop.

.include ../common.testscript

: line
:
$* <<EOI >>EOO
for i: 1 2 3
  print $i
EOI
1
2
3
EOO

: block
:
$* <<EOI >>EOO
for i: 1 2 3
{
  # This is a block if you haven't noticed.
  j = $i
  print $j
}
EOI
1
2
3
EOO

: flow-control
:
{{
  : continue
  :
  {{
    : basics
    :
    $* <<EOI >>EOO
    for i: 1 2
    {
      print 1 $i
      continue
      print 2 $i
    }
    print 3 $i
    EOI
    1 1
    1 2
    3 2
    EOO

    : attribute
    :
    $* <<EOI 2>>EOE != 0
    for i: 1 2
      [string] continue
    EOI
    <stdin>:2:3: error: attributes before continue
    EOE

    : trailing
    :
    $* <<EOI 2>>EOE != 0
    for i: 1 2
      continue junk
    EOI
    <stdin>:2:12: error: expected newline instead of 'junk'
    EOE

    : outside
    :
    $* <<EOI 2>>EOE != 0
    i = 2

    if ($i == 2)
      continue
    EOI
    <stdin>:4:3: error: continue outside loop
    EOE

    : skipped
    :
    $* <<EOI >>EOO
    i = 2

    if ($i == 2)
      i = 0
    else
      continue
    print $i
    EOI
    0
    EOO
  }}

  : break
  :
  {{
    : basics
    :
    $* <<EOI >>EOO
    for i: 1 2
    {
      print 1 $i
      break
      print 2 $i
    }
    print 3 $i
    EOI
    1 1
    3 1
    EOO

    : attribute
    :
    $* <<EOI 2>>EOE != 0
    for i: 1 2
      [string] break
    EOI
    <stdin>:2:3: error: attributes before break
    EOE

    : trailing
    :
    $* <<EOI 2>>EOE != 0
    for i: 1 2
      break junk
    EOI
    <stdin>:2:9: error: expected newline instead of 'junk'
    EOE

    : outside
    :
    $* <<EOI 2>>EOE != 0
    i = 2

    if ($i == 2)
      break
    EOI
    <stdin>:4:3: error: break outside loop
    EOE

    : skipped
    :
    $* <<EOI >>EOO
    i = 2

    if ($i == 2)
      i = 0
    else
      break
    print $i
    EOI
    0
    EOO
  }}

  : if
  :
  $* <<EOI >>EOO
  for i: 1 2 3 4 5
  {
    if ($i == 2)
      continue

    if ($i == 4)
      break

    print $i
  }
  EOI
  1
  3
  EOO

  : else
  :
  $* <<EOI >>EOO
  for i: 1 2 3 4 5
  {
    if ($i != 2)
    {
    }
    else
      continue

    if ($i != 4)
    {
    }
    else
      break

    print $i
  }
  EOI
  1
  3
  EOO

  : switch
  :
  $* <<EOI >>EOO
  for i: 1 2 3 4 5
  {
    switch $i
    {
      case 2
        continue

      default
        switch $i
        {
          case 4
            break
        }
    }

    print $i
  }
  EOI
  1
  3
  EOO

  : nesting
  :
  $* <<EOI >>EOO
  for i: 1 2
  {
    for j: 5 6 7 8 9
    {
      if ($j == 6)
        continue

      if ($j == 8)
        break

      print $i $j
    }
  }
  EOI
  1 5
  1 7
  2 5
  2 7
  EOO

  : directory-scope
  :
  {
    mkdir foo
    echo 'bar' >= bar

    cat <<EOI >=buildfile
    for i: 1 2 3 4
    {
      foo/
      {
        if ($i == 2)
          continue

        if ($i == 4)
          break

        for j: 5 6 7 8 9
        {
          if ($j == 6)
            continue

          if ($j == 8)
            break

          ../: file{baz-$i-$j}: ../bar
          {{
            cp $path($<) $path($>)
          }}
        }
      }
    }
    EOI

    test.options = $regex.filter_out_match($test.options, '--buildfile=.+')
    test.arguments =

    $* update

    for s: 1-5 1-7 3-5 3-7
      cat foo/baz-$s >bar

    $* clean
  }

  : source
  :
  {
    cat <<EOI >=foo
    if ($i == 2)
      continue

    if ($i == 4)
      break

    for j: 5 6 7 8 9
    {
      if ($j == 6)
        continue

      if ($j == 8)
        break

      print $i $j
    }
    EOI

    $* <<EOI >>EOO
    for i: 1 2 3 4
      source foo
    EOI
    1 5
    1 7
    3 5
    3 7
    EOO
  }

  : run
  :
  if ($cxx.target.class != 'windows')
  {
    cat <<EOI >=foo
    if ($i == 2)
      continue

    if ($i == 4)
      break

    for j: 5 6 7 8 9
    {
      if ($j == 6)
        continue

      if ($j == 8)
        break

      print $i $j
    }
    EOI

    $* <<EOI >>EOO
    for i: 1 2 3 4
      run cat foo
    EOI
    1 5
    1 7
    3 5
    3 7
    EOO
  }

  : include
  :
  {
    cat <<EOI >=foo
    for i: 1 2 3 4 5
    {
      if ($i == 2)
        continue

      if ($i == 4)
        break

      print $i
    }

    continue
    EOI

    $* <<EOI >>EOO 2>>EOE != 0
    for i: 1 2
      include foo
    EOI
    1
    3
    EOO
    foo:12:1: error: continue outside loop
    EOE
  }
}}

: empty
:
$* <<EOI
i = x
nums =
for i: $nums
  print $i
assert ($i == x)
EOI

: nested
:
$* <<EOI >>EOO
for i: 1 2 3
{
  for j: + -
  {
    print $j$i
  }
}
EOI
+1
-1
+2
-2
+3
-3
EOO

: diag-line
:
$* <<EOI 2>>EOE != 0
for i: true false
{
  assert $i
}
EOI
<stdin>:3:3: error: assertion failed
EOE

: var-attribute
:
$* <<EOI >>EOO
for [uint64] i: 0 1 2
{
  i += 1
  print $i
}
EOI
1
2
3
EOO

: val-attribute
:
$* <<EOI >>EOO
for i: [uint64s] 0 1 2
{
  i += 1
  print $i
}
EOI
1
2
3
EOO

: val-null
:
$* <<EOI
for i: [null]
  print $i
EOI

: pairs
:
$* <<EOI >>EOO
for i: a@1 b@2 c@3
  print $i
EOI
a@1
b@2
c@3
EOO

: elem-attribute
:
$* <<EOI >>EOO
for i [uint64]: 0 1 2
{
  i += 1
  print $i
}
EOI
1
2
3
EOO
