def test_A_native_function_can_edit_the_environment(): def mx3(env): env.set("x", NumberValue(3)) env = make_env() env.set("make_x_three", NativeFunctionValue(mx3)) assert (evald("x=1 make_x_three() x", env) == NumberValue(3))
def test_A_closure_holds_updateable_values(): def dumb_set(env, sym, val): env.parent().parent().parent().set(sym.value, val) def dumb_if_equal(env, val1, val2, then_fn, else_fn): if val1 == val2: ret = then_fn else: ret = else_fn return eval_cell_list([FunctionCallTree(ret, [])], env) env = make_env() env.set("dumb_set", NativeFunctionValue(dumb_set)) env.set("dumb_if_equal", NativeFunctionValue(dumb_if_equal)) assert (evald( """ counter={ x=0 {:(meth) dumb_if_equal( meth, "get", {x}, {dumb_set("x",x+1)} ) } }() counter("inc") counter("inc") counter("get") """, env) == NumberValue(2))
def test_Native_function_gets_called(): def native_fn(_env, x, y): return NumberValue(x.value + y.value) env = make_env() env.set("native_fn", NativeFunctionValue(native_fn)) assert evald("native_fn(2,8)", env) == NumberValue(10)
def r(nv): return NumberValue(round(nv.value))
def test_Get_wraps_around(): assert evald("Get([0,1,2,3,4],-1)") == NumberValue(4) assert evald("Get([0,1,2,3,4],-2)") == NumberValue(3) assert evald("Get([0,1,2,3,4],5)") == NumberValue(0) assert evald("Get([0,1,2,3,4],6.1)") == NumberValue(1) assert evald("Get([0,1,2,3,4],11)") == NumberValue(1)
def test_Calling_a_function_returns_its_last_value(): assert (evald("{10 11}()") == NumberValue(11))
def test_Negating_a_symbol(): assert evald("x=30 x=10 -x") == NumberValue(-10)
def test_Undefined_variables_are_equal_to_0(): assert evald("foo") == NumberValue(0)
def TODO_FAILS_test_Can_define_a_value_as_a_negative(): assert evald("x=-30 x") == NumberValue(-30)
def TODO_FAILS_test_Modifying_by_negative_numbers_comes_out_correct(): assert evald("r=3 r+=-4 r") == NumberValue(-1) assert evald("r=3 r*=-4 r") == NumberValue(-12)
def test_Modifying_arithmetic_expressions_come_out_correct(): assert evald("r=3 r+=4 r") == NumberValue(7) assert evald("r=3 r-=4 r") == NumberValue(-1) assert evald("r=3 r*=4 r") == NumberValue(12) assert evald("r=3 r/=4 r") == NumberValue(0.75)
def test_Evaluating_a_primitive_returns_itself(): assert evald("3") == NumberValue(3) assert evald("3.1") == NumberValue(3.1) assert evald("-3.1") == NumberValue(-3.1) assert evald("'foo'") == StringValue("foo")
def native_fn3(_env, _x, _y, _z): return NumberValue(12)
def native_fn0(_env): return NumberValue(12)
def native_fn(_env, x, y): return NumberValue(x.value + y.value)
def test_A_symbol_within_a_function_has_the_local_value(): assert (evald(""" foo=3 bar={foo=77 foo}() bar """) == NumberValue(77))
def test_Can_hold_a_reference_to_a_function_and_call_it(): assert (evald(""" add={:(x,y)x+y} add(20,2.2) """) == NumberValue(22.2))
def test_Body_of_a_function_can_use_arg_values(): assert (evald("{:(x,y)x+y}(100,1)") == NumberValue(101))
def test_Arithmetic_expressions_come_out_correct(): assert evald("3+4") == NumberValue(7) assert evald("3-4") == NumberValue(-1) assert evald("3*4") == NumberValue(12) assert evald("3*-4") == NumberValue(-12) assert evald("3/4") == NumberValue(0.75)
def mx3(env): env.set("x", NumberValue(3))
def test_Modifying_uninitialised_variables_comes_out_correct(): assert evald("d+=4 d") == NumberValue(4)
def test_Array_literal(): assert (evald("[3,4]") == ArrayValue([NumberValue(3), NumberValue(4)]))
def test_Referring_to_an_unknown_symbol_yields_0(): assert evald("unkn") == NumberValue(0.0)
def test_Get_from_array(): assert evald("x=[3,4] Get(x,0)") == NumberValue(3)
def test_Can_define_a_value_and_retrieve_it(): assert evald("x=30 x ") == NumberValue(30) assert evald("y='foo' y") == StringValue("foo")
def test_Get_from_array_literal(): assert evald("Get([3,4],1)") == NumberValue(4)
def test_Modifying_a_value_is_allowed(): assert evald("x=30 x=10 x") == NumberValue(10)
def test_Add_to_array_literal(): assert (evald("Add([3,4],1)") == ArrayValue([ NumberValue(3), NumberValue(4), NumberValue(1), ]))
def test_Value_of_an_assignment_is_the_value_assigned(): assert evald("x=31") == NumberValue(31)
def test_Negative_assignment(): assert evald("x=-31") == NumberValue(-31)