Esempio n. 1
0
 def atomize(param) -> Atom:
     if re.search(r"^\d+\.\d+$", param):
         return Atom(float(param))
     elif re.search(r"^\d+$", param):
         return Atom(int(param))
     else:
         return Atom(param)
def test_list_recursion(list_env):
    parse_expression(
        "(define (sum lon) (if (empty? lon) 0 (+ (car lon) (sum (cdr lon)))))",
        list_env,
    ).eval(list_env)

    assert parse_expression("(sum 5to1)", list_env).eval(list_env) == Atom(15)
Esempio n. 3
0
    def parse(exp_list: Union[str, List]) -> Expression:
        def atomize(param) -> Atom:
            if re.search(r"^\d+\.\d+$", param):
                return Atom(float(param))
            elif re.search(r"^\d+$", param):
                return Atom(int(param))
            else:
                return Atom(param)

        if isinstance(exp_list, str):
            return atomize(exp_list)
        else:
            exp = exp_list.pop(0)

            if exp == "lambda":
                return Function(parse(exp_list[1]), env, *exp_list[0])
            elif exp == "define":
                if isinstance(exp_list[0], str):
                    return Definition(exp_list[0], parse(exp_list[1]))
                elif isinstance(exp_list[0], list):
                    func_name = exp_list[0].pop(0)
                    return Definition(
                        func_name,
                        Function(parse(exp_list[1]), env, *exp_list[0]))

            args = list(map(parse, exp_list))

            if exp == "if":
                return If(*args)
            elif exp == "and":
                return And(*args)
            elif exp == "or":
                return Or(*args)
            elif exp == "cons":
                return Cons(*args)
            else:
                return FunctionCall(Atom(exp), *args)
def test_recursion(basic_env):
    parse_expression("(define (fact n) (if (zero? n) 1 (* n (fact (- n 1)))))",
                     basic_env).eval(basic_env)

    assert parse_expression("(fact 5)", basic_env).eval(basic_env) == Atom(120)
def test_define_lambda(basic_env):
    parse_expression("(define sqr (lambda (x) (* x x)))",
                     basic_env).eval(basic_env)

    assert parse_expression("(sqr 2)", basic_env).eval(basic_env) == Atom(4)
def test_builtin_math(basic_env):
    assert parse_expression("(+ 1 2)", basic_env).eval(basic_env) == Atom(3)
    assert parse_expression("(* 3 4)", basic_env).eval(basic_env) == Atom(12)
    assert parse_expression("(- 3 9)", basic_env).eval(basic_env) == Atom(-6)
    assert parse_expression("(/ 15 5)", basic_env).eval(basic_env) == Atom(3)
Esempio n. 7
0
def add(*args: Atom) -> Atom:
    rsf = 0
    for arg in args:
        rsf += arg.val
    return Atom(rsf)
Esempio n. 8
0
def divide(*args: Atom) -> Atom:
    rsf = args[0].val
    for arg in args[1:]:
        rsf /= arg.val
    return Atom(rsf)
Esempio n. 9
0
def multiply(*args: Atom) -> Atom:
    rsf = 1
    for arg in args:
        rsf *= arg.val
    return Atom(rsf)
Esempio n. 10
0
def subtract(*args: Atom) -> Atom:
    rsf = args[0].val
    for arg in args[1:]:
        rsf -= arg.val
    return Atom(rsf)