def let_star_expression(args: List, node): """Return let expression""" for param in args[0].children: node.getenv().symbols[param.children[0].value] = evaluator.evaluate_node( param.children[1]) return evaluator.evaluate_node(args[1])
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 func(local_args: List, _): """Callable object""" new_node = copy.copy(node.children[2]) if new_node.local_env is None: new_node.local_env = env.EnvNode({}) for arg, value in zip(params, local_args): new_node.local_env.symbols[arg] = evaluator.evaluate_node(value) return evaluator.evaluate_node(new_node)
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 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 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 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 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 and_statement(args: List, _): """Evaluate (and? a b c ...) as {a && b && c && ...}""" for arg in args: if evaluator.evaluate_node(arg) in FALSE_STATEMENTS: return False return True
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 or_statement(args: List, _): """Evaluate (or? a b c ...) as {a || b || c || ...}""" for arg in args: if evaluator.evaluate_node(arg) not in FALSE_STATEMENTS: return True return False
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 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 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 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 let_expression(args: List, node): """Return let expression""" with concurrent.futures.ThreadPoolExecutor() as executor: def set_env(x): (x, evaluator.evaluate_node(x.children[1])) for name, value in executor.map(set_env, args[0].children): node.getenv().symbols[name.children[0].value] = value return evaluator.evaluate_node(args[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 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 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 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 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 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 set_env(x): (x, evaluator.evaluate_node(x.children[1]))