about summary refs log tree commit diff stats
path: root/miasm2/expression/expression.py
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2015-02-23 11:29:10 +0100
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2015-02-23 12:52:49 +0100
commit6f931cb489f9551191f8e5910b08c351a7cd49b7 (patch)
treef59ba34e4c45a7b4990afb5ea4bee077d8e8dee9 /miasm2/expression/expression.py
parent835582686b695451202c89884516f16da45f3bac (diff)
downloadmiasm-6f931cb489f9551191f8e5910b08c351a7cd49b7.tar.gz
miasm-6f931cb489f9551191f8e5910b08c351a7cd49b7.zip
Expression: use private attributes in expression
Diffstat (limited to '')
-rw-r--r--miasm2/expression/expression.py424
1 files changed, 211 insertions, 213 deletions
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index aa213dc8..20a7ca52 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -125,6 +125,9 @@ class Expr(object):
     def __init__(self, arg):
         self.arg = arg
 
+    size = property(lambda self: self._size)
+    hash = property(lambda self: self._hash)
+
     # Common operations
 
     def __str__(self):
@@ -155,7 +158,7 @@ class Expr(object):
 
     def __eq__(self, a):
         if isinstance(a, Expr):
-            return self._hash == a._hash
+            return self.hash == a.hash
         else:
             return False
 
@@ -230,11 +233,11 @@ class Expr(object):
                 if e.is_associative():
                     # ((a+b) + c) => (a + b + c)
                     args = []
-                    for a in e.args:
-                        if isinstance(a, ExprOp) and e.op == a.op:
-                            args += a.args
+                    for arg in e.args:
+                        if isinstance(arg, ExprOp) and e.op == arg.op:
+                            args += arg.args
                         else:
-                            args.append(a)
+                            args.append(arg)
                     args = canonize_expr_list(args)
                     new_e = ExprOp(e.op, *args)
                 else:
@@ -324,19 +327,18 @@ class ExprInt(Expr):
         if not is_modint(arg):
             raise ValueError('arg must by numpy int! %s' % arg)
 
-        self.__arg = arg
-        self.__size = self.arg.size
-        self._hash = self.exprhash()
+        self._arg = arg
+        self._size = self.arg.size
+        self._hash = self._exprhash()
 
-    size = property(lambda self: self.__size)
-    arg = property(lambda self: self.__arg)
+    arg = property(lambda self: self._arg)
 
     def __get_int(self):
         "Return self integer representation"
-        return int(self.arg & size2mask(self.size))
+        return int(self._arg & size2mask(self._size))
 
     def __str__(self):
-        if self.arg < 0:
+        if self._arg < 0:
             return str("-0x%X" % (- self.__get_int()))
         else:
             return str("0x%X" % self.__get_int())
@@ -350,8 +352,8 @@ class ExprInt(Expr):
     def get_w(self):
         return set()
 
-    def exprhash(self):
-        return hash((EXPRINT, self.arg, self.size))
+    def _exprhash(self):
+        return hash((EXPRINT, self._arg, self._size))
 
     def __contains__(self, e):
         return self == e
@@ -364,7 +366,7 @@ class ExprInt(Expr):
         return self
 
     def copy(self):
-        return ExprInt(self.arg)
+        return ExprInt(self._arg)
 
     def depth(self):
         return 1
@@ -389,14 +391,13 @@ class ExprId(Expr):
         @size: int, identifier's size
         """
 
-        self.__name, self.__size = name, size
-        self._hash = self.exprhash()
+        self._name, self._size = name, size
+        self._hash = self._exprhash()
 
-    size = property(lambda self: self.__size)
-    name = property(lambda self: self.__name)
+    name = property(lambda self: self._name)
 
     def __str__(self):
-        return str(self.name)
+        return str(self._name)
 
     def get_r(self, mem_read=False, cst_read=False):
         return set([self])
@@ -404,22 +405,22 @@ class ExprId(Expr):
     def get_w(self):
         return set([self])
 
-    def exprhash(self):
+    def _exprhash(self):
         # TODO XXX: hash size ??
-        return hash((EXPRID, self.name, self.__size))
+        return hash((EXPRID, self._name, self._size))
 
     def __contains__(self, e):
         return self == e
 
     def __repr__(self):
-        return Expr.__repr__(self)[:-1] + " %s>" % self.name
+        return Expr.__repr__(self)[:-1] + " %s>" % self._name
 
     @visit_chk
     def visit(self, cb, tv=None):
         return self
 
     def copy(self):
-        return ExprId(self.name, self.size)
+        return ExprId(self._name, self._size)
 
     def depth(self):
         return 1
@@ -444,85 +445,84 @@ class ExprAff(Expr):
         if dst.size != src.size:
             raise ValueError(
                 "sanitycheck: ExprAff args must have same size! %s" %
-                             ([(str(x), x.size) for x in [dst, src]]))
+                             ([(str(arg), arg.size) for arg in [dst, src]]))
 
         if isinstance(dst, ExprSlice):
             # Complete the source with missing slice parts
-            self.__dst = dst.arg
+            self._dst = dst.arg
             rest = [(ExprSlice(dst.arg, r[0], r[1]), r[0], r[1])
                     for r in dst.slice_rest()]
             all_a = [(src, dst.start, dst.stop)] + rest
             all_a.sort(key=lambda x: x[1])
-            self.__src = ExprCompose(all_a)
+            self._src = ExprCompose(all_a)
 
         else:
-            self.__dst, self.__src = dst, src
+            self._dst, self._src = dst, src
 
-        self.__size = self.dst.size
-        self._hash = self.exprhash()
+        self._size = self.dst.size
+        self._hash = self._exprhash()
 
-    size = property(lambda self: self.__size)
-    dst = property(lambda self: self.__dst)
-    src = property(lambda self: self.__src)
+    dst = property(lambda self: self._dst)
+    src = property(lambda self: self._src)
 
     def __str__(self):
-        return "%s = %s" % (str(self.dst), str(self.src))
+        return "%s = %s" % (str(self._dst), str(self._src))
 
     def get_r(self, mem_read=False, cst_read=False):
-        r = self.src.get_r(mem_read, cst_read)
-        if isinstance(self.dst, ExprMem):
-            r.update(self.dst.arg.get_r(mem_read, cst_read))
-        return r
+        elements = self._src.get_r(mem_read, cst_read)
+        if isinstance(self._dst, ExprMem):
+            elements.update(self._dst.arg.get_r(mem_read, cst_read))
+        return elements
 
     def get_w(self):
-        if isinstance(self.dst, ExprMem):
-            return set([self.dst])  # [memreg]
+        if isinstance(self._dst, ExprMem):
+            return set([self._dst])  # [memreg]
         else:
-            return self.dst.get_w()
+            return self._dst.get_w()
 
-    def exprhash(self):
-        return hash((EXPRAFF, self.dst._hash, self.src._hash))
+    def _exprhash(self):
+        return hash((EXPRAFF, self._dst.hash, self._src.hash))
 
     def __contains__(self, e):
-        return self == e or self.src.__contains__(e) or self.dst.__contains__(e)
+        return self == e or self._src.__contains__(e) or self._dst.__contains__(e)
 
     # XXX /!\ for hackish expraff to slice
     def get_modified_slice(self):
         """Return an Expr list of extra expressions needed during the
         object instanciation"""
 
-        dst = self.dst
-        if not isinstance(self.src, ExprCompose):
+        dst = self._dst
+        if not isinstance(self._src, ExprCompose):
             raise ValueError("Get mod slice not on expraff slice", str(self))
         modified_s = []
-        for x in self.src.args:
-            if (not isinstance(x[0], ExprSlice) or
-                    x[0].arg != dst or
-                    x[1] != x[0].start or
-                    x[2] != x[0].stop):
+        for arg in self._src.args:
+            if (not isinstance(arg[0], ExprSlice) or
+                    arg[0].arg != dst or
+                    arg[1] != arg[0].start or
+                    arg[2] != arg[0].stop):
                 # If x is not the initial expression
-                modified_s.append(x)
+                modified_s.append(arg)
         return modified_s
 
     @visit_chk
     def visit(self, cb, tv=None):
-        dst, src = self.dst.visit(cb, tv), self.src.visit(cb, tv)
-        if dst == self.dst and src == self.src:
+        dst, src = self._dst.visit(cb, tv), self._src.visit(cb, tv)
+        if dst == self._dst and src == self._src:
             return self
         else:
             return ExprAff(dst, src)
 
     def copy(self):
-        return ExprAff(self.dst.copy(), self.src.copy())
+        return ExprAff(self._dst.copy(), self._src.copy())
 
     def depth(self):
-        return max(self.src.depth(), self.dst.depth()) + 1
+        return max(self._src.depth(), self._dst.depth()) + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        for a in [self.src, self.dst]:
-            a.graph_recursive(graph)
-            graph.add_uniq_edge(self, a)
+        for arg in [self._src, self._dst]:
+            arg.graph_recursive(graph)
+            graph.add_uniq_edge(self, arg)
 
 
 class ExprCond(Expr):
@@ -542,64 +542,64 @@ class ExprCond(Expr):
         @src2: Expr, value if condition is evaled zero
         """
 
