def test_basic_recursion(): implementation = function( [parameter_name], conditional( (invoke(GREATER_THAN, parameter_name, integer(1)), invoke( MULTIPLY, parameter_name, invoke(function_name, invoke(SUBTRACT, parameter_name, integer(1))))), (boolean(True), integer(1)))) environment = Environment.create_standard() environment.define(function_name, limp.evaluate(implementation, environment)) data = [ (1, 1), (2, 2), (3, 6), (4, 24), (5, 120), (6, 720), ] for parameter, expected_result in data: source_code = invoke(function_name, integer(parameter)) result = limp.evaluate(source_code, environment) yield assert_equal, expected_result, result
def test_executing_something_a_fixed_number_of_times(): for iterations in range(ARBITRARY_ITERATION_LIMIT): my_function = MagicMock() environment = Environment.create_standard() environment.define(FUNCTION_NAME, my_function) code = invoke(TIMES, integer(iterations), symbol(FUNCTION_NAME)) limp.evaluate(code, environment) yield (assert_equal, iterations, my_function.call_count)
def test_iterating_a_fixed_number_of_times(): my_function = MagicMock() environment = Environment.create_standard() environment.define(FUNCTION_NAME, my_function) code = invoke(ITERATE, integer(ARBITRARY_ITERATION_LIMIT), symbol(FUNCTION_NAME)) limp.evaluate(code, environment) for i in range(ARBITRARY_ITERATION_LIMIT): yield (my_function.assert_any_call, i)
def __init__(self, input_=None, output=None): if input_ == None: input_ = default_input if output == None: output = default_output self._input = input_ self._output = output self.__displayed_welcome = False self.__environment = Environment.create_standard()
def test_looping_functions(): FUNCTION_NAME = 'my_function' ARBITRARY_ITERATION_LIMIT = 100 # test 'times' function for iterations in range(ARBITRARY_ITERATION_LIMIT): my_function = MagicMock() environment = Environment.create_standard() environment.define(FUNCTION_NAME, my_function) limp.evaluate(f'(times {iterations} {FUNCTION_NAME})', environment) yield assert_equals, iterations, my_function.call_count # test 'iterate' function my_function = MagicMock() environment = Environment.create_standard() environment.define(FUNCTION_NAME, my_function) limp.evaluate(f'(iterate {ARBITRARY_ITERATION_LIMIT} {FUNCTION_NAME})', environment) for i in range(iterations): yield my_function.assert_any_call, i
def test_functions_with_no_arguments(): data = [ (['function', [], '10'], 10), (['function', [], '20'], 20), (['function', [], '0.1'], 0.1), (['function', [], ['+', '1', '2']], 3), ] for contents, expected_value in data: function = Types.Function(contents, Environment.create_standard()) internal_function = function.evaluate() yield assert_equals, expected_value, internal_function()
def evaluate(source_code, environment=None): source_code = source_code.strip() if source_code == "": raise Errors.EmptyCode() if environment is None: environment = Environment.create_standard() tokens = Tokens.create_from(source_code) syntax_tree = SyntaxTree.create_from(tokens) result = Evaluation.evaluate(syntax_tree, environment) return result
def sample_environment(): environment = Environment.create_standard() extras = { 'variable': 20, 'abc': None, 'def': None, 'add': operator.add, 'subtract': operator.sub, 'multiply': lambda x, y, z: x * y * z, 'return10': lambda: 10, 'x': 10, 'y': 20, 'z': 30, 'foo': 100, } environment.define_batch_of(extras) return environment
def test_evaluating_source_code(): data = [ ('1', 1), ('(+ 1 2)', 3), ('(+ (+ 1 2) 3)', 6), ('"Hello!"', "Hello!"), ('(+\n1\t2)', 3), ('(do 1 2 3 4)', 4), ("""(do (define a 1) (define b 2) (define c 3))""", None), ] for source_code, expected_result in data: result = Types.Form.infer_from( TokenTree.create_from(Tokens.create_from(source_code)), Environment.create_standard()).evaluate() yield assert_equals, expected_result, result
def test_functions_with_arguments(): data = [ (['function', ['x'], 'x'], [10], 10), (['function', ['x'], 'x'], [9], 9), (['function', ['y'], 'y'], [2], 2), (['function', ['y'], 'y'], [1], 1), (['function', ['n'], ['**', 'n', '2']], [1], 1), (['function', ['n'], ['**', 'n', '2']], [2], 4), (['function', ['n'], ['**', 'n', '2']], [3], 9), (['function', ['n'], ['**', 'n', '2']], [4], 16), (['function', ['n'], ['**', 'n', '2']], [5], 25), (['function', ['a', 'b'], ['+', 'a', 'b']], [0, 0], 0), (['function', ['a', 'b'], ['+', 'a', 'b']], [0, 1], 1), (['function', ['a', 'b'], ['+', 'a', 'b']], [5, 3], 8), ] for contents, arguments, expected_value in data: function = Types.Function(contents, Environment.create_standard()) internal_function = function.evaluate() yield assert_equals, expected_value, internal_function(*arguments)
def test_getting_symbols(): environment = Environment.create_standard() environment.define_multiple({ 'x': 10, 'y': 20, 'z': 30, 'foo': 100, }.items()) data = [ ('x', 10), ('y', 20), ('z', 30), ('foo', 100), ] for source_code, expected_result in data: result = limp.evaluate(source_code, environment) yield assert_equal, expected_result, result
def test_accessing_attributes(): environment = Environment.create_standard() environment.define('object', limp.evaluate(object_code)) data = [ ('{age: 90}.age', 90), ('{name:"Bob" age:200}.age', 200), ('object.name', "Blarg Smith"), ('object.age', 1337), ('object.interests', ["food", "limp", "THPS"]), ('object.address', { "house-number": 420, "street": "earth street" }), ('object.address.street', "earth street"), ('{profiles: {byxor: {is-cool: true}}}.profiles.byxor.is-cool', True), ] for source_code, expected_result in data: result = limp.evaluate(source_code, environment) yield assert_equals, expected_result, result
def test_lists_are_immutable(): LIST = 'my-list' LIST_VALUE = [1, 2, 3] environment = Environment.create_standard() environment.define(LIST, LIST_VALUE) invocations = [ invoke(APPEND_ELEMENT, LIST, integer(1)), invoke(CONCATENATE, LIST, list_of(string("foo"), string("bar"))), invoke(MAP, TEMPORARY_MAP_FUNCTION, LIST), invoke(FILTER, TEMPORARY_FILTER_FUNCTION, LIST), invoke(REDUCE, TEMPORARY_REDUCE_FUNCTION, LIST), invoke(FIRST_ELEMENT, LIST), invoke(LAST_ELEMENT, LIST), invoke(ALL_BUT_FIRST, LIST), invoke(ALL_BUT_LAST, LIST), invoke(PREPEND_ELEMENT, LIST, string("foo")), ] for invocation in invocations: limp.evaluate(invocation, environment) yield assert_equal, LIST_VALUE, environment.resolve(LIST)
def evaluate(source_code, environment=None): if environment is None: environment = Environment.create_standard() return Types.Form.infer_from( TokenTree.create_from(Tokens.create_from(source_code)), environment).evaluate()
def __init__(self, input_=input, output=sys.stdout.write): self._input = input_ self._output = output self.__displayed_welcome = False self.__environment = Environment.create_standard()