/** AWK~plus: predef for Java.
 */
import plus.BiBase
import plus.BiIO
import plus.concurrent.AtomicArray
import plus.concurrent.AtomicMap
import plus.concurrent.AtomicNumber
import plus.runtime.RunHelper
import plus.util.NumHelper
# ------------------------------------------------------------------------
# Built-in arithmetic Functions.
# ------------------------------------------------------------------------
function abs(x: Number): Number { return BiBase.abs(x) }
function atan2(x: Number, y: Number): Number { return BiBase.atan2(x, y) }
function cos(x: Number): Number { return BiBase.cos(x) }
function exp(x: Number): Number { return BiBase.exp(x) }
function log(x: Number): Number { return BiBase.log(x) }
function sin(x: Number): Number { return BiBase.sin(x) }
function sqrt(x: Number): Number { return BiBase.sqrt(x) }
function rand(): Number { return BiBase.rand() }
function srand(x: Number*): Number { return BiBase.srand(x) }
# ------------------------------------------------------------------------
# String Functions.
# ------------------------------------------------------------------------
function asort(a: Map*): int { return BiBase.asort(a) }
function asorti(a: Map*): int { return BiBase.asorti(a) }
function index(s: String, t: String): int { return RunHelper.indexOf(s, t) }
function length(x: Object*): int { return BiBase.length(x) }
function match(s: String, r: String): int { return BiBase.match(s, r) }
function split(x: Object*): int { return BiBase.split(x) }
function strtonum(s: String): Number { return NumHelper.parseNumber(s) }
function substr(s: String, i: int, n: int): String { return RunHelper.substr(s, i, n) }
function tolower(s: String): String { return s.toLowerCase() }
function toupper(s: String): String { return s.toUpperCase() }
function disableEscape(x: Object): Object { return BiIO.disableEscape(x) }
# ------------------------------------------------------------------------
# I/O Functions.
# ------------------------------------------------------------------------
function close(x: Object*): Void { return BiIO.close(x) }
function fflush(x: Object*): Void { return BiIO.fflush(x) }
function sprintf(x: Object*): String { return BiIO._sprintf(x) }
# ------------------------------------------------------------------------
# System Functions.
# ------------------------------------------------------------------------
function system(s: String): int { return BiBase.system(s) }
# ------------------------------------------------------------------------
# Timestamp Functions.
# ------------------------------------------------------------------------
function systime(): double { return BiBase.systime() }
# 日付時刻を表す文字列をタイムスタンプに変換して返す
function mktime(s: String): double {
    try { return 0.001 * java.text.DateFormat.getDateTimeInstance().parse(s).getTime()
    } catch (java.text.ParseException e) { return -1 }
}
# strftime([ format [ , timestamp ] ]) 日付時刻を表す文字表現を返す
function strftime(x: Object*): String {
    return BiBase.strftime(x)
}
# ------------------------------------------------------------------------
# Concurrent Future Functions.
# ------------------------------------------------------------------------
function Barrier(x: int): Object { return new java.util.concurrent.CyclicBarrier(x) }
function Future(x: Function): Object {
    val e = new java.util.concurrent.FutureTask(x)
    new java.lang.Thread(e).start()
    # Lambda; wait by the analysis completion of the expression
    plus.concurrent.Futures.await(x.toString())
    return e
}
function Cancel(x: Object): Boolean { return plus.concurrent.Futures.cancel(x) }
function Join(x: Object): Boolean { return plus.concurrent.Futures.join(x) }
function isAlive(x: Object): Boolean { return plus.concurrent.Futures.isAlive(x) }
# ------------------------------------------------------------------------
# Concurrent Util Functions.
# ------------------------------------------------------------------------
function Channel(): Object { return new plus.concurrent.SimpleQueue }
function Range(start: int, end: int, step: int*): Object {
    return new plus.concurrent.Range(start, end, 0 in step ? step[0]: 0 > end - start ? -1: 1)
}
function Sleep(second: Number): Boolean { return RunHelper.sleep(second) }
