# file      : libbuild2/build/script/parser+if.test.testscript
# license   : MIT; see accompanying LICENSE file

: if
:
{{
  : true
  :
  $* <<EOI >>EOO
  if true foo
  {
    cmd1
    cmd2
  }
  EOI
  ? true foo
  cmd1
  cmd2
  EOO

  : false
  :
  $* <<EOI >>EOO
  if false foo
  {
    cmd1
    cmd2
  }
  EOI
  ? false foo
  EOO

  : not-true
  :
  $* <<EOI >>EOO
  if! true foo
  {
    cmd1
    cmd2
  }
  EOI
  ? true foo
  EOO

  : not-false
  :
  $* <<EOI >>EOO
  if! false foo
  {
    cmd1
    cmd2
  }
  EOI
  ? false foo
  cmd1
  cmd2
  EOO

  : end
  :
  $* <<EOI 2>>EOE != 0
  if true
    cmd
  end
  EOI
  buildfile:13:1: error: flow-control constructs use {} in syntax version 2
  EOE

  : without-command
  :
  $* <<EOI 2>>EOE != 0
  if
    cmd
  EOI
  buildfile:11:3: error: missing program
  EOE
}}

: elif
:
{{
  : true
  :
  $* <<EOI >>EOO
  if false
  {
    cmd1
    cmd2
  }
  elif true
  {
    cmd3
    cmd4
  }
  EOI
  ? false
  ? true
  cmd3
  cmd4
  EOO

  : false
  :
  $* <<EOI >>EOO
  if false
  {
    cmd1
    cmd2
  }
  elif false
  {
    cmd3
    cmd4
  }
  EOI
  ? false
  ? false
  EOO

  : not-true
  :
  $* <<EOI >>EOO
  if false
  {
    cmd1
    cmd2
  }
  elif! true
  {
    cmd3
    cmd4
  }
  EOI
  ? false
  ? true
  EOO

  : not-false
  :
  $* <<EOI >>EOO
  if false
  {
    cmd1
    cmd2
  }
  elif! false
  {
    cmd3
    cmd4
  }
  EOI
  ? false
  ? false
  cmd3
  cmd4
  EOO

  : without-if
  :
  $* <<EOI 2>>EOE != 0
  cmd
  elif true
    cmd
  EOI
  buildfile:12:1: error: 'elif' without preceding 'if'
  EOE

  : not-without-if
  :
  $* <<EOI 2>>EOE != 0
  cmd
  elif! true
    cmd
  EOI
  buildfile:12:1: error: 'elif!' without preceding 'if'
  EOE

  : after-else
  :
  $* <<EOI 2>>EOE != 0
  if false
    cmd
  else
    cmd
  elif true
    cmd
  EOI
  buildfile:15:1: error: 'elif' after 'else'
  EOE
}}

: else
:
{{
  : true
  :
  $* <<EOI >>EOO
  if false
  {
    cmd1
    cmd2
  }
  else
  {
    cmd3
    cmd4
  }
  EOI
  ? false
  cmd3
  cmd4
  EOO

  : false
  :
  $* <<EOI >>EOO
  if true
  {
    cmd1
    cmd2
  }
  else
  {
    cmd3
    cmd4
  }
  EOI
  ? true
  cmd1
  cmd2
  EOO

  : chain
  :
  $* <<EOI >>EOO
  if false
  {
    cmd
    cmd
  }
  elif false
  {
    cmd
    cmd
  }
  elif false
  {
    cmd
    cmd
  }
  elif true
  {
    cmd1
    cmd2
  }
  elif false
  {
    cmd
    cmd
  }
  else
  {
    cmd
    cmd
  }
  EOI
  ? false
  ? false
  ? false
  ? true
  cmd1
  cmd2
  EOO

  : command-after
  :
  $* <<EOI 2>>EOE != 0
  if true
    cmd
  else cmd
    cmd
  EOI
  buildfile:13:6: error: expected newline instead of 'cmd'
  EOE

  : without-if
  :
  $* <<EOI 2>>EOE != 0
  cmd
  else
    cmd
  EOI
  buildfile:12:1: error: 'else' without preceding 'if'
  EOE

  : after-else
  :
  $* <<EOI 2>>EOE != 0
  if false
    cmd
  else
    cmd
  else
    cmd
  EOI
  buildfile:15:1: error: 'else' after 'else'
  EOE
}}

