Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TurtleArt/tablock.py16
-rw-r--r--TurtleArt/taconstants.py2
-rw-r--r--TurtleArt/talogo.py100
-rw-r--r--plugins/turtle_blocks_extras/turtle_blocks_extras.py38
4 files changed, 107 insertions, 49 deletions
diff --git a/TurtleArt/tablock.py b/TurtleArt/tablock.py
index 35dd6d3..a0c0c2e 100644
--- a/TurtleArt/tablock.py
+++ b/TurtleArt/tablock.py
@@ -172,7 +172,6 @@ class Block:
'flow-style-tail': self._make_flow_style_tail,
'flow-style-1arg': self._make_flow_style_1arg,
'flow-style-boolean': self._make_flow_style_boolean,
- 'flow-style-while': self._make_flow_style_while,
'flow-style-else': self._make_flow_style_else,
'collapsible-top': [self._make_collapsible_style_top, True, True],
'collapsible-top-no-arm': [self._make_collapsible_style_top,
@@ -809,21 +808,6 @@ class Block:
['flow', False, self.svg.docks[3][0],
self.svg.docks[3][1], ']']]
- def _make_flow_style_while(self, svg):
- self.svg.expand(self.dx + self.ex, self.ey)
- self.svg.set_slot(True)
- self.svg.set_tab(True)
- self.svg.set_boolean(True)
- self._make_block_graphics(svg, self.svg.basic_flow)
- self.docks = [['flow', True, self.svg.docks[0][0],
- self.svg.docks[0][1]],
- ['bool', False, self.svg.docks[1][0],
- self.svg.docks[1][1], '['],
- ['flow', False, self.svg.docks[2][0],
- self.svg.docks[2][1], ']['],
- ['flow', False, self.svg.docks[3][0],
- self.svg.docks[3][1], ']']]
-
def _make_flow_style_else(self, svg):
self.svg.expand(self.dx + self.ex, self.ey)
self.svg.set_slot(True)
diff --git a/TurtleArt/taconstants.py b/TurtleArt/taconstants.py
index d0b7b46..3a0a4c0 100644
--- a/TurtleArt/taconstants.py
+++ b/TurtleArt/taconstants.py
@@ -227,6 +227,7 @@ VOICES = {'af': 'afrikaans', 'cy': 'welsh-test', 'el': 'greek',
# Macros (groups of blocks)
#
MACROS = {
+ '''
'until':
[[0, 'forever', 0, 0, [None, 2, 1]],
[1, 'vspace', 0, 0, [0, None]],
@@ -239,6 +240,7 @@ MACROS = {
[2, 'ifelse', 0, 0, [0, None, 3, 4, None]],
[3, 'vspace', 0, 0, [2, None]],
[4, 'stopstack', 0, 0, [2, None]]],
+ '''
'kbinput':
[[0, 'forever', 0, 0, [None, 1, None]],
[1, 'kbinput', 0, 0, [0, 2]],
diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py
index b63098d..c7ef76c 100644
--- a/TurtleArt/talogo.py
+++ b/TurtleArt/talogo.py
@@ -67,6 +67,14 @@ class logoerror(Exception):
def __str__(self):
return repr(self.value)
+class HiddenBlock:
+
+ def __init__(self, name):
+ self.name = name
+ self.primitive = name
+ self.connections = []
+ self.docks = []
+
# Utility functions
def _just_stop():
@@ -163,6 +171,11 @@ class LogoCode:
self.stacks['stack2'] = None
self.tw.saving_svg = False
+ # Save state in case there is a hidden macro expansion
+ saveblocks = None
+ saveblk = blk
+ savewhileblks = []
+
if self.trace > 0:
self.update_values = True
else:
@@ -173,10 +186,10 @@ class LogoCode:
if b.name == 'hat1':
code = self._blocks_to_code(b)
self.stacks['stack1'] = self._readline(code)
- if b.name == 'hat2':
+ elif b.name == 'hat2':
code = self._blocks_to_code(b)
self.stacks['stack2'] = self._readline(code)
- if b.name == 'hat':
+ elif b.name == 'hat':
if b.connections is not None and len(b.connections) > 1 and \
b.connections[1] is not None:
code = self._blocks_to_code(b)
@@ -189,8 +202,84 @@ class LogoCode:
if int(float(x)) == x:
x = int(x)
self.stacks['stack3' + str(x)] = self._readline(code)
+ elif b.name in ['while', 'until']:
+ # Hidden macro expansion: Convert a while or until block into
+ # forever, ifelse, stopstack
+ if saveblocks is None:
+ saveblocks = blocks[:]
+ # Replace the while block
+ foreverblk = HiddenBlock('forever')
+ ifelseblk = HiddenBlock('ifelse')
+ stopstackblk = HiddenBlock('stopstack')
+ if b.connections is not None:
+ inflow = b.connections[0]
+ boolflow = b.connections[1]
+ whileflow = b.connections[2]
+ outflow = b.connections[3]
+ if inflow is not None:
+ i = inflow.connections.index(b)
+ inflow.connections[i] = foreverblk
+ else:
+ i = None
+ if outflow is not None:
+ j = outflow.connections.index(b)
+ outflow.connections[j] = foreverblk
+ else:
+ j = None
+ # Save the connections so we can restore them later
+ savewhileblks.append([b, i, j])
+ # Assign the connections and build the docks
+ foreverblk.connections.append(inflow)
+ foreverblk.docks.append(['flow', True, 0, 0])
+ foreverblk.connections.append(ifelseblk)
+ foreverblk.docks.append(['flow', False, 0, 0, '['])
+ foreverblk.connections.append(outflow)
+ foreverblk.docks.append(['flow', False, 0, 0, ']'])
+ ifelseblk.connections.append(foreverblk)
+ ifelseblk.docks.append(['flow', True, 0, 0])
+ ifelseblk.connections.append(boolflow)
+ ifelseblk.docks.append(['bool', False, 0, 0])
+ if b.name == 'while':
+ ifelseblk.connections.append(whileflow)
+ ifelseblk.connections.append(stopstackblk)
+ else: # until
+ ifelseblk.connections.append(stopstackblk)
+ ifelseblk.connections.append(whileflow)
+ ifelseblk.docks.append(['flow', False, 0, 0, '['])
+ ifelseblk.docks.append(['flow', False, 0, 0, ']['])
+ ifelseblk.connections.append(None)
+ ifelseblk.docks.append(['flow', False, 0, 0, ']'])
+ stopstackblk.connections.append(ifelseblk)
+ stopstackblk.docks.append(['flow', False, 0, 0])
+ i = blocks.index(b)
+ if i == 0:
+ blocksleft = []
+ else:
+ blocksleft = blocks[0:i]
+ if i == len(blocks) - 1:
+ blocksright = []
+ else:
+ blocksright = blocks[i + 1:]
+ blocks = blocksleft[:]
+ blocks.append(foreverblk)
+ blocks.append(ifelseblk)
+ blocks.append(stopstackblk)
+ blocks.extend(blocksright)
+ if b == blk:
+ blk = foreverblk
code = self._blocks_to_code(blk)
+
+ if saveblocks is not None:
+ # Undo any hidden macro expansion
+ blocks = saveblocks[:]
+ blk = saveblk
+ for b in savewhileblks:
+ if b[1] is not None:
+ b[0].connections[0].connections[b[1]] = b[0]
+ if b[2] is not None:
+ b[0].connections[3].connections[b[2]] = b[0]
+
if run_flag:
# debug_output("running code: %s" % (code), self.tw.running_sugar)
self.start_time = time()
@@ -211,7 +300,12 @@ class LogoCode:
if blk.name == 'savesvg':
self.tw.saving_svg = True
if blk.primitive is not None: # make a tuple (prim, blk)
- code.append((blk.primitive, self.tw.block_list.list.index(blk)))
+ # special case: expand 'while' and 'until' primitives
+ try:
+ code.append((blk.primitive,
+ self.tw.block_list.list.index(blk)))
+ except ValueError:
+ code.append(blk.primitive) # Hidden block
elif len(blk.values) > 0: # Extract the value from content blocks.
if blk.name == 'number':
try:
diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
index d512f54..9369d80 100644
--- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py
+++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
@@ -93,30 +93,23 @@ class Turtle_blocks_extras(Plugin):
colors=["#FFC000", "#A08000"],
help_string=_('Palette of flow operators'))
- '''
- primitive_dictionary['while'] = self._prim_while
+ # internally expanded macro
palette.add_block('while',
style='flow-style-boolean',
label=[_('while'), ' ', ' '],
prim_name='while',
- default=[None, None, 'vspace'],
+ default=[None, None, None],
special_name=_('while'),
help_string=_('do-while-True operator that uses \
boolean operators from Numbers palette'))
- self.tw.lc.def_prim('while', 2, primitive_dictionary['while'], True)
- '''
- # macro
- palette.add_block('while',
- style='flow-style-boolean',
- label=_('while'),
- help_string=_('do-while-True operator that uses \
-boolean operators from Numbers palette'))
-
- # macro
- palette.add_block('until',
+ # internally expanded macro
+ palette.add_block('until',
style='flow-style-boolean',
- label=_('until'),
+ label=[_('until'), ' ', ' '],
+ prim_name='until',
+ default=[None, None, None],
+ special_name=_('until'),
help_string=_('do-until-True operator that uses \
boolean operators from Numbers palette'))
@@ -1278,21 +1271,6 @@ bullets'))
self.tw.lc.update_label_value('time', elapsed_time)
return elapsed_time
- '''
- def _prim_while(self, boolean, blklist): """ Repeat while true:
- won't work as coded as boolean is only calculated once. """
-
- while(True):
- if not boolean:
- break
- self.tw.lc.icall(self.tw.lc.evline, blklist[:])
- yield True
- if self.tw.lc.procstop:
- break
- self.tw.lc.ireturn()
- yield True
- '''
-
# Deprecated blocks
def _prim_t1x1(self, title, media):