diff options
author | Marion <marion.zepf@gmail.com> | 2013-08-29 14:41:43 (GMT) |
---|---|---|
committer | Marion <marion.zepf@gmail.com> | 2013-08-29 14:41:43 (GMT) |
commit | 355ff738875299f44c9eda210102b22223818272 (patch) | |
tree | cb69cd7b331a30913fe7fd365c09f89ba3517ff6 | |
parent | 203303db1b9b75d09e55b9618b980188256a6258 (diff) |
re-implement python export functionality using the type system
-rw-r--r-- | TurtleArt/taprimitive.py | 47 | ||||
-rw-r--r-- | TurtleArt/tatype.py | 11 |
2 files changed, 33 insertions, 25 deletions
diff --git a/TurtleArt/taprimitive.py b/TurtleArt/taprimitive.py index 1d49d21..e366a34 100644 --- a/TurtleArt/taprimitive.py +++ b/TurtleArt/taprimitive.py @@ -364,14 +364,18 @@ class Primitive(object): """ Transform this object into a Python AST. When serialized and executed, the AST will do exactly the same as calling this object. """ - # constant arguments - (all_arg_asts, all_kwarg_asts) = self._add_constant_args(arg_asts, - kwarg_asts, convert_to_ast=True) + new_prim = self.fill_slots(*arg_asts, **kwarg_asts) + if not new_prim.are_slots_filled(): + raise PyExportError("not enough arguments") - # slot wrappers - (new_arg_asts, new_kwarg_asts) = self._apply_wrappers(all_arg_asts, - all_kwarg_asts, - convert_to_ast=True) + # extract the actual values from the (now constant) arguments + # TODO put this into a method and use it also in __call__ + new_arg_asts = [] + for c_arg in new_prim.arg_descs: + new_arg_asts.append(c_arg.get()) + new_kwarg_asts = {} + for key in new_prim.kwarg_descs: + new_kwarg_asts[key] = new_prim.kwarg_descs[key].get() # SPECIAL HANDLING # @@ -491,7 +495,13 @@ class Primitive(object): # group of Primitives elif self == Primitive.group: - return new_arg_asts[0].elts + ast_list = [] + for prim in new_arg_asts[0]: + if export_me(prim): + new_ast = value_to_ast(prim) + if isinstance(new_ast, ast.AST): + ast_list.append(new_ast) + return ast_list # NORMAL FUNCTION CALL # @@ -623,15 +633,15 @@ class Primitive(object): return (callable(candidate) and candidate in Primitive.LOOP_CONTROLLERS) - # look at the first constant argument - first_const = self.constant_args.get(0, None) - if _is_loop_controller(first_const): - return first_const - - # look at the first slot wrapper - first_wrapper = self.slot_wrappers.get(0, None) - if _is_loop_controller(first_wrapper): - return first_wrapper + for desc in self.arg_descs: + if isinstance(desc, ConstantArg): + value = desc.get() + if _is_loop_controller(value): + return value + elif isinstance(desc, ArgSlot): + wrapper = desc.wrapper + if _is_loop_controller(wrapper): + return wrapper # no controller found raise ValueError("found no loop controller for " + repr(self)) @@ -1080,7 +1090,6 @@ class ArgSlot(object): [value_to_ast(arg) for arg in args]) if slot.call_arg: # call and pass on the return value - was_argument_called = True if convert_to_ast: called_argument = call_ast else: @@ -1088,12 +1097,10 @@ class ArgSlot(object): else: # don't call and pass on the callable if convert_to_ast: - was_argument_called = True called_argument = ast.Lambda(body=call_ast, args=[], vararg=None, kwarg=None, defaults=[]) elif args: - was_argument_called = True if isinstance(func, Primitive): called_argument = func.fill_slots(*args) else: diff --git a/TurtleArt/tatype.py b/TurtleArt/tatype.py index e6ffbb9..477e028 100644 --- a/TurtleArt/tatype.py +++ b/TurtleArt/tatype.py @@ -106,10 +106,11 @@ def get_type(x): else: return (get_type(value)[0], True) elif isinstance(x, ast.Call): - if x.func.__name__ in ('float', 'int'): - return (x.func.__name__, True) - elif x.func.__name__ in ('repr', 'str', 'unicode'): - return (TYPE_STRING, True) + if isinstance(x.func, ast.Name): + if x.func.id in ('float', 'int'): + return (x.func.__name__, True) + elif x.func.id in ('repr', 'str', 'unicode'): + return (TYPE_STRING, True) return (TYPE_OBJECT, isinstance(x, ast.AST)) @@ -317,7 +318,7 @@ def convert(x, new_type, old_type=None, converter=None): kwargs=None) else: func_name = converter.__name__ - return get_call_ast(func_name, y) + return get_call_ast(func_name, [y]) else: return converter(y) |