aboutsummaryrefslogtreecommitdiff
path: root/neb/std/boolean.py
blob: b851d7d6d056ef63cbe333680f081b975fabee0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from .. import TypeEnum, Environment, Arg, Builtin, evaluate
from ..structs import *

BOOLEAN = Environment()

def interpretOr(symbol, args, env, ns):
    # or returns true for the first expression that returns true
    for arg in args:
        ev = evaluate(arg, env, ns)
        if not isinstance(ev, Bool):
            raise InterpretPanic(symbol, "requires :bool arguments")
        if ev.value == True:
            return ev
    return Bool(False)

or_arg = Arg("arg", TypeEnum.BOOL, lazy=True)
BOOLEAN.register("or", Builtin(interpretOr, [or_arg, or_arg], or_arg))

def interpretAnd(symbol, args, env, ns):
    # and returns false for the first expression that returns false
    for arg in args:
        ev = evaluate(arg, env, ns)
        if not isinstance(ev, Bool):
            raise InterpretPanic(symbol, "requires :bool arguments")
        if ev.value == False:
            return ev
    return Bool(True)

BOOLEAN.register("and", Builtin(interpretAnd, [or_arg, or_arg], or_arg))

def interpretEq(symbol, args, env, ns):
    # NOTE this currently only works for literals
    # compare types because 0 != #false in neb
    if type(args[0]) == type(args[1]) and args[0].value == args[1].value:
        return Bool(True)
    else:
        return Bool(False)

eq_arg = Arg("value", TypeEnum.LITERAL)
BOOLEAN.register("eq?", Builtin(interpretEq, [eq_arg, eq_arg]))


def interpretNot(symbol, args, env, ns):
    return Bool(not args[0].value)

not_arg = Arg("not", TypeEnum.BOOL)
BOOLEAN.register("not", Builtin(interpretNot, [not_arg]))