-        self.__cond, self.__src1, self.__src2 = cond, src1, src2
         assert(src1.size == src2.size)
-        self.__size = self.src1.size
-        self._hash = self.exprhash()
 
-    size = property(lambda self: self.__size)
-    cond = property(lambda self: self.__cond)
-    src1 = property(lambda self: self.__src1)
-    src2 = property(lambda self: self.__src2)
+        self._cond, self._src1, self._src2 = cond, src1, src2
+        self._size = self.src1.size
+        self._hash = self._exprhash()
+
+    cond = property(lambda self: self._cond)
+    src1 = property(lambda self: self._src1)
+    src2 = property(lambda self: self._src2)
 
     def __str__(self):
-        return "(%s?(%s,%s))" % (str(self.cond), str(self.src1), str(self.src2))
+        return "(%s?(%s,%s))" % (str(self._cond), str(self._src1), str(self._src2))
 
     def get_r(self, mem_read=False, cst_read=False):
-        out_src1 = self.src1.get_r(mem_read, cst_read)
-        out_src2 = self.src2.get_r(mem_read, cst_read)
-        return self.cond.get_r(mem_read,
-                               cst_read).union(out_src1).union(out_src2)
+        out_src1 = self._src1.get_r(mem_read, cst_read)
+        out_src2 = self._src2.get_r(mem_read, cst_read)
+        return self._cond.get_r(mem_read,
+                                cst_read).union(out_src1).union(out_src2)
 
     def get_w(self):
         return set()
 
-    def exprhash(self):
-        return hash((EXPRCOND, self.cond._hash,
-                     self.src1._hash, self.src2._hash))
+    def _exprhash(self):
+        return hash((EXPRCOND, self.cond.hash,
+                     self._src1.hash, self._src2.hash))
 
     def __contains__(self, e):
         return (self == e or
-                self.cond.__contains__(e) or
-                self.src1.__contains__(e) or
-                self.src2.__contains__(e))
+                self._cond.__contains__(e) or
+                self._src1.__contains__(e) or
+                self._src2.__contains__(e))
 
     @visit_chk
     def visit(self, cb, tv=None):
-        cond = self.cond.visit(cb, tv)
-        src1 = self.src1.visit(cb, tv)
-        src2 = self.src2.visit(cb, tv)
-        if cond == self.cond and \
-                src1 == self.src1 and \
-                src2 == self.src2:
+        cond = self._cond.visit(cb, tv)
+        src1 = self._src1.visit(cb, tv)
+        src2 = self._src2.visit(cb, tv)
+        if (cond == self._cond and
+            src1 == self._src1 and
+            src2 == self._src2):
             return self
         return ExprCond(cond, src1, src2)
 
     def copy(self):
-        return ExprCond(self.cond.copy(),
-                        self.src1.copy(),
-                        self.src2.copy())
+        return ExprCond(self._cond.copy(),
+                        self._src1.copy(),
+                        self._src2.copy())
 
     def depth(self):
