Skip to content

Commit

Permalink
Merge pull request #616 from poke1024/classdef
Browse files Browse the repository at this point in the history
Speedups by avoiding inner classes
  • Loading branch information
sn6uv authored Oct 9, 2016
2 parents 5287dc2 + 08ff70e commit d4912a1
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 46 deletions.
14 changes: 8 additions & 6 deletions mathics/builtin/combinatorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,13 @@ def apply(self, values, evaluation):
return result


class _NoBoolVector(Exception):
pass


class _BooleanDissimilarity(Builtin):
@staticmethod
def _to_bool_vector(u):
class NoBoolVector(Exception):
pass

def generate():
for leaf in u.leaves:
Expand All @@ -115,21 +117,21 @@ def generate():
if val in (0, 1):
yield val
else:
raise NoBoolVector
raise _NoBoolVector
elif isinstance(leaf, Symbol):
name = leaf.name
if name == 'System`True':
yield 1
elif name == 'System`False':
yield 0
else:
raise NoBoolVector
raise _NoBoolVector
else:
raise NoBoolVector
raise _NoBoolVector

try:
return [x for x in generate()]
except NoBoolVector:
except _NoBoolVector:
return None

def apply(self, u, v, evaluation):
Expand Down
15 changes: 8 additions & 7 deletions mathics/builtin/exptrig.py
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,10 @@ def _fold(self, state, steps, math):
yield x, y, phi


class _IllegalStepSpecification(Exception):
pass


class AnglePath(Builtin):
"""
<dl>
Expand Down Expand Up @@ -1072,28 +1076,25 @@ def _compute(x0, y0, phi0, steps, evaluation):
if not steps:
return Expression('List')

class IllegalStepSpecification(Exception):
pass

if steps[0].get_head_name() == 'System`List':
def parse(step):
if step.get_head_name() != 'System`List':
raise IllegalStepSpecification
raise _IllegalStepSpecification
arguments = step.leaves
if len(arguments) != 2:
raise IllegalStepSpecification
raise _IllegalStepSpecification
return arguments
else:
def parse(step):
if step.get_head_name() == 'System`List':
raise IllegalStepSpecification
raise _IllegalStepSpecification
return None, step

try:
fold = AnglePathFold(parse)
leaves = [Expression('List', x, y) for x, y, _ in fold.fold((x0, y0, phi0), steps)]
return Expression('List', *leaves)
except IllegalStepSpecification:
except _IllegalStepSpecification:
evaluation.message('AnglePath', 'steps', Expression('List', *steps))

def apply(self, steps, evaluation):
Expand Down
44 changes: 34 additions & 10 deletions mathics/builtin/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,10 @@ def get_match_count(self, vars={}):
return range


class _StopGeneratorExcept(StopGenerator):
pass


class Except(PatternObject):
"""
<dl>
Expand Down Expand Up @@ -558,34 +562,32 @@ def init(self, expr):
self.p = Pattern.create(Expression('Blank'))

def match(self, yield_func, expression, vars, evaluation, **kwargs):
class StopGenerator_Except(StopGenerator):
pass

def except_yield_func(vars, rest):
raise StopGenerator_Except(Symbol("True"))
raise _StopGeneratorExcept(True)

try:
self.c.match(except_yield_func, expression, vars, evaluation)
except StopGenerator_Except:
except _StopGeneratorExcept:
pass
else:
self.p.match(yield_func, expression, vars, evaluation)


class _StopGeneratorMatchQ(StopGenerator):
pass


class Matcher(object):
def __init__(self, form):
self.form = Pattern.create(form)

def match(self, expr, evaluation):
class StopGenerator_MatchQ(StopGenerator):
pass

def yield_func(vars, rest):
raise StopGenerator_MatchQ(Symbol("True"))
raise _StopGeneratorMatchQ(True)

try:
self.form.match(yield_func, expr, {}, evaluation)
except StopGenerator_MatchQ:
except _StopGeneratorMatchQ:
return True
return False

Expand Down Expand Up @@ -1332,3 +1334,25 @@ def _match(leaf):
return (leaf.has_form(('Rule', 'RuleDelayed'), 2) or
leaf.has_form('List', None))
return [leaf for leaf in leaves if _match(leaf)]


class _StopGeneratorBaseExpressionIsFree(StopGenerator):
pass


def item_is_free(item, form, evaluation):
# for vars, rest in form.match(self, {}, evaluation, fully=False):
def yield_match(vars, rest):
raise _StopGeneratorBaseExpressionIsFree(False)
# return False

try:
form.match(yield_match, item, {}, evaluation, fully=False)
except _StopGeneratorBaseExpressionIsFree as exc:
return exc.value

if item.is_atom():
return True
else:
return item_is_free(item.head, form, evaluation) and all(
item_is_free(leaf, form, evaluation) for leaf in item.leaves)
11 changes: 6 additions & 5 deletions mathics/builtin/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1592,6 +1592,10 @@ def apply(self, string, evaluation):
return from_python(codes)


class _InvalidCodepointError(ValueError):
pass


class FromCharacterCode(Builtin):
"""
<dl>
Expand Down Expand Up @@ -1667,9 +1671,6 @@ def apply(self, n, evaluation):
"FromCharacterCode[n_]"
exp = Expression('FromCharacterCode', n)

class InvalidCodepointError(ValueError):
pass

def convert_codepoint_list(l, encoding=None):
if encoding is not None:
raise NotImplementedError
Expand All @@ -1681,7 +1682,7 @@ def convert_codepoint_list(l, encoding=None):
evaluation.message(
'FromCharacterCode', 'notunicode',
Expression('List', *l), Integer(i + 1))
raise InvalidCodepointError
raise _InvalidCodepointError
s += unichr(pyni)

return s
Expand Down Expand Up @@ -1710,7 +1711,7 @@ def convert_codepoint_list(l, encoding=None):
return evaluation.message(
'FromCharacterCode', 'intnm', exp, Integer(1))
return String(convert_codepoint_list([n]))
except InvalidCodepointError:
except _InvalidCodepointError:
return

assert False, "can't get here"
Expand Down
20 changes: 2 additions & 18 deletions mathics/core/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,24 +312,8 @@ def format(self, evaluation, form):
return result

def is_free(self, form, evaluation):
from mathics.core.pattern import StopGenerator

class StopGenerator_BaseExpression_is_free(StopGenerator):
pass

# for vars, rest in form.match(self, {}, evaluation, fully=False):
def yield_match(vars, rest):
raise StopGenerator_BaseExpression_is_free(False)
# return False
try:
form.match(yield_match, self, {}, evaluation, fully=False)
except StopGenerator_BaseExpression_is_free as exc:
return exc.value
if self.is_atom():
return True
else:
return self.head.is_free(form, evaluation) and all(
leaf.is_free(form, evaluation) for leaf in self.leaves)
from mathics.builtin.patterns import item_is_free
return item_is_free(self, form, evaluation)

def is_inexact(self):
return self.get_precision() is not None
Expand Down

0 comments on commit d4912a1

Please sign in to comment.