From b35311891e284acb6b9204a2f94154258da14d6a Mon Sep 17 00:00:00 2001 From: Marion Date: Fri, 16 Aug 2013 09:14:44 +0000 Subject: add Primitives for all 'hat' and 'stack' blocks (not yet exportable) - Move the backend for defining and invoking stacks to talogo (from tabasics and tawindow). - Simplify internal stack naming scheme: convert integers to floats instead of floats to integers. - Don't re-define the 'stack' primitive when a new stack is created. --- diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py index ddaf1c2..d102c95 100644 --- a/TurtleArt/tabasics.py +++ b/TurtleArt/tabasics.py @@ -970,9 +970,9 @@ buttons')) default=_('action'), logo_command='to action', help_string=_('top of nameable action stack')) - self.tw.lc.def_prim('nop3', 1, lambda self, x: None) + self.tw.lc.def_prim('nop3', 1, Primitive(self.tw.lc.prim_define_stack)) - primitive_dictionary['stack'] = self._prim_stack + primitive_dictionary['stack'] = Primitive(self.tw.lc.prim_invoke_stack) palette.add_block('stack', style='basic-style-1arg', label=_('action'), @@ -981,7 +981,8 @@ buttons')) logo_command='action', default=_('action'), help_string=_('invokes named action stack')) - self.tw.lc.def_prim('stack', 1, primitive_dictionary['stack'], True) + self.tw.lc.def_prim('stack', 1, + Primitive(self.tw.lc.prim_invoke_stack), True) primitive_dictionary['setbox'] = Primitive(self.tw.lc.prim_set_box) palette.add_block('storeinbox1', @@ -1063,7 +1064,9 @@ variable')) prim_name='nop1', logo_command='to stack1\n', help_string=_('top of Action 1 stack')) - self.tw.lc.def_prim('nop1', 0, lambda self: None) + self.tw.lc.def_prim('nop1', 0, + Primitive(self.tw.lc.prim_define_stack, + constant_args={0: 'stack1'})) palette.add_block('hat2', hidden=True, @@ -1072,9 +1075,10 @@ variable')) prim_name='nop2', logo_command='to stack2\n', help_string=_('top of Action 2 stack')) - self.tw.lc.def_prim('nop2', 0, lambda self: None) + self.tw.lc.def_prim('nop2', 0, + Primitive(self.tw.lc.prim_define_stack, + constant_args={0: 'stack2'})) - primitive_dictionary['stack1'] = self._prim_stack1 palette.add_block('stack1', hidden=True, style='basic-style-extended-vertical', @@ -1082,9 +1086,11 @@ variable')) prim_name='stack1', logo_command='stack1', help_string=_('invokes Action 1 stack')) - self.tw.lc.def_prim('stack1', 0, primitive_dictionary['stack1'], True) + self.tw.lc.def_prim('stack1', 0, + Primitive(self.tw.lc.prim_invoke_stack, + constant_args={0: 'stack1'}), + True) - primitive_dictionary['stack2'] = self._prim_stack2 palette.add_block('stack2', hidden=True, style='basic-style-extended-vertical', @@ -1092,7 +1098,10 @@ variable')) prim_name='stack2', logo_command='stack2', help_string=_('invokes Action 2 stack')) - self.tw.lc.def_prim('stack2', 0, primitive_dictionary['stack2'], True) + self.tw.lc.def_prim('stack2', 0, + Primitive(self.tw.lc.prim_invoke_stack, + constant_args={0: 'stack2'}), + True) def _trash_palette(self): ''' The basic Turtle Art turtle palette ''' diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index 9cbe1dd..b96a2b9 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -258,10 +258,7 @@ class LogoCode: self.tw.showblocks() self.tw.running_blocks = False return None - if isinstance(convert(x, float, False), float): - if int(float(x)) == x: - x = int(x) - self.stacks['stack3' + str(x)] = self._readline(code) + self.stacks[self._get_stack_key(x)] = self._readline(code) code = self._blocks_to_code(blk) @@ -686,6 +683,31 @@ class LogoCode: name = float(name) return ('box3' + str(name), False) + def prim_define_stack(self, name): + """ Top of a named stack """ + pass + + def prim_invoke_stack(self, name): + """ Process a named stack """ + key = self._get_stack_key(name) + if self.stacks.get(key) is None: + raise logoerror("#nostack") + self.icall(self.evline, self.stacks[key][:]) + yield True + self.procstop = False + self.ireturn() + yield True + + def _get_stack_key(self, name): + """ Return the key used for this stack in the stacks dictionary """ + if name in ('stack1', 'stack2'): + return name + else: + # make sure '5' and '5.0' point to the same action stack + if isinstance(name, (int, long)): + name = float(name) + return 'stack3' + str(name) + def clear_value_blocks(self): if not hasattr(self, 'value_blocks_to_update'): return @@ -1055,14 +1077,14 @@ class LogoCode: # Create a separate stacks for the forever loop and the whileflow code = self._blocks_to_code(forever_blk) - self.stacks['stack3' + str(action_name)] = self._readline(code) + self.stacks[self._get_stack_key(action_name)] = self._readline(code) if until_blk and whileflow is not None: # Create a stack from the whileflow to be called from # action_first, but then reconnect it to the ifelse block c = whileflow.connections[0] whileflow.connections[0] = None code = self._blocks_to_code(whileflow) - self.stacks['stack3' + str(action_flow_name)] = \ + self.stacks[self._get_stack_key(action_flow_name)] = \ self._readline(code) whileflow.connections[0] = c diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index c9b2eb0..467a772 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -4519,7 +4519,6 @@ before making changes to your Turtle Blocks program')) palette = make_palette('blocks') # Create a new block prototype. - primitive_dictionary['stack'] = self._prim_stack palette.add_block('stack_%s' % (name), style='basic-style-1arg', label=name, @@ -4528,7 +4527,6 @@ before making changes to your Turtle Blocks program')) logo_command='action', default=name, help_string=_('invokes named action stack')) - self.lc.def_prim('stack', 1, primitive_dictionary['stack'], True) # Regenerate the palette, which will now include the new block. self.show_toolbar_palette(palette_name_to_index('blocks'), @@ -4589,21 +4587,6 @@ variable')) self.show_toolbar_palette(palette_name_to_index('blocks'), regenerate=True) - def _prim_stack(self, x): - ''' Process a named stack ''' - if isinstance(convert(x, float, False), float): - if int(float(x)) == x: - x = int(x) - if 'stack3' + str(x) not in self.lc.stacks or \ - self.lc.stacks['stack3' + str(x)] is None: - raise logoerror('#nostack') - self.lc.icall(self.lc.evline, - self.lc.stacks['stack3' + str(x)][:]) - yield True - self.lc.procstop = False - self.lc.ireturn() - yield True - def dock_dx_dy(self, block1, dock1n, block2, dock2n): ''' Find the distance between the dock points of two blocks. ''' # Cannot dock a block to itself -- cgit v0.9.1