-        return max(self.cond.depth(),
-                   self.src1.depth(),
-                   self.src2.depth()) + 1
+        return max(self._cond.depth(),
+                   self._src1.depth(),
+                   self._src2.depth()) + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        for a in [self.cond, self.src1, self.src2]:
-            a.graph_recursive(graph)
-            graph.add_uniq_edge(self, a)
+        for arg in [self._cond, self._src1, self._src2]:
+            arg.graph_recursive(graph)
+            graph.add_uniq_edge(self, arg)
 
 
 class ExprMem(Expr):
@@ -620,51 +620,50 @@ class ExprMem(Expr):
             raise ValueError(
                 'ExprMem: arg must be an Expr (not %s)' % type(arg))
 
-        self.__arg, self.__size = arg, size
-        self._hash = self.exprhash()
+        self._arg, self._size = arg, size
+        self._hash = self._exprhash()
 
-    size = property(lambda self: self.__size)
-    arg = property(lambda self: self.__arg)
+    arg = property(lambda self: self._arg)
 
     def __str__(self):
-        return "@%d[%s]" % (self.size, str(self.arg))
+        return "@%d[%s]" % (self._size, str(self._arg))
 
     def get_r(self, mem_read=False, cst_read=False):
         if mem_read:
-            return set(self.arg.get_r(mem_read, cst_read).union(set([self])))
+            return set(self._arg.get_r(mem_read, cst_read).union(set([self])))
         else:
             return set([self])
 
     def get_w(self):
         return set([self])  # [memreg]
 
-    def exprhash(self):
-        return hash((EXPRMEM, self.arg._hash, self.__size))
+    def _exprhash(self):
+        return hash((EXPRMEM, self._arg.hash, self._size))
 
     def __contains__(self, e):
-        return self == e or self.arg.__contains__(e)
+        return self == e or self._arg.__contains__(e)
 
     @visit_chk
     def visit(self, cb, tv=None):
-        arg = self.arg.visit(cb, tv)
-        if arg == self.arg:
+        arg = self._arg.visit(cb, tv)
+        if arg == self._arg:
             return self
-        return ExprMem(arg, self.size)
+        return ExprMem(arg, self._size)
 
     def copy(self):
-        arg = self.arg.copy()
-        return ExprMem(arg, size=self.size)
+        arg = self._arg.copy()
+        return ExprMem(arg, size=self._size)
 
     def is_op_segm(self):
-        return isinstance(self.arg, ExprOp) and self.arg.op == 'segm'
+        return isinstance(self._arg, ExprOp) and self._arg.op == 'segm'
 
     def depth(self):
-        return self.arg.depth() + 1
+        return self._arg.depth() + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        self.arg.graph_recursive(graph)
-        graph.add_uniq_edge(self, self.arg)
+        self._arg.graph_recursive(graph)
+        graph.add_uniq_edge(self, self._arg)
 
 
 class ExprOp(Expr):
