Commits

Pierre Carbonnelle  committed 3b79b13

Support for slices of list/tuple.
Must now use X.data and (X.data)[0] instead of list(X), X[0] in calling program.

  • Participants
  • Parent commits fc16973

Comments (0)

Files changed (3)

File pyDatalog/examples/test.py

     X, Y = pyDatalog.variables(2)
     assert (A.c[X]=='a') == [(a,)]
     assert (A.c[X]=='a')[0] == (a,)
-    assert list(X) == [a]
+    assert list(X.data) == [a]
     assert X.v() == a
     assert ((A.c[a]==X) >= X) == 'a'
     assert ((A.c[a]==X) & (A.c[a]==X) >= X) == 'a'
     assert ((A.c[a]==X) & (A.c[b]==X) >= X) == None
     (A.c[X]=='b') & (A.b[X]=='a')
-    assert list(X) == []
+    assert list(X.data) == []
     (A.c[X]=='a') & (A.b[X]=='a')
-    assert list(X) == [a]
+    assert list(X.data) == [a]
     result = (A.c[X]=='a') & (A.b[X]=='a')
     assert result == [(a,)]
     assert (A.c[a] == 'a') == [()]
     assert z.z == 'z'
     assert (Z.z[X]=='z') == [(z,)]
     assert ((Z.z[X]=='z') & (Z.z[X]>'a')) == [(z,)]
-    assert list(X) == [z]
+    assert list(X.data) == [z]
     try:
         a.z == 'z'
     except Exception as e:
     + (p[a] == (1,(2,)))
     assert ( (p[X]==(1,(2,))) & (p[X]==(1, (X2,))) & (Y==X2)) == [('a', 2, 2)]
 
+    # slices
+    assert ((X==(1,2)) & (Y==X[1:2])) == [((1, 2), (2,))]
+    assert ((X==(1,2)) & (Y==X[1])) == [((1, 2), 2)]
+    assert ((X==(1,2)) & (X1==1) & (Y==X[X1])) == [((1, 2), 1, 2)]
+    assert ((X==(1,2)) & (X1==1) & (Y==X[X1:])) == [((1, 2), 1, (2,))]
+    assert ((X==(1,2)) & (X1==1) & (Y==X[X1:X1+1])) == [((1, 2), 1, (2,))]
+
     print("Test completed successfully.")
 
     

File pyDatalog/pyEngine.py

             return environment[self.index-1]
         elif isinstance(self.value, (list, tuple)):
             return tuple(element.eval(environment) for element in self.value)
+        elif isinstance(self.value, slice):
+            return slice(self.value.start.eval(environment), 
+                         self.value.stop.eval(environment),
+                         self.value.step.eval(environment),)
         else:
             return self.value
         
             return self.operand1.eval(env) / self.operand2.eval(env)
         elif self.operator == '//':
             return self.operand1.eval(env) // self.operand2.eval(env)
+        elif self.operator == 'slice':
+            return self.operand1.eval(env).__getitem__(self.operand2.eval(env))
         assert False # dead code
         
 """

File pyDatalog/pyParser.py

         return Operation(self, '/', other)
     def __rfloordiv__(self, other):
         return Operation(other, '//', self)
+
+    def __getitem__(self, keys):
+        """ called when compiling expression[keys] """
+        return Operation(self, 'slice', keys)
+    def __getslice__(self, i, j):
+        return self.__getitem__(slice(i,j))
+    
     
 class VarSymbol(Expression):
     """ represents the symbol of a variable, both inline and in pyDatalog program 
             self._pyD_name = [Expression._for(element) for element in name]
             self._pyD_type = 'tuple'
             self._pyD_lua = pyEngine.VarTuple([e._pyD_lua for e in self._pyD_name])
+        elif isinstance(name, slice):
+            start, stop, step = map(Expression._for, (name.start, name.stop, name.step))
+            self._pyD_name = slice(start, stop, step)
+            self._pyD_type = 'slice'
+            self._pyD_lua = slice(start, stop, step)
         elif forced_type=="constant" or isinstance(name, (int, list, tuple, xrange)) or not name or name[0] not in string.ascii_uppercase + '_':
             self._pyD_name = name
             self._pyD_type = 'constant'
             return pyEngine.Operand('variable', variables.index(self._pyD_name))
         elif self._pyD_type == 'tuple':
             return pyEngine.Operand('tuple', [element.lua_expr(variables) for element in self._pyD_name])
+        elif self._pyD_type == 'slice':
+            return pyEngine.Operand('slice', slice(self._pyD_name.start.lua_expr(variables),
+                                                   self._pyD_name.stop.lua_expr(variables),
+                                                   self._pyD_name.step.lua_expr(variables),))
         else:
             return pyEngine.Operand('constant', self._pyD_name)
     
             for element in self._pyD_name:
                 variables.update(element._variables())
             return variables
+        elif self._pyD_type == 'slice':
+            variables = OrderedDict()
+            variables.update(self._pyD_name.start._variables())
+            variables.update(self._pyD_name.stop._variables())
+            variables.update(self._pyD_name.step._variables())
+            return variables
         else:
             return OrderedDict()
-
+        
 class Symbol(VarSymbol):
     """
     can be constant, list, tuple, variable or predicate name