[print "Assertions in process..."]


scope {
    assert 42 === (catch {
      throw 21 *
    2
    }).message
    assert undefined === catch {}
    assert 17 === catch {throw 17}.message
    assert 19 === catch {toss 19}
    assert undefined === catch {17}
    assert "hi" === catch { toss "hi" }
}
scope {
    assert 17 === scope {return 17}
    assert 19 === scope {19}
    assert true === eval {true}
    assert undefined === eval {}
    assert "hi" === scope {1 3 6 "hi"}
    assert "hix" === scope {return "hix";}
    assert false === catch { eval{ toss false } }
    assert 77 === catch{scope{if(true){toss 70+7}}}
}

scope {
    /* some of these conversions are highly arguable... */
    /* And some were removed: we now do conventional
        string concatenation when the LHS of the operator
        is-a String. This behaviour can be DISABLED by
        unsetting "".prototype.'operator+'!
    */
    assert "3.00.1" === "3.0"+0.1 // string on the left!
    assert 3.7 === 0.7 + "3" // string on the right!
    assert 3.74 === 0.7 + "3" + "0.04" // int on the left!
    assert 3.1 === 3.1 + "abc" // "abc"==0
    assert 5 === +"5"
    assert -5 === -"5"
    assert -5 === -"5"
    assert -5 === +"-5"
    assert 5.1 === +"5.1"
    assert -5.1 === -"5.1"
    assert -5.1 === +"-5.1"
}

scope {
    /** Assignment operator sanity tests... */
    var a
    a = 7
    assert 21 === (a *= 3)
    assert 21 === a
    assert 10 === (a/=2)
    assert 10 === a
    assert 9 === (a-=1)
    assert 9 === a
    assert 2 === (a %= 7)
    assert 2 === a
    var b
    assert 1 === (a = b += 1)
    assert 1 === a
    assert 0 === (a /= 2)
    assert 'integer' === typename (a /= 2.0)
    assert 'integer' === typename (1.0 * a) // optimization of (1*anything)
    a += 5
    assert 'double' === typename (1.1 * a)
    assert 'CWAL_RC_TYPE' === [catch{a*=1/=2}.codeString]

    a = 1
    assert 2 === (a <<= 1)
    assert 8 === (a <<= 2)
    assert 9 === (a |= 0x01)
    assert 8 === (a &= 0xFE)
    assert 4 === (a >>= 1)
    assert 0xf4 === (a |= 0xF4)
    assert 0x04 === (a &= 0x0F)
    assert 0x04 == a

    0 && throw "one" || throw "two" /*
        unconventional/broken precedence, doesn't throw, but instead
        short-circuits as far as it can (to the EOL).
    */

    unset a, b
    assert 'undefined' === typename b

    var ob
    ob = object{a:object{b:7}}
    assert 21 === (ob.a.b *= 3)
    assert 21 === ob.a.b
    assert 10 === (ob.a.b/=2)
    assert 10 === ob.a.b
    assert 9 === (ob.a.b-=1)
    assert 9 === ob.a.b
    assert 2 === (ob.a.b %= 7)
    assert 2 === ob.a.b

    assert 'CWAL_SCR_DIV_BY_ZERO' === [catch {ob.a.b/=0.0}.codeString]
    const x = 1
    assert 'CWAL_RC_ACCESS' === [catch {x+=1}.codeString]
}

scope {
    /**
        Be aware that the operator precedence is
        "not quite conventional" for (|, &, <<, >>)
        and combining them without parens grouping might
        surprise you. (2<<2|1) === 16 instead of the
        expected 9 because it evaluates as (2<<(2|1)).

        Fixing that is going to require me gutting doing
        a minor overhaul of the evaluation engine to accommodate
        more precedence granularity.
    */
    assert 1 === (1<<0)
    assert 2 === (1<<1)
    assert 8 === (0x10>>1)
    assert 0xF0 === (0x0f<<4)

    assert !(~0xf0 & 0xf0)
    assert 0x0f == (~0xf0 & 0x0F)
}


scope {
    assert 'CWAL_SCR_DIV_BY_ZERO' === [catch{3/0.0}.codeString]
}

scope {
    true || throw "oh noez"
    false && throw "oh noez"
}



return {end of script #3}
throw "NOT REACHED"