@@ -683,48 +682,48 @@ class ExprOp(Expr):
         @*args: Expr, operand list
         """
 
-        sizes = set([x.size for x in args])
+        sizes = set([arg.size for arg in args])
 
-        if None not in sizes and len(sizes) != 1:
+        if len(sizes) != 1:
             # Special cases : operande sizes can differ
             if op not in ["segm"]:
                 raise ValueError(
                     "sanitycheck: ExprOp args must have same size! %s" %
-                                 ([(str(x), x.size) for x in args]))
+                                 ([(str(arg), arg.size) for arg in args]))
 
         if not isinstance(op, str):
             raise ValueError("ExprOp: 'op' argument must be a string")
 
-        self.__op, self.__args = op, tuple(args)
+        self._op, self._args = op, tuple(args)
 
         # Set size for special cases
-        if self.op in [
+        if self._op in [
                 '==', 'parity', 'fcom_c0', 'fcom_c1', 'fcom_c2', 'fcom_c3',
                 "access_segment_ok", "load_segment_limit_ok", "bcdadd_cf",
                 "ucomiss_zf", "ucomiss_pf", "ucomiss_cf"]:
             sz = 1
-        elif self.op in [TOK_INF, TOK_INF_SIGNED,
-                         TOK_INF_UNSIGNED, TOK_INF_EQUAL,
-                         TOK_INF_EQUAL_SIGNED, TOK_INF_EQUAL_UNSIGNED,
-                         TOK_EQUAL, TOK_POS,
-                         TOK_POS_STRICT,
-                         ]:
+        elif self._op in [TOK_INF, TOK_INF_SIGNED,
+                          TOK_INF_UNSIGNED, TOK_INF_EQUAL,
+                          TOK_INF_EQUAL_SIGNED, TOK_INF_EQUAL_UNSIGNED,
+                          TOK_EQUAL, TOK_POS,
+                          TOK_POS_STRICT,
+                          ]:
             sz = 1
-        elif self.op in ['mem_16_to_double', 'mem_32_to_double',
-                         'mem_64_to_double', 'mem_80_to_double',
-                         'int_16_to_double', 'int_32_to_double',
-                         'int_64_to_double', 'int_80_to_double']:
+        elif self._op in ['mem_16_to_double', 'mem_32_to_double',
+                          'mem_64_to_double', 'mem_80_to_double',
+                          'int_16_to_double', 'int_32_to_double',
+                          'int_64_to_double', 'int_80_to_double']:
             sz = 64
-        elif self.op in ['double_to_mem_16', 'double_to_int_16', 'double_trunc_to_int_16']:
+        elif self._op in ['double_to_mem_16', 'double_to_int_16', 'double_trunc_to_int_16']:
             sz = 16
-        elif self.op in ['double_to_mem_32', 'double_to_int_32', 'double_trunc_to_int_32']:
+        elif self._op in ['double_to_mem_32', 'double_to_int_32', 'double_trunc_to_int_32']:
             sz = 32
-        elif self.op in ['double_to_mem_64', 'double_to_int_64', 'double_trunc_to_int_64']:
+        elif self._op in ['double_to_mem_64', 'double_to_int_64', 'double_trunc_to_int_64']:
             sz = 64
-        elif self.op in ['double_to_mem_80', 'double_to_int_80', 'double_trunc_to_int_80']:
+        elif self._op in ['double_to_mem_80', 'double_to_int_80', 'double_trunc_to_int_80']:
             sz = 80
-        elif self.op in ['segm']:
-            sz = self.args[1].size
+        elif self._op in ['segm']:
+            sz = self._args[1].size
         else:
             if None in sizes:
                 sz = None
@@ -732,141 +731,140 @@ class ExprOp(Expr):
                 # All arguments have the same size
                 sz = list(sizes)[0]
 
-        self.__size = sz
-        self._hash = self.exprhash()
+        self._size = sz
+        self._hash = self._exprhash()
 
-    size = property(lambda self: self.__size)
-    op = property(lambda self: self.__op)
-    args = property(lambda self: self.__args)
+    op = property(lambda self: self._op)
+    args = property(lambda self: self._args)
 
     def __str__(self):
         if self.is_associative():
-            return '(' + self.op.join([str(x) for x in self.args]) + ')'
-        if len(self.args) == 2:
-            return '(' + str(self.args[0]) + \
-                   ' ' + self.op + ' ' + str(self.args[1]) + ')'
-        elif len(self.args) > 2:
-            return self.op + '(' + ', '.join([str(x) for x in self.args]) + ')'
+            return '(' + self._op.join([str(arg) for arg in self._args]) + ')'
+        if len(self._args) == 2:
+            return ('(' + str(self._args[0]) +
+                    ' ' + self.op + ' ' + str(self._args[1]) + ')')
+        elif len(self._args) > 2:
+            return self._op + '(' + ', '.join([str(arg) for arg in self._args]) + ')'
         else:
             return reduce(lambda x, y: x + ' ' + str(y),
-                          self.args,
-                          '(' + str(self.op)) + ')'
+                          self._args,
+                          '(' + str(self._op)) + ')'
 
     def get_r(self, mem_read=False, cst_read=False):
-        return reduce(lambda x, y:
-                      x.union(y.get_r(mem_read, cst_read)), self.args, set())
+        return reduce(lambda elements, arg:
+                      elements.union(arg.get_r(mem_read, cst_read)), self._args, set())
 
     def get_w(self):
         raise ValueError('op cannot be written!', self)
 
-    def exprhash(self):
-        h_hargs = [x._hash for x in self.args]
-        return hash((EXPROP, self.op, tuple(h_hargs)))
+    def _exprhash(self):
+        h_hargs = [arg.hash for arg in self._args]
+        return hash((EXPROP, self._op, tuple(h_hargs)))
 
     def __contains__(self, e):
         if self == e:
             return True
-        for a in self.args:
-            if a.__contains__(e):
+        for arg in self._args:
+            if arg.__contains__(e):
                 return True
         return False
 
     def is_associative(self):
         "Return True iff current operation is associative"
-        return (self.op in ['+', '*', '^', '&', '|'])
+        return (self._op in ['+', '*', '^', '&', '|'])
 
     def is_commutative(self):
         "Return True iff current operation is commutative"
-        return (self.op in ['+', '*', '^', '&', '|'])
+        return (self._op in ['+', '*', '^', '&', '|'])
 
     @visit_chk
     def visit(self, cb, tv=None):
-        args = [a.visit(cb, tv) for a in self.args]
-        modified = any([x[0] != x[1] for x in zip(self.args, args)])
+        args = [arg.visit(cb, tv) for arg in self._args]
+        modified = any([arg[0] != arg[1] for arg in zip(self._args, args)])
         if modified:
-            return ExprOp(self.op, *args)
+            return ExprOp(self._op, *args)
         return self
 
     def copy(self):
-        args = [a.copy() for a in self.args]
-        return ExprOp(self.op, *args)
+        args = [arg.copy() for arg in self._args]
+        return ExprOp(self._op, *args)
 
     def depth(self):
-        depth = [a.depth() for a in self.args]
+        depth = [arg.depth() for arg in self._args]
         return max(depth) + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        for a in self.args:
-            a.graph_recursive(graph)
-            graph.add_uniq_edge(self, a)
+        for arg in self._args:
+            arg.graph_recursive(graph)
+            graph.add_uniq_edge(self, arg)
 
 
 class ExprSlice(Expr):
 
     def __init__(self, arg, start, stop):
         assert(start < stop)
-        self.__arg, self.__start, self.__stop = arg, start, stop
-        self.__size = self.__stop - self.__start
-        self._hash = self.exprhash()
 
-    size = property(lambda self: self.__size)
-    arg = property(lambda self: self.__arg)
-    start = property(lambda self: self.__start)
-    stop = property(lambda self: self.__stop)
+        self._arg, self._start, self._stop = arg, start, stop
+        self._size = self._stop - self._start
+        self._hash = self._exprhash()
+
+    arg = property(lambda self: self._arg)
+    start = property(lambda self: self._start)
+    stop = property(lambda self: self._stop)
 
     def __str__(self):
-        return "%s[%d:%d]" % (str(self.arg), self.start, self.stop)
+        return "%s[%d:%d]" % (str(self._arg), self._start, self._stop)
 
     def get_r(self, mem_read=False, cst_read=False):
-        return self.arg.get_r(mem_read, cst_read)
+        return self._arg.get_r(mem_read, cst_read)
 
     def get_w(self):
-        return self.arg.get_w()
+        return self._arg.get_w()
 
-    def exprhash(self):
-        return hash((EXPRSLICE, self.arg._hash, self.start, self.stop))
+    def _exprhash(self):
+        return hash((EXPRSLICE, self._arg.hash, self._start, self._stop))
 
     def __contains__(self, e):
         if self == e:
             return True
-        return self.arg.__contains__(e)
+        return self._arg.__contains__(e)
 
     @visit_chk
     def visit(self, cb, tv=None):
-        arg = self.arg.visit(cb, tv)
-        if arg == self.arg:
+        arg = self._arg.visit(cb, tv)
+        if arg == self._arg:
             return self
-        return ExprSlice(arg, self.start, self.stop)
+        return ExprSlice(arg, self._start, self._stop)
 
     def copy(self):
-        return ExprSlice(self.arg.copy(), self.start, self.stop)
+        return ExprSlice(self._arg.copy(), self._start, self._stop)
 
     def depth(self):
-        return self.arg.depth() + 1
+        return self._arg.depth() + 1
 
     def slice_rest(self):
         "Return the completion of the current slice"
-        size = self.arg.size
-        if self.start >= size or self.stop > size:
+        size = self._arg.size
+        if self._start >= size or self._stop > size:
             raise ValueError('bad slice rest %s %s %s' %
-                             (size, self.start, self.stop))
+                             (size, self._start, self._stop))
 
-        if self.start == self.stop:
+        if self._start == self._stop:
             return [(0, size)]
 
         rest = []
-        if self.start != 0:
-            rest.append((0, self.start))
-        if self.stop < size:
-            rest.append((self.stop, size))
+        if self._start != 0:
+            rest.append((0, self._start))
+        if self._stop < size:
+            rest.append((self._stop, size))
 
         return rest
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        self.arg.graph_recursive(graph)
-        graph.add_uniq_edge(self, self.arg)
+        self._arg.graph_recursive(graph)
+        graph.add_uniq_edge(self, self._arg)
 
 
 class ExprCompose(Expr):
@@ -883,6 +881,7 @@ class ExprCompose(Expr):
 
     def __init__(self, args):
         """Create an ExprCompose