: if-predicate
:
{{
  : ifn
  :
  {{
    : null
    :
    $* <<EOI >>EOO
    ifn $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd1
    cmd2
    EOO

    : not-null
    :
    $* <<EOI >>EOO
    foo =
    ifn $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd3
    cmd4
    EOO

    : end
    :
    $* <<EOI 2>>EOE != 0
    ifn foo
      cmd
    end
    EOI
    buildfile:13:1: error: flow-control constructs use {} in syntax version 2
    EOE

    : without-value
    :
    $* <<EOI 2>>EOE != 0
    ifn
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    buildfile:11:4: error: expected value after 'ifn'
    EOE
  }}

  : elifn
  :
  {{
    : null
    :
    $* <<EOI >>EOO
    ifn foo
    {
      cmd1
      cmd2
    }
    elifn $foo
    {
      cmd3
      cmd4
    }
    EOI
    cmd3
    cmd4
    EOO

    : not-null
    :
    $* <<EOI
    foo =
    ifn foo
    {
      cmd1
      cmd2
    }
    elifn $foo
    {
      cmd3
      cmd4
    }
    EOI

    : without-if
    :
    $* <<EOI 2>>EOE != 0
    cmd
    elifn foo
      cmd
    EOI
    buildfile:12:1: error: 'elifn' without preceding 'if'
    EOE

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    ifn foo
      cmd
    else
      cmd
    elifn bar
      cmd
    EOI
    buildfile:15:1: error: 'elifn' after 'else'
    EOE
  }}

  : ifnn
  :
  {{
    : null
    :
    $* <<EOI >>EOO
    ifn! $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd3
    cmd4
    EOO

    : not-null
    :
    $* <<EOI >>EOO
    foo =
    ifn! $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd1
    cmd2
    EOO
  }}

  : elifnn
  :
  {{
    : null
    :
    $* <<EOI
    ifn foo
    {
      cmd1
      cmd2
    }
    elifn! $foo
    {
      cmd3
      cmd4
    }
    EOI

    : not-null
    :
    $* <<EOI >>EOO
    foo =
    ifn foo
    {
      cmd1
      cmd2
    }
    elifn! $foo
    {
      cmd3
      cmd4
    }
    EOI
    cmd3
    cmd4
    EOO
  }}

  : ife
  :
  {{
    : empty
    :
    $* <<EOI >>EOO
    foo =
    ife $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd1
    cmd2
    EOO

    : empty-string
    :
    $* <<EOI >>EOO
    foo = [string] ''
    ife $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd1
    cmd2
    EOO

    : not-empty
    :
    $* <<EOI >>EOO
    foo = 'abc'
    ife $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd3
    cmd4
    EOO

    : end
    :
    $* <<EOI 2>>EOE != 0
    ife foo
      cmd
    end
    EOI
    buildfile:13:1: error: flow-control constructs use {} in syntax version 2
    EOE

    : without-value
    :
    $* <<EOI 2>>EOE != 0
    ife
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    buildfile:11:4: error: expected value after 'ife'
    EOE
  }}

  : elife
  :
  {{
    : empty
    :
    $* <<EOI >>EOO
    foo =
    ife foo
    {
      cmd1
      cmd2
    }
    elife $foo
    {
      cmd3
      cmd4
    }
    EOI
    cmd3
    cmd4
    EOO

    : not-empty
    :
    $* <<EOI
    foo = 'abc'
    ife foo
    {
      cmd1
      cmd2
    }
    elife $foo
    {
      cmd3
      cmd4
    }
    EOI

    : without-if
    :
    $* <<EOI 2>>EOE != 0
    cmd
    elife foo
      cmd
    EOI
    buildfile:12:1: error: 'elife' without preceding 'if'
    EOE

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    ife foo
      cmd
    else
      cmd
    elife bar
      cmd
    EOI
    buildfile:15:1: error: 'elife' after 'else'
    EOE
  }}

  : ifen
  :
  {{
    : empty
    :
    $* <<EOI >>EOO
    foo =
    ife! $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd3
    cmd4
    EOO

    : not-empty
    :
    $* <<EOI >>EOO
    foo = 'abc'
    ife! $foo
    {
      cmd1
      cmd2
    }
    else
    {
      cmd3
      cmd4
    }
    EOI
    cmd1
    cmd2
    EOO
  }}

  : elifen
  :
  {{
    : empty
    :
    $* <<EOI
    foo =
    ife foo
    {
      cmd1
      cmd2
    }
    elife! $foo
    {
      cmd3
      cmd4
    }
    EOI

    : not-empty
    :
    $* <<EOI >>EOO
    foo = 'abc'
    ife foo
    {
      cmd1
      cmd2
    }
    elife! $foo
    {
      cmd3
      cmd4
    }
    EOI
    cmd3
    cmd4
    EOO
  }}
}}

