From e7e51ddbaabb345a8466d7f843286b5824eeca06 Mon Sep 17 00:00:00 2001 From: Bernhard Liebl Date: Mon, 26 Sep 2016 19:49:23 +0200 Subject: [PATCH 1/2] add evaluation to replace_vars() --- mathics/builtin/assignment.py | 2 +- mathics/builtin/functional.py | 2 +- mathics/builtin/patterns.py | 2 +- mathics/builtin/scoping.py | 2 +- mathics/core/convert.py | 2 +- mathics/core/expression.py | 16 +++++++--------- mathics/core/rules.py | 2 +- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/mathics/builtin/assignment.py b/mathics/builtin/assignment.py index 8be0566e57..9a66b10833 100644 --- a/mathics/builtin/assignment.py +++ b/mathics/builtin/assignment.py @@ -722,7 +722,7 @@ def print_rule(rule, up=False, lhs=lambda l: l, rhs=lambda r: r): evaluation.check_stopped() if isinstance(rule, Rule): r = rhs(rule.replace.replace_vars( - {'System`Definition': Expression('HoldForm', Symbol('Definition'))})) + {'System`Definition': Expression('HoldForm', Symbol('Definition'))}, evaluation)) lines.append(Expression('HoldForm', Expression( up and 'UpSet' or 'Set', lhs(rule.pattern.expr), r))) diff --git a/mathics/builtin/functional.py b/mathics/builtin/functional.py index 6692bf795d..b12b4aa481 100644 --- a/mathics/builtin/functional.py +++ b/mathics/builtin/functional.py @@ -88,7 +88,7 @@ def apply_named(self, vars, body, args, evaluation): else: vars = dict(list(zip(( var.get_name() for var in vars), args[:len(vars)]))) - return body.replace_vars(vars) + return body.replace_vars(vars, evaluation) class Slot(Builtin): diff --git a/mathics/builtin/patterns.py b/mathics/builtin/patterns.py index 20efaf88b1..c2e5a0709d 100644 --- a/mathics/builtin/patterns.py +++ b/mathics/builtin/patterns.py @@ -1219,7 +1219,7 @@ def match(self, yield_func, expression, vars, evaluation, **kwargs): # for new_vars, rest in self.pattern.match(expression, vars, # evaluation): def yield_match(new_vars, rest): - test_expr = self.test.replace_vars(new_vars) + test_expr = self.test.replace_vars(new_vars, evaluation) test_result = test_expr.evaluate(evaluation) if test_result.is_true(): yield_func(new_vars, rest) diff --git a/mathics/builtin/scoping.py b/mathics/builtin/scoping.py index ad6324b009..baf9550bf1 100644 --- a/mathics/builtin/scoping.py +++ b/mathics/builtin/scoping.py @@ -194,7 +194,7 @@ def apply(self, vars, expr, evaluation): if new_def is not None: evaluation.definitions.set_ownvalue(new_name, new_def) replace[name] = Symbol(new_name) - new_expr = expr.replace_vars(replace, in_scoping=False) + new_expr = expr.replace_vars(replace, evaluation, in_scoping=False) result = new_expr.evaluate(evaluation) return result diff --git a/mathics/core/convert.py b/mathics/core/convert.py index 575545a661..393d57433f 100644 --- a/mathics/core/convert.py +++ b/mathics/core/convert.py @@ -73,7 +73,7 @@ def _eval_subs(self, old, new): old, new = from_sympy(old), from_sympy(new) old_name = old.get_name() if old_name: - new_expr = self.expr.replace_vars({old_name: new}) + new_expr = self.expr.replace_vars({old_name: new}, None) return SympyExpression(new_expr) return self diff --git a/mathics/core/expression.py b/mathics/core/expression.py index d062af44d6..e9082d82d6 100644 --- a/mathics/core/expression.py +++ b/mathics/core/expression.py @@ -1146,16 +1146,14 @@ def descend(expr): expr = Expression(head, *expr.leaves) return expr, new_applied[0] - - def replace_vars(self, vars, options=None, - in_scoping=True, in_function=True): + def replace_vars(self, vars, evaluation, options=None, in_scoping=True, in_function=True): from mathics.builtin.scoping import get_scoping_vars if not in_scoping: if (self.head.get_name() in ('System`Module', 'System`Block', 'System`With') and len(self.leaves) > 0): # nopep8 - scoping_vars = set(name for name, new_def in get_scoping_vars(self.leaves[0])) + scoping_vars = set(name for name, new_def in get_scoping_vars(self.leaves[0], evaluation=evaluation)) """for var in new_vars: if var in scoping_vars: del new_vars[var]""" @@ -1177,7 +1175,7 @@ def replace_vars(self, vars, options=None, body = self.leaves[1] replacement = {name: Symbol(name + '$') for name in func_params} func_params = [Symbol(name + '$') for name in func_params] - body = body.replace_vars(replacement, options, in_scoping) + body = body.replace_vars(replacement, evaluation, options, in_scoping) leaves = [Expression('List', *func_params), body] + \ self.leaves[2:] @@ -1186,8 +1184,8 @@ def replace_vars(self, vars, options=None, return Expression( self.head.replace_vars( - vars, options=options, in_scoping=in_scoping), - *[leaf.replace_vars(vars, options=options, in_scoping=in_scoping) + vars, evaluation, options=options, in_scoping=in_scoping), + *[leaf.replace_vars(vars, evaluation, options=options, in_scoping=in_scoping) for leaf in leaves]) def replace_slots(self, slots, evaluation): @@ -1325,7 +1323,7 @@ def get_atom_name(self): def __repr__(self): return '<%s: %s>' % (self.get_atom_name(), self) - def replace_vars(self, vars, options=None, in_scoping=True): + def replace_vars(self, vars, evaluation, options=None, in_scoping=True): return self def replace_slots(self, slots, evaluation): @@ -1424,7 +1422,7 @@ def get_sort_key(self, pattern_sort=False): def same(self, other): return isinstance(other, Symbol) and self.name == other.name - def replace_vars(self, vars, options={}, in_scoping=True): + def replace_vars(self, vars, evaluation, options={}, in_scoping=True): assert all(fully_qualified_symbol_name(v) for v in vars) var = vars.get(self.name, None) if var is None: diff --git a/mathics/core/rules.py b/mathics/core/rules.py index a1c4115d62..ad5c945bdd 100644 --- a/mathics/core/rules.py +++ b/mathics/core/rules.py @@ -89,7 +89,7 @@ def __init__(self, pattern, replace, system=False): self.replace = replace def do_replace(self, vars, options, evaluation): - new = self.replace.replace_vars(vars) + new = self.replace.replace_vars(vars, evaluation) new.options = options # if options is a non-empty dict, we need to ensure reevaluation of the whole expression, since 'new' will From 8aefe85c8f0da925ec639c1180fe7f9975acf2a6 Mon Sep 17 00:00:00 2001 From: Bernhard Liebl Date: Mon, 26 Sep 2016 20:21:57 +0200 Subject: [PATCH 2/2] adds test case for nested modules --- mathics/builtin/scoping.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mathics/builtin/scoping.py b/mathics/builtin/scoping.py index baf9550bf1..9fd0a8d3ac 100644 --- a/mathics/builtin/scoping.py +++ b/mathics/builtin/scoping.py @@ -167,6 +167,10 @@ class Module(Builtin): = a >> Module[{a}, Block[{}, a]] = a$5 + + #> Module[{n = 3}, Module[{b = n * 5}, b * 7]] + = 105 + """ attributes = ('HoldAll',)