+        The ExprCompose is contiguous and starts at 0
         @args: tuple(Expr, int, int)
         """
 
@@ -904,62 +903,61 @@ class ExprCompose(Expr):
         for e, a, b in args:
             assert(a >= 0 and b >= 0)
             o.append(tuple([e, a, b]))
-        self.__args = tuple(o)
+        self._args = tuple(o)
 
-        self.__size = max([x[2]
-                           for x in self.args]) - min([x[1] for x in self.args])
-        self._hash = self.exprhash()
+        self._size = self._args[-1][2]
+        self._hash = self._exprhash()
 
-    size = property(lambda self: self.__size)
-    args = property(lambda self: self.__args)
+    args = property(lambda self: self._args)
 
     def __str__(self):
         return '{' + ', '.join(['%s,%d,%d' %
-                                (str(x[0]), x[1], x[2]) for x in self.args]) + '}'
+                                (str(arg[0]), arg[1], arg[2]) for arg in self._args]) + '}'
 
     def get_r(self, mem_read=False, cst_read=False):
-        return reduce(lambda x, y:
-                      x.union(y[0].get_r(mem_read, cst_read)), self.args, set())
+        return reduce(lambda elements, arg:
+                      elements.union(arg[0].get_r(mem_read, cst_read)), self._args, set())
 
     def get_w(self):
-        return reduce(lambda x, y:
-                      x.union(y[0].get_w()), self.args, set())
+        return reduce(lambda elements, arg:
+                      elements.union(arg[0].get_w()), self._args, set())
 
-    def exprhash(self):
-        h_args = [EXPRCOMPOSE] + [(x[0]._hash, x[1], x[2]) for x in self.args]
+    def _exprhash(self):
+        h_args = [EXPRCOMPOSE] + [(arg[0].hash, arg[1], arg[2])
+                                  for arg in self._args]
         return hash(tuple(h_args))
 
     def __contains__(self, e):
         if self == e:
             return True
-        for a in self.args:
-            if a == e:
+        for arg in self._args:
+            if arg == e:
                 return True
-            if a[0].__contains__(e):
+            if arg[0].__contains__(e):
                 return True
         return False
 
     @visit_chk
     def visit(self, cb, tv=None):
-        args = [(a[0].visit(cb, tv), a[1], a[2]) for a in self.args]
-        modified = any([x[0] != x[1] for x in zip(self.args, args)])
+        args = [(arg[0].visit(cb, tv), arg[1], arg[2]) for arg in self._args]
+        modified = any([arg[0] != arg[1] for arg in zip(self._args, args)])
         if modified:
             return ExprCompose(args)
         return self
 
     def copy(self):
-        args = [(a[0].copy(), a[1], a[2]) for a in self.args]
+        args = [(arg[0].copy(), arg[1], arg[2]) for arg in self._args]
         return ExprCompose(args)
 
     def depth(self):
-        depth = [a[0].depth() for a in self.args]
+        depth = [arg[0].depth() for arg in self._args]
         return max(depth) + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        for a in self.args:
-            a[0].graph_recursive(graph)
-            graph.add_uniq_edge(self, a[0])
+        for arg in self.args:
+            arg[0].graph_recursive(graph)
+            graph.add_uniq_edge(self, arg[0])
 
 
 # Expression order for comparaison