# HG changeset patch # User Paul Boddie # Date 1254264787 -7200 # Node ID 5ad00ae3d24d9a15dc6df49161f505fd5e18bdb6 # Parent 49e650e830301095092d28176047bea9127e2107 Added a listiterator implementation. Added more generic native operator support. Added notes on how try...finally might be supported. diff -r 49e650e83030 -r 5ad00ae3d24d lib/builtins.py --- a/lib/builtins.py Wed Sep 30 00:24:41 2009 +0200 +++ b/lib/builtins.py Wed Sep 30 00:53:07 2009 +0200 @@ -163,8 +163,26 @@ return listiterator(self) class listiterator(object): - def __init__(self, l): pass - def next(self): pass + + "Implementation of listiterator." + + def __init__(self, l): + + "Initialise with the given list 'l'." + + self.l = l + self.i = 0 + + def next(self): + + "Return the next item." + + try: + value = self.l[self.i] + self.i += 1 + return value + except IndexError: + raise StopIteration class long(object): def __init__(self, number_or_string=None): pass diff -r 49e650e83030 -r 5ad00ae3d24d micropython/ast.py --- a/micropython/ast.py Wed Sep 30 00:24:41 2009 +0200 +++ b/micropython/ast.py Wed Sep 30 00:53:07 2009 +0200 @@ -1009,7 +1009,17 @@ self.new_op(ClearException()) self.drop_exception_blocks() - def visitTryFinally(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "TryFinally") + def visitTryFinally(self, node): + + """ + Add finally handler, potentially as an exception handler. + Generate body, potentially changing return statements so that they do + not return immediately. + Generate handler, removing the handler from the active handler list, + adding instructions which raise active exceptions. + """ + + raise TranslationNotImplementedError(self.module.full_name(), node, "TryFinally") def visitWhile(self, node): exit_block = self.new_block() diff -r 49e650e83030 -r 5ad00ae3d24d rsvplib.py --- a/rsvplib.py Wed Sep 30 00:24:41 2009 +0200 +++ b/rsvplib.py Wed Sep 30 00:53:07 2009 +0200 @@ -47,6 +47,9 @@ cls = self.machine._get_class("__builtins__", "IndexError") self.index_error = cls.location self.index_error_instance = cls.instance_template_location + cls = self.machine._get_class("__builtins__", "basestring") + self.str_class = cls.location + self.str_instance = cls.instance_template_location self.tuple_class = self.machine.tuple_class self.type_error_instance = self.machine.type_error_instance @@ -88,6 +91,95 @@ self.machine.result = addr, addr + def builtins_logical_op(self, operand_class, op, true_if_incompatible): + frame = self.local_sp_stack[-1] + + # Get operands addresses. + + left_context, left = self.frame_stack[frame] + right_context, right = self.frame_stack[frame + 1] + + # Test operand suitability. + # NOTE: Handle comparisons of incompatible types more appropriately. + + if not (self.machine._CheckInstance(left, operand_class) and self.machine._CheckInstance(right, operand_class)): + if true_if_incompatible: + self.machine.result = self.true_constant, self.true_constant + else: + self.machine.result = self.false_constant, self.false_constant + return + + # NOTE: Assume single location for data. + + left_data = left + 1 + right_data = right + 1 + + # Test the data. + # NOTE: The data is considered ready to use. + + if op(self.machine.load(left_data), self.machine.load(right_data)): + self.machine.result = self.true_constant, self.true_constant + else: + self.machine.result = self.false_constant, self.false_constant + + # Operators. + # Although this takes a short-cut by using the operator module, testing is + # still performed on the operands to ensure that they qualify for these + # native operations. + + def builtins_int_add(self): + return self.builtins_int_arithmetic_op(operator.add) + + def builtins_int_sub(self): + return self.builtins_int_arithmetic_op(operator.sub) + + def builtins_int_pow(self): + return self.builtins_int_arithmetic_op(operator.pow) + + def builtins_int_lt(self): + return self.builtins_logical_op(self.int_class, operator.lt, 0) + + def builtins_int_le(self): + return self.builtins_logical_op(self.int_class, operator.le, 0) + + def builtins_int_gt(self): + return self.builtins_logical_op(self.int_class, operator.gt, 0) + + def builtins_int_ge(self): + return self.builtins_logical_op(self.int_class, operator.ge, 0) + + def builtins_int_eq(self): + return self.builtins_logical_op(self.int_class, operator.eq, 0) + + def builtins_int_ne(self): + return self.builtins_logical_op(self.int_class, operator.ne, 1) + + def builtins_str_lt(self): + return self.builtins_logical_op(self.str_class, operator.lt, 0) + + def builtins_str_le(self): + return self.builtins_logical_op(self.str_class, operator.le, 0) + + def builtins_str_gt(self): + return self.builtins_logical_op(self.str_class, operator.gt, 0) + + def builtins_str_ge(self): + return self.builtins_logical_op(self.str_class, operator.ge, 0) + + def builtins_str_eq(self): + return self.builtins_logical_op(self.str_class, operator.eq, 0) + + def builtins_str_ne(self): + return self.builtins_logical_op(self.str_class, operator.ne, 1) + + def builtins_int_and(self): + return self.builtins_int_arithmetic_op(operator.and_) + + def builtins_int_or(self): + return self.builtins_int_arithmetic_op(operator.or_) + + # Specific operator methods. + def builtins_int_bool(self): frame = self.local_sp_stack[-1] @@ -144,67 +236,7 @@ self.machine.result = addr, addr - def builtins_int_op(self, op, true_if_incompatible): - frame = self.local_sp_stack[-1] - - # Get operands addresses. - - left_context, left = self.frame_stack[frame] - right_context, right = self.frame_stack[frame + 1] - - # Test operand suitability. - # NOTE: Support other types. - # NOTE: Handle comparisons of incompatible types more appropriately. - - if not (self.machine._CheckInstance(left, self.int_class) and self.machine._CheckInstance(right, self.int_class)): - if true_if_incompatible: - self.machine.result = self.true_constant, self.true_constant - else: - self.machine.result = self.false_constant, self.false_constant - return - - # NOTE: Assume single location for data. - - left_data = left + 1 - right_data = right + 1 - - # Test the data. - # NOTE: The data is considered ready to use. - - if op(self.machine.load(left_data), self.machine.load(right_data)): - self.machine.result = self.true_constant, self.true_constant - else: - self.machine.result = self.false_constant, self.false_constant - - def builtins_int_add(self): - return self.builtins_int_arithmetic_op(operator.add) - - def builtins_int_sub(self): - return self.builtins_int_arithmetic_op(operator.sub) - - def builtins_int_lt(self): - return self.builtins_int_op(operator.lt, 0) - - def builtins_int_le(self): - return self.builtins_int_op(operator.le, 0) - - def builtins_int_gt(self): - return self.builtins_int_op(operator.gt, 0) - - def builtins_int_ge(self): - return self.builtins_int_op(operator.ge, 0) - - def builtins_int_eq(self): - return self.builtins_int_op(operator.eq, 0) - - def builtins_int_ne(self): - return self.builtins_int_op(operator.ne, 1) - - def builtins_int_and(self): - return self.builtins_int_arithmetic_op(operator.and_) - - def builtins_int_or(self): - return self.builtins_int_arithmetic_op(operator.or_) + # Various built-in methods. def builtins_bool_bool(self): frame = self.local_sp_stack[-1] @@ -431,6 +463,7 @@ "__builtins__.int.__add__" : builtins_int_add, "__builtins__.int.__radd__" : builtins_int_add, # NOTE: To be made distinct. "__builtins__.int.__sub__" : builtins_int_sub, + "__builtins__.int.__pow__" : builtins_int_pow, "__builtins__.int.__iadd__" : builtins_int_add, "__builtins__.int.__bool__" : builtins_int_bool, "__builtins__.int.__neg__" : builtins_int_neg, @@ -450,6 +483,12 @@ "__builtins__.list.append" : builtins_list_append, "__builtins__.tuple.__len__" : builtins_tuple_len, "__builtins__.tuple.__getitem__" : builtins_tuple_getitem, + "__builtins__.basestring.__lt__" : builtins_str_lt, + "__builtins__.basestring.__le__" : builtins_str_le, + "__builtins__.basestring.__gt__" : builtins_str_gt, + "__builtins__.basestring.__ge__" : builtins_str_ge, + "__builtins__.basestring.__eq__" : builtins_str_eq, + "__builtins__.basestring.__ne__" : builtins_str_ne, # Native initialisers: