$print "Assertions in progress..."

1 && scope {
    set bDefault 12
    set a proc {a, b = bDefault, c = 7} {
        $print "a =" a "| b =" b "| c =" c
        //scope { return a }
        //if {1} { return a }
        return a
        //throw "NOT REACHED"
        //$print "d =" d
    }

    assert 'function' === typename a

    //$print 'a:' typename a a
    //$(1+2, 8%3, print) 'a:' typename a a

    assert 3 === (false || [a 3])

    set bDefault "(B)"
    [a]
    set bDefault "(X)"
    assert 3 === [a 3]
    //$print 1 2 [a 1]
    assert [a 7 8 9 10 11] === 7
}

1 && scope {
    var toInt proc {v} { return v % (v+1) }
    assert 3 === [toInt 3.99]
    assert 3 === [toInt 3.01]
}

1 && scope {
    var defaultB 0
    var sum = proc {a, b = defaultB} { return a + b }
    assert 3 === $sum 3
    set defaultB 2
    assert 5 === $sum 3
}


1 && scope {
    /* Ensure that function calls honor short-circuit mode... */
    var f proc {} {
        throw "NOT REACHED"
    }
    assert false ? [f] : true;
    assert false ? f 1 2 3; : true
    assert true ? true : [f]
    assert true ? true : $f 1 2 3
    assert "NOT REACHED" === catch{[f]}.message
}


1 && scope {
    var ifcheck proc {v} {
        if {v < 0} { return -1 }
        else if {v > 0} { return 1 }
        else { return 0 }
        throw "NOT REACHED"
    }
    [ifcheck 1]
    $print "ifcheck 0 ==" [ifcheck 0]
    assert 0 === $ifcheck 0
    assert -1 === $ifcheck -2
    assert 1 === $ifcheck 3
}

set sum proc {a,b} { return a + b }
1 && scope {
    //$print 'sum =' sum
    assert 4 === $sum 1 3
}
assert 8 === [sum 3 5]

if {var z = 8; z===6} {
    $print "From an IF z =" z
} else if {7===z} {
    $print "From an IF/ELSE z =" z
} else {
    $print "From an ELSE z =" z
}
assert 'undefined' === typename z

1 && scope {
    set a "foo"
    set (1+2,"a") "bar"
    assert "bar" === a
    set a catch { set 3+3 = 7 }
    assert 'exception' === typename a
    $print "caught expected error: " a
}


1 && scope {
    /**
        Malloc count potentially _explodes_ here,
        mostly from evaluating the identifiers (strings).
        Turn on string interning _drastically_ cuts
        the number of mallocs (making them flat, regardless
        of the max loop count.
    */
    var max 1000*4
    var rc scope {
        $print "Trying WHILE loop..."
        var i = 0
        while {true} {
            set i = i + 1
            if {i < max} { continue }
            //else if {i === max} { return max }
            if {i === max} { break }
        }
        $print "Done WHILE looping. i =" i
        return i
    }
    $print 'rc =' rc
    assert max === rc
    $print "After while loop test."
}

1 && scope {
    $print "Starting FOR loop(s)..."
    var i = 0
    var max 500*4
    for {} {i<max} {set i i+1} {
        assert i < max
        continue
        throw "not reached!"
    }
    $print "... done with FOR loop. iterations =" i
    set i 0
    set p1 proc {a} { return a+1 }
    for {} {true} {} {
        if {i===max} {break}
        //set i [p1 i]
        set i i + 1
        continue
        throw "not reached!"
    }
    $print "... done with FOR loop. iterations =" i
}


1 && scope { /* BREAK with value... */

    var i = 0, max = 10
    var z = while{i<max}{
        scope {if((i += 1) > 3){
            break "broke"
        }}
    }
    assert {broke} === z

    z = for{i=0}{i<max}{i+=1}{
        if((i += 1) > 4){
            scope { break "breaked" }
        }
    }
    assert {breaked} === z

    z = for{i=0}{i<max}{i+=1}{
        if((i += 1) > 4){
            break
        }
    }
    assert undefined === z
}

1 && scope { /* do{}while{} */
  var i = 3, n = 0

  var rc = do{
   i -= 1
   n += 1
  }{i > 0}
  assert 0 === i
  assert 3 === n

  rc = do{i += 1; n -= 1; n || break i} while{true}
  assert 3 === rc
}

scope {
  var f3=proc(){0 && print('from',@argv,'f3'); return argv.callee}
  var f2=proc(){0 && print('from',@argv,'f2'); return f3}
  var o = object{f:proc(){0 && print('from',@argv,'f1'); return f2}}
  assert f3 === o.f(123)(234)(345)
}

return {end of script #5}
