/**
    Experimenting with "conventional" func(call) syntax.
*/
if{'function' === (typename 1.0.toInt())}{
    $print "Conventional func(call) syntax is disabled." \
        "When using the demo/test shell, use the -c flag to enable it."
    return
}
print("Conventional func(call) syntax is enabled.")

//$print 'function' '===' typename 1.0.toInt()

1 && scope {
    var ok = false
    scope {
        var cache = object{}
        proc{}{
            assert cache
            ok = true
            assert ok
        }.importSymbols('cache', 'ok')
    }()
}

1 && scope {
    $print 1 2 3 4 5
    [print 1 2 3 4 5]
    print(1,2, 3, 4, 5)
    
    $print 1 2, print(3,4)
    ($print 1 2) print(3,4)
    [print 1 2] print(3,4)
    print(1, 2) print(3,4)

    var x = "hi"
    assert "hiho" === x.concat("ho")
    // seemingly unresolvable ambiguity:
    assert "hi123" === x.concat(1,2,3)
    // ===> $print (x.concat (1,2,3))
    //Doh:
    //$print (x.concat) (1,2,3) 
    // ===> $(print (x.concat)) (1,2,3)
    // ===> 3
    //$(print) (x.concat) (1,2,3) "?"
    // ==> $(print) ((x.concat) (1,2,3)) "?"

    $print x.concat (1,2,3)

    assert 'hiobjsubstr' ===
        object{sub:object{str: x}}.
            sub.str.concat ('obj','sub','str')
}


1 && scope {

    print ["HI".toLower].prototype
    assert "hi" === [["HI".toLower].toString]
    assert "hi" === "HI".toLower().toString()
    assert 'hi' === "HI".toString().toLower().toUpper().toLower()
}

1 && scope {
    /* Ensure that 'this' is translated properly when
       chaining method calls... */
    const ob2 = object{
        g:proc(){
            return this
        }
    }
    const obj = object {
        f:proc(){
            return this.g
        },
        g:proc(){
            print("G!", this);
            return this
        },
        h:proc(){
            return ob2
        }
    }

    //$print obj.f() obj.g
    assert obj.g === obj.f()
    assert obj.g === [obj.f]
    $print 'f =' obj.f ', g =' obj.g ', f() =' obj.f() ', g() =' obj.g()
    $print '[[obj.f]] =' [[obj.f]] ', f()() =' obj.f()()
    assert obj.g === [[obj.f]]
    assert obj === obj.g()
    assert ob2 === obj.h().g()

}

1 && scope {
    var obj = object{}
    assert 2009 === catch{obj.foo(undefined,2,null)}.code
    assert 2009 === catch{obj.foo ()}.code
    assert undefined === eval {obj.foo,()}
    // Ensure that short-circuting of func call arguments
    // DTRT...
    0 && $print this must not cause an error
    true ? 1 : $print(this must not cause an error)
}

var rc = "Done with ".concat(__FILE,'.')
print(rc)
return rc

