Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TurtleArt
diff options
context:
space:
mode:
authorMarion <marion.zepf@gmail.com>2013-09-10 22:04:43 (GMT)
committer Marion <marion.zepf@gmail.com>2013-09-10 22:04:43 (GMT)
commit27c87bbc282dcc72fcc137684831551556eb5e24 (patch)
tree584a85d38010d08c531dc71a98acbf92d5446c0e /TurtleArt
parent3d3238126b293f2354b97d7d331fc502b70f198e (diff)
add Primitives for the 'push', 'pop', and 'is empty heap?' blocks
Diffstat (limited to 'TurtleArt')
-rw-r--r--TurtleArt/taexportpython.py1
-rw-r--r--TurtleArt/talogo.py3
-rw-r--r--TurtleArt/taprimitive.py44
-rw-r--r--TurtleArt/tatype.py34
4 files changed, 53 insertions, 29 deletions
diff --git a/TurtleArt/taexportpython.py b/TurtleArt/taexportpython.py
index 19cf48e..3f3a03e 100644
--- a/TurtleArt/taexportpython.py
+++ b/TurtleArt/taexportpython.py
@@ -50,6 +50,7 @@ tw = get_tw()
BOX = {}
ACTION = {}
+heap = []
diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py
index 20a374d..b496ea8 100644
--- a/TurtleArt/talogo.py
+++ b/TurtleArt/talogo.py
@@ -805,6 +805,9 @@ class LogoCode:
name = float(name)
return 'stack3' + str(name)
+ def get_heap(self):
+ return self.heap
+
def clear_value_blocks(self):
if not hasattr(self, 'value_blocks_to_update'):
return
diff --git a/TurtleArt/taprimitive.py b/TurtleArt/taprimitive.py
index 70762f1..b9e74bc 100644
--- a/TurtleArt/taprimitive.py
+++ b/TurtleArt/taprimitive.py
@@ -132,6 +132,8 @@ class Primitive(object):
func_name = "canvas."
elif self.wants_logocode():
func_name = "logo."
+ elif self.wants_heap():
+ func_name = "heap."
elif self.wants_tawindow():
func_name = "tw."
# get the name of the function directly from the function itself
@@ -270,21 +272,23 @@ class Primitive(object):
debug_output("end " + repr(self))
# what does this primitive want as its first argument?
- if new_prim.wants_turtle():
- first_arg = global_objects["turtles"].get_active_turtle()
- elif new_prim.wants_turtles():
- first_arg = global_objects["turtles"]
- elif new_prim.wants_canvas():
- first_arg = global_objects["canvas"]
- elif new_prim.wants_logocode():
- first_arg = global_objects["logo"]
- elif new_prim.wants_tawindow():
- first_arg = global_objects["window"]
- else:
- first_arg = None
+ first_arg = None
+ if not is_bound_method(new_prim.func):
+ if new_prim.wants_turtle():
+ first_arg = global_objects["turtles"].get_active_turtle()
+ elif new_prim.wants_turtles():
+ first_arg = global_objects["turtles"]
+ elif new_prim.wants_canvas():
+ first_arg = global_objects["canvas"]
+ elif new_prim.wants_logocode():
+ first_arg = global_objects["logo"]
+ elif new_prim.wants_heap():
+ first_arg = global_objects["logo"].heap
+ elif new_prim.wants_tawindow():
+ first_arg = global_objects["window"]
# execute the actual function
- if first_arg is None or is_bound_instancemethod(new_prim.func):
+ if first_arg is None:
return_value = new_prim.func(*new_args, **new_kwargs)
else:
return_value = new_prim.func(first_arg, *new_args, **new_kwargs)
@@ -464,6 +468,9 @@ class Primitive(object):
text = ' ' + str(ast_to_value(new_arg_asts[0]))
return ast_extensions.Comment(text)
+ elif self == LogoCode.get_heap:
+ return TypedName(id_='heap', return_type=self.return_type)
+
# NORMAL FUNCTION CALL #
else:
@@ -520,6 +527,12 @@ class Primitive(object):
first argument? """
return self._wants(LogoCode)
+ def wants_heap(self):
+ """ Does this Primitive want to get the heap as its first argument? """
+ return ((hasattr(self.func, '__self__') and
+ isinstance(self.func.__self__, list)) or
+ self.func in list.__dict__.values())
+
def wants_tawindow(self):
""" Does this Primitive want to get the TurtleArtWindow instance
as its first argument? """
@@ -532,10 +545,7 @@ class Primitive(object):
return not is_instancemethod(self.func)
def _wants(self, theClass):
- if is_instancemethod(self.func):
- return self.func.im_class == theClass
- else:
- return False
+ return is_instancemethod(self.func) and self.func.im_class == theClass
# treat the following methods in a special way when converting the
# Primitive to an AST
diff --git a/TurtleArt/tatype.py b/TurtleArt/tatype.py
index 9a8c17d..3a14fbf 100644
--- a/TurtleArt/tatype.py
+++ b/TurtleArt/tatype.py
@@ -46,11 +46,9 @@ class Type(object):
repr(type(other)))
return self.value == other.value
- def __repr__(self):
- return repr(self.constant_name)
-
def __str__(self):
return str(self.constant_name)
+ __repr__ = __str__
class TypeDisjunction(tuple,Type):
@@ -137,7 +135,11 @@ def get_type(x):
return (TYPE_STRING, True)
# unary operands never change the type of their argument
elif isinstance(x, ast.UnaryOp):
- return get_type(x.operand)
+ if issubclass(x.op, ast.Not):
+ # 'not' always returns a boolean
+ return (TYPE_BOOL, True)
+ else:
+ return get_type(x.operand)
# boolean and comparison operators always return a boolean
if isinstance(x, (ast.BoolOp, ast.Compare)):
return (TYPE_BOOL, True)
@@ -159,11 +161,9 @@ def is_instancemethod(method):
# TODO how to access the type `instancemethod` directly?
return type(method).__name__ == "instancemethod"
-def is_bound_instancemethod(method):
- return is_instancemethod(method) and method.im_self is not None
-
-def is_unbound_instancemethod(method):
- return is_instancemethod(method) and method.im_self is None
+def is_bound_method(method):
+ return ((is_instancemethod(method) and method.im_self is not None) or
+ (hasattr(method, '__self__') and method.__self__ is not None))
def is_staticmethod(method):
# TODO how to access the type `staticmethod` directly?
@@ -311,8 +311,8 @@ def convert(x, new_type, old_type=None, converter=None):
if old_type == new_type:
return x
- # special case: 'box' block as an AST
- if isinstance(x, ast.Subscript) and x.value is BOX_AST:
+ # special case: 'box' block (or 'pop' block) as an AST
+ if is_an_ast and old_type == TYPE_BOX:
new_type_ast = ast.Name(id=new_type.constant_name)
return get_call_ast('convert', [x, new_type_ast], return_type=new_type)
@@ -378,7 +378,7 @@ class TypedCall(ast.Call,TypedAST):
class TypedSubscript(ast.Subscript,TypedAST):
- """ Like a Subscript AST, but with a return type """
+ """ Like a Subscript AST, but with a type """
def __init__(self, value, slice_, ctx=ast.Load, return_type=None):
@@ -387,6 +387,16 @@ class TypedSubscript(ast.Subscript,TypedAST):
self._return_type = return_type
+class TypedName(ast.Name,TypedAST):
+ """ Like a Name AST, but with a type """
+
+ def __init__(self, id_, ctx=ast.Load, return_type=None):
+
+ ast.Name.__init__(self, id=id_, ctx=ctx)
+
+ self._return_type = return_type
+
+
def get_call_ast(func_name, args=None, kwargs=None, return_type=None):
""" Return an AST representing the call to a function with the name
func_name, passing it the arguments args (given as a list) and the