diff options
Diffstat (limited to 'TurtleArt/taprimitive.py')
-rw-r--r-- | TurtleArt/taprimitive.py | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/TurtleArt/taprimitive.py b/TurtleArt/taprimitive.py index 4e0910e..8171c43 100644 --- a/TurtleArt/taprimitive.py +++ b/TurtleArt/taprimitive.py @@ -64,7 +64,8 @@ class Primitive(object): 'bitwise_or': ast.BitOr, 'and_': ast.And, 'or_': ast.Or, - 'not_': ast.Not} + 'not_': ast.Not, + 'equals': ast.Eq} def __init__(self, func, constant_args=None, slot_wrappers=None, call_afterwards=None, call_me=True, export_me=True): @@ -347,8 +348,11 @@ class Primitive(object): if isinstance(op, tuple): op = op[1] (left, right) = new_arg_asts - if op in (ast.And, ast.Or): + if issubclass(op, ast.boolop): return ast.BoolOp(op=op, values=[left, right]) + elif issubclass(op, ast.cmpop): + return ast.Compare(left=left, ops=[op], + comparators=[right]) else: return ast.BinOp(op=op, left=left, right=right) else: @@ -357,6 +361,16 @@ class Primitive(object): % (str(self.func.__func__.__name__), len(new_arg_asts))) + elif self == Primitive.convert_for_cmp: + # remove the 'convert_to_ast' keyword argument + my_kwarg_asts = {} + for (key, value) in new_kwarg_asts.iteritems(): + if key != 'convert_to_ast': + my_kwarg_asts[key] = value + return Primitive.convert_for_cmp(*new_arg_asts, + convert_to_ast=True, + **my_kwarg_asts) + # identity elif self == Primitive.identity: if len(new_arg_asts) == 1: @@ -615,6 +629,56 @@ class Primitive(object): otherwise. """ return not arg + @staticmethod + def convert_for_cmp(value, decimal_point='.', convert_to_ast=False): + """ Convert value such that it can be compared to something else. + 1. Convert a string containing a number into a float. + 2. Convert a single character to its ASCII integer value. + 3. Return all other values unchanged. """ + converted = None + conversion_ast = None + if convert_to_ast: + value_ast = value_to_ast(value) + + if isinstance(value, basestring): + # 1. string containing a number + replaced = value.replace(decimal_point, '.') + try: + converted = float(replaced) + except ValueError: + pass + else: + if convert_to_ast: + conversion_ast = get_call_ast('float', [value_ast]) + + # 2. single character + if converted is None: + try: + converted = ord(value) + except TypeError: + pass + else: + if convert_to_ast: + conversion_ast = get_call_ast('ord', [value_ast]) + + # 3. normal string or other type of value (nothing to do) + + if convert_to_ast: + if conversion_ast is None: + return value_ast + else: + return conversion_ast + else: + if converted is None: + return value + else: + return converted + + @staticmethod + def equals(arg1, arg2): + """ Return arg1 == arg2 """ + return arg1 == arg2 + class PrimitiveCall(Primitive): @@ -681,6 +745,15 @@ def value_to_ast(value, *args_for_prim, **kwargs_for_prim): raise ValueError("unknown type of raw value: " + repr(type(value))) +def get_call_ast(func_name, args=[], keywords={}): + return ast.Call(func=ast.Name(id=func_name, + ctx=ast.Load), + args=args, + keywords=keywords, + starargs=None, + kwargs=None) + + def call_me(something): """ Return True iff this is a Primitive and its call_me attribute is True, i.e. nothing is callable except for Primitives with |