utils = FFI clone("utils", """
def tobin(x):
    return bin(int(x))

def tobool(x):
    return bool(x)

def tochr(x):
    return chr(int(x))

def tohex(x):
    return hex(int(x))
""")

abs = block(x,
    Number clone setValue(x :__abs__)
)

all = block(xs,
    xs foreach(x,
        (x bool) ifFalse(False)
    )
    True
)

any = block(xs,
    xs foreach(x,
        (x bool) ifTrue(True)
    )
    False
)

bin = block(x, utils tobin(x))

bool = block(x, utils tobool(x))

callable = block(x,
    (x has("__call__")) ifTrue(
        True
    ) ifFalse(
        (x type == "Block")
    )
)

chr = block(x, utils tochr(x))

dict = block(
    d = Dict clone
    call message args foreach(arg,
        arg eval(d)
    )
    d
)

eval = block(code, context,
    Parser parse(code) eval(context ifNone(Root))
)

exit = block(status,
    status ifNone(
        System exit(0)
    )
    System exit(status)
)

hex = block(x, utils tohex(x))

filter = block(f, xs,
    rs = List clone
    xs foreach(x,
        (f is None) ifTrue(
            not x is None ifTrue(
                rs append(x)
            )
        ) ifFalse(
            f(x) ifTrue(
                rs append(x)
            )
        )
    )
    rs
)

from = import = Importer get("import")

iter = block(iterable, iterable __iter__())

list = block(
    (List clone(call message evalArgs(call sender)))
)

loop = block(
    code = call message args at(0)
    c = Continuation current()
    code eval(call sender)
    c()
)

map = block(f, xs,
    rs = List clone
    xs foreach(x,
        rs append(f(x))
    )
    rs
)

open = block(filename,
    File clone open(filename)
)

print = block(*args, sep=" ", end="\n", file=System stdout,
    file write(sep join(args))
    file write(end)
    file flush
    None
)

raise = Exception get("raise")

range = block(Range clone(call message evalArgs(call sender)))

reduce = block(f, xs, s,
    it = iter(xs)

    s ifNone (
        try (
            s = next(it)
        ) catch(StopIteration) (
            raise TypeError("reduce() of empty sequence with no initial value")
        )
    )

    a = s
    c = Continuation current
    try(
        a = f(a, it next())
        c()
    )
    a
)

return = block(value,
    (call sender type != "Locals") ifTrue(
        raise(RunTimeError clone("return outside Block"))
    )
    call sender state setReturn(value)
    value
)

sum = block(xs,
    r = 0
    xs foreach(x,
        r += x
    )
    r
)

try = Exception get("try")

with = block(
    obj = call message arg(0, call sender)
    res = call message arg(1, call sender)
    obj close
    res
)

while = block(
    test = call message args at(0)
    code = call message args at(1)
    c = Continuation current()
    (test eval(call sender)) ifTrue(
        code eval(call sender)
        c()
    )
    None
)

#
# Syntactic Sugar
#

set("()", Object get("evalArg"))
set(":", Object get("primitive"))
set("[]", get("list"))
set("{}", get("dict"))

set("?",
    block(
        name = call message args at(0) name
        call target has(name) ifTrue(
            call target get(name)
        ) ifFalse(
            None
        )
    )
)

from errors import *
from iterators import *
