Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TurtleArt/taprimitive.py
diff options
context:
space:
mode:
Diffstat (limited to 'TurtleArt/taprimitive.py')
-rw-r--r--TurtleArt/taprimitive.py77
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