def to_int(args: List, node): """Convert expression to its boolean value""" if len(args) != 1: evaluator.error("(special_forms.types.to_int) 1 parameter expected, {} given".format(len(args)), node) value = evaluator.evaluate_node(args[0]) return int(value)
def floor(args: List, _): """Evaluates expression (floor a) as {math.floor(a)}""" if len(args) != 1: evaluator.error("wrong number of arguments, got {}, 1 expected".format( str(len(args)))) return math.floor(evaluator.evaluate_node(args[0]))
def not_statement(args: List, node): """Evaluate (< a b) as {a < b}""" if len(args) != 1: evaluator.error( "(special_forms.control_statements.not) 1 parameter expected, {} given" .format(len(args)), node) return evaluator.evaluate_node(args[0]) in FALSE_STATEMENTS
def greater_statement(args: List, node): """Evaluate (> a b) as {a > b}""" if len(args) != 2: evaluator.error( "(special_forms.control_statements.greater) 2 parameters expected, {} given" .format(len(args)), node) return evaluator.evaluate_node(args[0]) > evaluator.evaluate_node(args[1])
def equals_statement(args: List, node): """Evaluate (== a b) as {a == b}""" if len(args) != 2: evaluator.error( "(special_forms.control_statements.equals) 2 parameters expected, {} given" .format(len(args)), node) return evaluator.evaluate_node(args[0]) == evaluator.evaluate_node(args[1])
def sqrt(args: List, node): """Evaluates expression (sqrt a) as {sqrt(a)}""" if len(args) != 1: evaluator.error( "(arithmetic.basic.sqrt) wrong number of arguments, got {}, 1 expected" .format(str(len(args))), node) return math.sqrt(evaluator.evaluate_node(args[0]))
def modulo(args: List, node): """Evaluates expression (sqrt a) as {sqrt(a)}""" if len(args) != 2: evaluator.error( "(arithmetic.basic.modulo) wrong number of arguments, got {}, 2 expected" .format(str(len(args))), node) params = evaluator.evaluate_parallel_args(args) return params[0] % params[1]
def list_length(args: List, node): """Return list length""" value = evaluator.evaluate_node(args[0]) if not isinstance(value, list): evaluator.error("(lists.lists.list-length) 1st argument must be list", node) return len(value)
def enumerate_list(args: List, node): """Python enumerate equiv.""" value = evaluator.evaluate_node(args[0]) if not isinstance(value, list): evaluator.error("(lists.lists.enumerate) 1st argument must be list", node) return list(enumerate(value))
def assert_equal(args: List, node): """First argument must equals to the second one""" if len(args) != 2: evaluator.error("(special_forms.assert_value.assert-equal) 2 parameter expected, {} given".format(len(args)), node) values = evaluator.evaluate_parallel_args(args) if values[0] != values[1]: evaluator.error("assertion failed: {} != {}".format(values[0], values[1]), node) return None
def assert_value(args: List, node): """First argument must be True""" if len(args) != 1: evaluator.error("(special_forms.assert_value.assert) 1 parameter expected, {} given".format(len(args)), node) value = evaluator.evaluate_node(args[0]) if value in FALSE_STATEMENTS: evaluator.error("assertion failed: {}".format(value), node) return None
def if_statement(args: List, node): """Evaluate (if cond a b) as {(cond) ? a : b}""" if len(args) != 3: evaluator.error( "(special_forms.control_statements.if) 3 parameters expected, {} given" .format(len(args)), node) condition = evaluator.evaluate_node(args[0]) if condition: return evaluator.evaluate_node(args[1]) return evaluator.evaluate_node(args[2])
def slice_list(args: List, node): """slice of list""" if len(args) < 2: evaluator.error( "(lists.lists.slice) at least 2 parameters expected, {} given.". format(len(args)), node) param = evaluator.evaluate_node(args[0]) if not isinstance(param, list) and not isinstance(param, str): evaluator.error( "(lists.lists.slice) 1st parameter must be of type list or str", node) params = evaluator.evaluate_parallel_args(args[1:]) if not isinstance(params[0], int): evaluator.error( "(lists.lists.slice) 1st parameter must be of type int", node) if len(args) == 2: return param[params[0]:] if not isinstance(params[1], int): evaluator.error( "(lists.lists.slice) 2st parameter must be of type int", node) return param[params[0]:params[1]]
def car_list(args: List, node): """Create list""" if len(args) != 1: evaluator.error( "(lists.lists.car) 1 parameter expected, {} given.".format( len(args)), node) param = evaluator.evaluate_node(args[0]) if not isinstance(param, list): evaluator.error("(lists.lists.car) 1st parameter must be of type list", node) return param[0]
def map_list(args: List, node): """Map list""" if len(args) != 2: evaluator.error( "(lists.lists.map) 2 parameters expected, {} given.".format( len(args)), node) function_object = evaluator.evaluate_node(args[0]) if not callable(function_object): evaluator.error("(lists.lists.map) map function is not callable", node) arg_list = evaluator.evaluate_node(args[1]) return list(map(lambda x: function_object([x], node), arg_list))
def filter_list(args: List, node): """Filter list""" if len(args) != 2: evaluator.error( "(lists.lists.filter) 2 parameters expected, {} given.".format( len(args)), node) function_object = evaluator.evaluate_node(args[0]) if not callable(function_object): evaluator.error("(lists.lists.filter) 1st parameter is not callable", node) arg_list = evaluator.evaluate_node(args[1]) return list(filter(lambda x: function_object([x], node), arg_list))
def define(args: List, node): """create new name->symbol connection""" if len(args) != 2: evaluator.error( "(special_forms.define.def) 2 parameters expected, {} given". format(len(args)), node) if args[0].value in node.parent.getenv().symbols: evaluator.error( "(special_forms.define.def) {} already defined".format( args[0].value), node) node.parent.getenv().symbols[args[0].value] = evaluator.evaluate_node( args[1]) return None
def python_getattr(args: List, node): """Call python function from mplisp""" if len(args) != 2: evaluator.error( "(special_forms.module_import.get_attribute) 2 parameters expected, {} given" .format(len(args)), node) params = evaluator.evaluate_parallel_args(args) if not isinstance(params[0], ModuleType): params[0] = import_module(args[0:1], node) if not isinstance(params[1], str): evaluator.error( "(special_forms.module_import.get_attribute) 2st param must be of type str, {} given" .format(type(params[1])), node) attr = getattr(params[0], params[1]) if callable(attr): return function_caller(attr) return attr
def import_module(args: List, node): """ Import all functions from a module and add corresponding symbols to the parent environment. """ module_name = evaluator.evaluate_node(args[0]) if not isinstance(module_name, str): evaluator.error( "(special_forms.module_import.import) 1st param must be of type str", node) local_path = module_name + ".mplisp" absolute_path = os.path.join("/usr/lib/mplisp", local_path) path = '' if os.path.isfile(local_path): path = local_path elif os.path.isfile(absolute_path): path = absolute_path if path: with open(local_path) as file_object: list(evaluator.evaluate(file_object.read(), node.getenv())) return None mplispstd = module_name.replace("std", "mplispstd") if module_exists(mplispstd): module_name = mplispstd elif not module_exists(module_name): evaluator.error( "(special_forms.module_import.import) package {} not found".format( module_name), node) mod = importlib.import_module(module_name) return mod
def substr(args: List, _): """python str[x:y] equiv""" if not args: evaluator.error("max 3 arguments expected, {} given".format(len(args))) params = evaluator.evaluate_parallel_args(args) if not isinstance(params[0], str): evaluator.error("first param must be of type str, {} given".format( type(params[0]))) if len(params) == 1: return params[0] if len(params) == 2: if not isinstance(params[1], int): evaluator.error("second param must be of type int") return params[0][params[1]:] elif len(params) == 3: if not isinstance(params[2], int): evaluator.error("third param must be of type int") return params[0][params[1]:params[2]]
def list_ref(args: List, _): """Check whether the first argument is list and the second one is int. Return element on that position""" if len(args) != 2: evaluator.error( "(lists.lists.list-ref) 2 parameters expected, {} given.".format( len(args)), node) params = evaluator.evaluate_parallel_args(args) if not isinstance(params[0], list): evaluator.error( "(lists.lists.list-ref) 1st parameter must be of type list", node) if not isinstance(params[1], int): evaluator.error( "(lists.lists.list-ref) 2st parameter must be of type list", node) if params[1] < 0 or params[1] >= len(params[0]): evaluator.error( "(lists.lists.list-ref) index {} is out of range".format( params[1]), node) return params[0][params[1]]
def list_apply(args: List, node): """Evaluate function on params given by list""" if len(args) != 2: evaluator.error( "(lists.lists.apply) 2 parameters expected, {} given.".format( len(args)), node) function_object = evaluator.evaluate_node(args[0]) if not callable(function_object): evaluator.error("(lists.lists.apply) apply function is not callable", node) arg_list = evaluator.evaluate_node(args[1]) if not isinstance(arg_list, list): evaluator.error("(lists.lists.apply) apply function is not callable", node) return function_object(arg_list, node)
def is_list(args: List, node): """Is value list""" if len(args) != 1: evaluator.error("(special_forms.types.is_list) 1 parameters expected, {} given".format(len(args)), node) return isinstance(evaluator.evaluate_node(args[0]), list)
def is_null(args: List, node): """Is value null""" if len(args) != 1: evaluator.error("(special_forms.types.is_null) 1 parameters expected, {} given".format(len(args)), node) return evaluator.evaluate_symbol(args[0].value, node) is None
def lambda_expression(args: List, node): """Return lambda expression""" if len(args) != 2: evaluator.error("(special_forms.lambda_expression.lambda) 2 parameters expected, {} given".format(len(args)), node) return create_lambda(args, node)