: rcbrace
:
{{
  : without-if
  :
  $* <<EOI 2>>EOE != 0
  cmd
  }
  EOI
  buildfile:12:1: error: expected command instead of '}'
  EOE

  : before
  {{
    : command
    :
    $* <<EOI 2>>EOE != 0
    if true
    {
      cmd
    } cmd
    EOI
    buildfile:14:3: error: expected newline after '}'
    EOE
  }}
}}

: lcbrace
:
$* <<EOI 2>>EOE != 0
cmd
{
EOI
buildfile:12:1: error: expected command instead of '{'
EOE

: nested
:
{{
  : take
  :
  $* <<EOI >>EOO
  if true
  {
    cmd1
    if false
      cmd
    elif false
    {
      if true
        cmd
    }
    else
      cmd2
    cmd3
  }
  EOI
  ? true
  cmd1
  ? false
  ? false
  cmd2
  cmd3
  EOO

  : skip
  :
  $* <<EOI >>EOO
  if false
  {
    cmd1
    if false
      cmd
    elif false
    {
      if true
        cmd
    }
    else
      cmd2
    cmd3
  }
  else
    cmd
  EOI
  ? false
  cmd
  EOO
}}

: contained
:
{{
  : eos
  :
  $* <<EOI 2>>EOE != 0
  if
  EOI
  buildfile:12:1: error: expected command instead of <end of file>
  EOE
}}

: line-index
:
$* -l <<EOI >>EOO
if false
{
  cmd
  if true
    cmd
  cmd
}
elif false
  cmd
else
  cmd
EOI
? false # 1
? false # 6
cmd # 8
EOO

: var
:
$* <<EOI >>EOO
if true
  x = foo
else
  x = bar
cmd $x
EOI
? true
cmd foo
EOO

: syntax-1
:
{{
  test.options += -v 1

  : if
  :
  {{
    : true
    :
    $* <<EOI >>EOO
    if true foo
      cmd1
      cmd2
    end
    EOI
    ? true foo
    cmd1
    cmd2
    EOO

    : false
    :
    $* <<EOI >>EOO
    if false foo
      cmd1
      cmd2
    end
    EOI
    ? false foo
    EOO

    : not-true
    :
    $* <<EOI >>EOO
    if! true foo
      cmd1
      cmd2
    end
    EOI
    ? true foo
    EOO

    : not-false
    :
    $* <<EOI >>EOO
    if! false foo
      cmd1
      cmd2
    end
    EOI
    ? false foo
    cmd1
    cmd2
    EOO

    : without-command
    :
    $* <<EOI 2>>EOE != 0
    if
      cmd
    end
    EOI
    buildfile:11:3: error: missing program
    EOE
  }}

  : elif
  :
  {{
    : true
    :
    $* <<EOI >>EOO
    if false
      cmd1
      cmd2
    elif true
      cmd3
      cmd4
    end
    EOI
    ? false
    ? true
    cmd3
    cmd4
    EOO

    : false
    :
    $* <<EOI >>EOO
    if false
      cmd1
      cmd2
    elif false
      cmd3
      cmd4
    end
    EOI
    ? false
    ? false
    EOO

    : not-true
    :
    $* <<EOI >>EOO
    if false
      cmd1
      cmd2
    elif! true
      cmd3
      cmd4
    end
    EOI
    ? false
    ? true
    EOO

    : not-false
    :
    $* <<EOI >>EOO
    if false
      cmd1
      cmd2
    elif! false
      cmd3
      cmd4
    end
    EOI
    ? false
    ? false
    cmd3
    cmd4
    EOO

    : without-if
    :
    $* <<EOI 2>>EOE != 0
    cmd
    elif true
      cmd
    end
    EOI
    buildfile:12:1: error: 'elif' without preceding 'if'
    EOE

    : not-without-if
    :
    $* <<EOI 2>>EOE != 0
    cmd
    elif! true
      cmd
    end
    EOI
    buildfile:12:1: error: 'elif!' without preceding 'if'
    EOE

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    if false
      cmd
    else
      cmd
    elif true
      cmd
    end
    EOI
    buildfile:15:1: error: 'elif' after 'else'
    EOE
  }}

  : else
  :
  {{
    : true
    :
    $* <<EOI >>EOO
    if false
      cmd1
      cmd2
    else
      cmd3
      cmd4
    end
    EOI
    ? false
    cmd3
    cmd4
    EOO

    : false
    :
    $* <<EOI >>EOO
    if true
      cmd1
      cmd2
    else
      cmd3
      cmd4
    end
    EOI
    ? true
    cmd1
    cmd2
    EOO

    : chain
    :
    $* <<EOI >>EOO
    if false
      cmd
      cmd
    elif false
      cmd
      cmd
    elif false
      cmd
      cmd
    elif true
      cmd1
      cmd2
    elif false
      cmd
      cmd
    else
      cmd
      cmd
    end
    EOI
    ? false
    ? false
    ? false
    ? true
    cmd1
    cmd2
    EOO

    : command-after
    :
    $* <<EOI 2>>EOE != 0
    if true
      cmd
    else cmd
      cmd
    end
    EOI
    buildfile:13:6: error: expected newline instead of 'cmd'
    EOE

    : without-if
    :
    $* <<EOI 2>>EOE != 0
    cmd
    else
      cmd
    end
    EOI
    buildfile:12:1: error: 'else' without preceding 'if'
    EOE

    : after-else
    :
    $* <<EOI 2>>EOE != 0
    if false
      cmd
    else
      cmd
    else
      cmd
    end
    EOI
    buildfile:15:1: error: 'else' after 'else'
    EOE
  }}

  : end
  {{
    : without-if
    :
    $* <<EOI 2>>EOE != 0
    cmd
    end
    EOI
    buildfile:12:1: error: 'end' without preceding 'if', 'for', or 'while'
    EOE

    : before
    {{
      : command
      :
      $* <<EOI 2>>EOE != 0
      if true
        cmd
      end cmd
      EOI
      buildfile:13:5: error: expected newline instead of 'cmd'
      EOE
    }}
  }}

  : nested
  :
  {{
    : take
    :
    $* <<EOI >>EOO
    if true
      cmd1
      if false
        cmd
      elif false
        if true
          cmd
        end
      else
        cmd2
      end
      cmd3
    end
    EOI
    ? true
    cmd1
    ? false
    ? false
    cmd2
    cmd3
    EOO

    : skip
    :
    $* <<EOI >>EOO
    if false
      cmd1
      if false
        cmd
      elif false
        if true
          cmd
        end
      else
        cmd2
      end
      cmd3
    else
      cmd
    end
    EOI
    ? false
    cmd
    EOO
  }}

  : contained
  :
  {{
    : eos
    :
    $* <<EOI 2>>EOE != 0
    if
    EOI
    buildfile:12:1: error: expected closing 'end'
    EOE
  }}

  : line-index
  :
  $* -l <<EOI >>EOO
  if false
    cmd
    if true
      cmd
    end
    cmd
  elif false
    cmd
  else
    cmd
  end
  EOI
  ? false # 1
  ? false # 6
  cmd # 8
  EOO

  : var
  :
  $* <<EOI >>EOO
  if true
    x = foo
  else
    x = bar
  end
  cmd $x
  EOI
  ? true
  cmd foo
  EOO
}}
