Commits

Ronny Pfannschmidt committed bcc0185

switch to a mapping of command counts

  • Participants
  • Parent commits 030a2b4

Comments (0)

Files changed (3)

File whenever/__init__.py

 from .eval import Evaluator
 from pypy.rlib.rrandom import Random
 
-random = Random()
+random = Random(200)
 
 
 class Runner(object):
     __slots__ = 'statements', 'todo'
     def __init__(self, statements):
-        assert isinstance(statements, dict)
         self.statements = statements
-        self.todo = list(statements.keys())
+        items = statements.keys()
+        self.todo = {}
+        for i in range(len(items)):
+            self.todo[items[i]] = 1
+
+    
+    def has_work(self):
+        items = self.todo.keys()
+        for i in range(len(items)):
+            if self.todo[items[i]]:
+                return True
+        return False
 
     def run(self):
-
-        while len(self.todo):
+        i = 1
+        while self.has_work():
             rand = random.random()
-            l = len(self.todo)
+            keys = [x for x, y in self.todo.items() if y]
+            l = len(keys)
 
             number = int(l*rand)
 
-            command = self.todo.pop(number)
+            command = keys[number]
+            tree = self.statements[command]
+            #print tree
 
             evaluator = Evaluator(self.todo)
-            try:
-                evaluator.handle(self.statements[command])
-            except StopIteration:
-                pass
-            if evaluator.keep:
-                self.todo.append(number)
+            evaluator.execute(tree)
+            if not evaluator.keep:
+                if self.todo[command] > 0:
+                    self.todo[command] -= 1
+
+            if i%1000 == 0:
+                print todo

File whenever/eval.py

     __slots__ = 'value',
     def __init__(self, value):
         self.value = value
+    
+    def __repr__(self):
+        return str(self.value)
 
-
+class Paused(Exception):
+    pass
 
 class Evaluator(object):
     __slots__ = 'todo', 'resultstate', 'stack', 'node_stack', 'keep'
         assert isinstance(item, type)
         return item
 
+    def execute(self, node):
+        try:
+            self.handle(node)
+        except Paused:
+            pass
+        except Exception:
+            print node
+            raise
+
     def handle(self, node):
         #print ' '*len(self.node_stack), node.symbol
         self.node_stack.append(node)
 
         #print self.stack
         #print [x.symbol for x in self.node_stack]
+        #print ' '*(len(self.node_stack)-1), node.symbol, '!'
         if not node.symbol[0] == '_':
             handler = self.dispatch[node.symbol]
             handler(self, node)
 
     def handle_integer(self, node):
         if len(node.children) == 2:
-            w_int = self.stack[-1]
-            assert isinstance(w_int, W_Int)
-            w_int.intval = -w_int.intval
+            i = self.pop(W_Int)
+            i.intval = -i.intval
+            self.push(i)
 
     def handle_compare(self, node):
         b = self.pop(W_Int)
         self.push(W_Bool(bool(result)))
 
     def handle_statement(self, node):
+        if len(node.children) == 1:
+            count = 1
+        else:
+            count = self.pop(W_Int).intval
+        number = self.pop(W_Int).intval
+        if number < 0:
+            count = -count
+            number = -number
+        self.todo[number] = max(self.todo[number] + count, 0)
 
-        if len(node.children) == 1:
-            number = self.pop(W_Int)
-            n = number.intval
-            if n < 0:
-                self.todo.remove(-n)
-            else:
-                self.todo.append(n)
-        else:
-            b_count = self.stack.pop()
-            b_number = self.stack.pop()
-            assert isinstance(b_count, W_Int)
-            assert isinstance(b_number, W_Int)
-            count = b_count.intval
-            number = b_number.intval
-            if number < 0:
-                count = -count
-                number = -number
-            if count < 0:
-                for i in range(count):
-                    self.todo.remove(number)
-            else:
-                for i in range(count):
-                    self.todo.append(number)
 
 
 
 
     def handle_function(self, node):
         #XXX: its n
-        w_int = self.stack.pop()
-        assert isinstance(w_int, W_Int)
-        count = 0
-        for i in range(len(self.todo)):
-            if self.todo[i] == w_int.intval:
-                count += 1
-        self.stack.append(W_Int(count))
+        w_int = self.pop(W_Int)
+        self.push(W_Int(self.todo[w_int.intval]))
 
     def handle_bool(self, node):
         val = self.stack.pop()
         if isinstance(val, W_Int):
-            has = False
-            for i in range(len(self.todo)):
-                if self.todo[i] == val.intval:
-                    has = True
-                    break
-
-            self.stack.append(W_Bool(has))
+            number = self.todo[val.intval]
+            self.push(W_Bool(bool(number)))
         else:
-            self.stack.append(val)
+            self.push(val)
 
     def handle_boolean(self, node):
         if len(node.children) == 1:
             return
 
-        a = self.stack.pop()
-        chain = self.stack.pop()
-        b = self.stack.pop()
+        b = self.pop(W_Bool).value
+        op = self.pop(W_Chain).op
+        a = self.pop(W_Bool).value
 
-        assert isinstance(a, W_Bool)
-        assert isinstance(b, W_Bool)
-        assert isinstance(chain, W_Chain)
-        if chain.op == 'a':
-            res = a.value & b.value
-        elif chain.op == 'o':
-            res = a.value | b.value
+        if op == 'a':
+            res = a and b
+        elif op == 'o':
+            res = a or b
         else:
             raise ValueError
-        assert isinstance(res, bool)
-        self.stack.append(W_Bool(res))
+        self.push(W_Bool(res))
 
     def handle_statements(self, node):
         pass
 
     def handle_action(self, node):
         if len(self.stack) >=2 and isinstance(self.stack[-2], W_Action):
-            truth = self.stack.pop()
-            assert isinstance(truth, W_Bool)
+            truth = self.pop(W_Bool).value
             action = self.pop(W_Action).name
-            if not truth.value:
+
+            if not truth:
                 return
 
             if  action == 'defer':
                 self.keep = True
-                raise StopIteration
+                raise Paused
             elif action=='forget':
                 self.keep = False
-                raise StopIteration
+                raise Paused
             elif action=='again':
                 self.keep = True
         else:

File whenever/parse.py

         if len(line) == 0:
             break
         number, commands = parseline(line)
+        #commands.view()
         assert number not in result
         result[number] = commands
     return result