annotate roundup/mlink_expr.py @ 6401:8bc5faeb7677

Make rev multilink expressions work for anydbm
author Ralf Schlatterbeck <rsc@runtux.com>
date Sat, 08 May 2021 12:52:35 +0200
parents
children a0c0ee3ed8b1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6401
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
1 #
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
2 # Copyright: 2010 Intevation GmbH.
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
3 # 2021 Ralf Schlatterbeck, rsc@runtux.com.
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
4 #
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
5
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
6 # This module is Free Software under the Roundup licensing,
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
7 # see the COPYING.txt file coming with Roundup.
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
8 #
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
9
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
10 class Binary:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
11
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
12 def __init__(self, x, y):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
13 self.x = x
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
14 self.y = y
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
15
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
16 def visit(self, visitor):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
17 self.x.visit(visitor)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
18 self.y.visit(visitor)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
19
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
20 class Unary:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
21
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
22 def __init__(self, x):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
23 self.x = x
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
24
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
25 def generate(self, atom):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
26 return atom(self)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
27
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
28 def visit(self, visitor):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
29 self.x.visit(visitor)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
30
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
31 class Equals(Unary):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
32
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
33 def evaluate(self, v):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
34 return self.x in v
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
35
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
36 def visit(self, visitor):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
37 visitor(self)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
38
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
39 class Empty(Unary):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
40
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
41 def evaluate(self, v):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
42 return not v
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
43
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
44 def visit(self, visitor):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
45 visitor(self)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
46
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
47 class Not(Unary):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
48
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
49 def evaluate(self, v):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
50 return not self.x.evaluate(v)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
51
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
52 def generate(self, atom):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
53 return "NOT(%s)" % self.x.generate(atom)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
54
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
55 class Or(Binary):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
56
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
57 def evaluate(self, v):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
58 return self.x.evaluate(v) or self.y.evaluate(v)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
59
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
60 def generate(self, atom):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
61 return "(%s)OR(%s)" % (
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
62 self.x.generate(atom),
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
63 self.y.generate(atom))
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
64
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
65 class And(Binary):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
66
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
67 def evaluate(self, v):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
68 return self.x.evaluate(v) and self.y.evaluate(v)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
69
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
70 def generate(self, atom):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
71 return "(%s)AND(%s)" % (
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
72 self.x.generate(atom),
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
73 self.y.generate(atom))
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
74
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
75 def compile_expression(opcodes):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
76
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
77 stack = []
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
78 push, pop = stack.append, stack.pop
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
79 for opcode in opcodes:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
80 if opcode == -1: push(Empty(opcode))
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
81 elif opcode == -2: push(Not(pop()))
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
82 elif opcode == -3: push(And(pop(), pop()))
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
83 elif opcode == -4: push(Or(pop(), pop()))
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
84 else: push(Equals(opcode))
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
85
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
86 return pop()
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
87
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
88 class Expression:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
89
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
90 def __init__(self, v):
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
91 try:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
92 opcodes = [int(x) for x in v]
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
93 if min(opcodes) >= -1:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
94 raise ValueError()
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
95
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
96 compiled = compile_expression(opcodes)
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
97 self.evaluate = lambda x: compiled.evaluate([int(y) for y in x])
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
98 except:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
99 if '-1' in v:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
100 v = [x for x in v if int(x) > 0]
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
101 self.evaluate = lambda x: bool(set(x) & set(v)) or not x
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
102 else:
8bc5faeb7677 Make rev multilink expressions work for anydbm
Ralf Schlatterbeck <rsc@runtux.com>
parents:
diff changeset
103 self.evaluate = lambda x: bool(set(x) & set(v))

Roundup Issue Tracker: http://roundup-tracker.org/