From 34d13acd6453f0bfea8ac0c55eec4b737bddea5c Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Fri, 08 Nov 2013 13:36:05 +0000 Subject: refactor handling of extra code in python export --- diff --git a/TurtleArt/taexportpython.py b/TurtleArt/taexportpython.py index c3c8e84..1ed1ac5 100644 --- a/TurtleArt/taexportpython.py +++ b/TurtleArt/taexportpython.py @@ -123,13 +123,6 @@ def _action_stack_to_python(block, tw, name="start"): # serialize the ASTs into python code generated_code = codegen.to_source(action_stack_ast) - # FIXME: there must be a better way to do this using the AST - # patch code to include missing get_active_turtle() calls - if generated_code.count('turtles.set_turtle') > 0: - generated_code = _insert_extra_code( - generated_code, 'turtles.set_turtle', - 'turtle = turtles.get_active_turtle()\n') - # wrap the action stack setup code around everything name_id = _make_identifier(name) if name == 'start': @@ -152,27 +145,6 @@ def _action_stack_to_python(block, tw, name="start"): return "".join(snippets) -def _insert_extra_code(generated_code, target, insert): - """ Add extra code when needed """ - tmp_code = '' - while target in generated_code: - i = generated_code.index(target) - if i == 0: - indent = 0 - else: - indent = 0 - while generated_code[i - 1 - indent] == ' ': - indent += 1 - while generated_code[i] != '\n': - i += 1 - i += 1 # include the newline - tmp_code += generated_code[0:i] - for j in range(indent): - tmp_code += ' ' - tmp_code += insert - generated_code = generated_code[i:] - return tmp_code + generated_code - def _walk_action_stack(top_block, lc, convert_me=True): """ Turn a stack of blocks into a list of ASTs convert_me -- convert values and Primitives to ASTs or return them diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index f4511df..775af0f 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -735,6 +735,9 @@ class LogoCode: """ Stop execution of a stack """ self.procstop = True + def prim_turtle(self, name): + self.tw.turtles.set_turtle(name) + def prim_wait(self, wait_time): """ Show the turtle while we wait """ self.tw.turtles.get_active_turtle().show() @@ -1357,7 +1360,7 @@ class LogoCode: first_label_blk = HiddenBlock('string', value=action_flow_name) # Assign new connections and build the docks - if inflow is not None: + if inflow is not None and b in inflow.connections: i = inflow.connections.index(b) if until_blk and whileflow is not None: inflow.connections[i] = action_first diff --git a/TurtleArt/taprimitive.py b/TurtleArt/taprimitive.py index 7f9d76c..e59d3fd 100644 --- a/TurtleArt/taprimitive.py +++ b/TurtleArt/taprimitive.py @@ -488,6 +488,12 @@ class Primitive(object): ast_list.append(new_ast) return ast_list + # set turtle + elif self == LogoCode.prim_turtle: + text = 'turtle = turtles.get_active_turtle()' + return [get_call_ast('logo.prim_turtle', new_arg_asts), + ast_extensions.ExtraCode(text)] + # comment elif self == Primitive.comment: if isinstance(new_arg_asts[0], ast.Str): @@ -1149,6 +1155,10 @@ def ast_yield_true(): return ast.Yield(value=ast.Name(id='True', ctx=ast.Load)) +def ast_turtle(): + return ast.Turtle(value=None) + + def export_me(something): """ Return True iff this is not a Primitive or its export_me attribute is True, i.e. everything is exportable except for Primitives with diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py index beed99d..c35125b 100644 --- a/TurtleArt/taturtle.py +++ b/TurtleArt/taturtle.py @@ -347,12 +347,7 @@ class Turtle: def set_heading(self, heading, share=True): ''' Set the turtle heading (one shape per 360/SHAPES degrees) ''' - try: - self._heading = heading - except (TypeError, ValueError): - debug_output('bad value sent to %s' % (__name__), - self._turtles.turtle_window.running_sugar) - return + self._heading = heading self._heading %= 360 self._update_sprite_heading() @@ -384,12 +379,7 @@ class Turtle: else: color = self._pen_color - try: - self._pen_color = color - except (TypeError, ValueError): - debug_output('bad value sent to %s' % (__name__), - self._turtles.turtle_window.running_sugar) - return + self._pen_color = color self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade, gray=self._pen_gray, @@ -403,12 +393,7 @@ class Turtle: def set_gray(self, gray=None, share=True): ''' Set the pen gray level for this turtle. ''' if gray is not None: - try: - self._pen_gray = gray - except (TypeError, ValueError): - debug_output('bad value sent to %s' % (__name__), - self._turtles.turtle_window.running_sugar) - return + self._pen_gray = gray if self._pen_gray < 0: self._pen_gray = 0 @@ -427,12 +412,7 @@ class Turtle: def set_shade(self, shade=None, share=True): ''' Set the pen shade for this turtle. ''' if shade is not None: - try: - self._pen_shade = shade - except (TypeError, ValueError): - debug_output('bad value sent to %s' % (__name__), - self._turtles.turtle_window.running_sugar) - return + self._pen_shade = shade self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade, gray=self._pen_gray, @@ -446,12 +426,7 @@ class Turtle: def set_pen_size(self, pen_size=None, share=True): ''' Set the pen size for this turtle. ''' if pen_size is not None: - try: - self._pen_size = max(0, pen_size) - except (TypeError, ValueError): - debug_output('bad value sent to %s' % (__name__), - self._turtles.turtle_window.running_sugar) - return + self._pen_size = max(0, pen_size) self._turtles.turtle_window.canvas.set_pen_size( self._pen_size * self._turtles.turtle_window.coord_scale) diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py index 8d5ab91..e6f2989 100644 --- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py +++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py @@ -787,7 +787,7 @@ module found in the Journal')) string_or_number=True, help_string=_('chooses which turtle to command')) self.tw.lc.def_prim('addturtle', 1, - Primitive(self.tw.turtles.set_turtle, + Primitive(self.tw.lc.prim_turtle, arg_descs=[ArgSlot(TYPE_STRING)])) palette.add_block('turtlex', diff --git a/util/ast_extensions.py b/util/ast_extensions.py index 3335afb..d46bdb0 100644 --- a/util/ast_extensions.py +++ b/util/ast_extensions.py @@ -24,6 +24,23 @@ import ast +class ExtraCode(ast.stmt): + """Adds extra content to a primitive needed in Python code, e.g., + changes to the turtle (e.g., prim_turtle) require the addition of + turtle = turtles.get_active_turtle() + Extends the Python abstract grammar by the following: stmt + = ExtraContent(string text) | ... """ + + _fields = ('text') + + def __init__(self, text="", lineno=1, col_offset=0): + """ text -- the textual content of the comment, i.e. everything + directly following the hashtag until the next newline """ + self.text = text + self.lineno = lineno + self.col_offset = col_offset + + class Comment(ast.stmt): """ An inline comment, starting with a hashtag (#). Extends the Python abstract grammar by the following: diff --git a/util/codegen.py b/util/codegen.py index 3785085..46184e7 100644 --- a/util/codegen.py +++ b/util/codegen.py @@ -35,7 +35,7 @@ Modified by Marion Zepf. """ from ast import * -from ast_extensions import Comment +from ast_extensions import Comment, ExtraCode def to_source(node, indent_with=' ' * 4, add_line_information=False): @@ -362,6 +362,10 @@ class SourceGenerator(NodeVisitor): self.newline(node) self.write('#' + str(node.text)) + def visit_ExtraCode(self, node): + self.newline(node) + self.write(str(node.text)) + # Expressions def visit_Attribute(self, node): -- cgit v0.9.1