Commits

catseye  committed ca8de60

Support including initial configuration in ALPACA description.

  • Participants
  • Parent commits 035ffcd

Comments (0)

Files changed (6)

File eg/life_initial1.alp

+/*
+   John Conway's Game of Life, plus an initial configuration.
+*/
+
+state Dead  " " to Alive when 3 Alive and 5 Dead;
+state Alive "*" to Dead when 4 Alive or 7 Dead
+begin      
+ **
+* *
+  *

File src/alpaca/eval.py

 """
 Direct evaluator of ALPACA AST nodes.
 
+XXX move some of these out into alpaca.analysis
+
 """
 
 from alpaca.ast import AST
+from alpaca.playfield import Playfield
 
 
 def eval_state_ref(playfield, x, y, ast):
 
 
 def get_default_state(ast):
-    map = {}
     assert ast.type == 'Alpaca'
     defns = ast.children[0]
     assert defns.type == 'Definitions'
             return defn.value
 
 
+def get_defined_playfield(ast):
+    assert ast.type == 'Alpaca'
+    playast = ast.children[1]
+    assert playast.type == 'Playfield'
+    repr_map = construct_representation_map(ast)
+    pf = Playfield(get_default_state(ast), repr_map)
+    for (x, y, ch) in playast.value:
+        pf.set(x, y, repr_map[ch])
+    pf.recalculate_limits()
+    return pf
+
+
 def evolve_playfield(playfield, new_pf, ast):
     # XXX TODO + 1, - 1's in here should reflect the maximum
     # neighbourhood used by any rule
+    if playfield.min_y is None:
+        return
     y = playfield.min_y - 1
     while y <= playfield.max_y + 1:
         x = playfield.min_x - 1

File src/alpaca/main.py

 from alpaca.eval import (
     evolve_playfield,
     construct_representation_map,
-    get_default_state
+    get_default_state,
+    get_defined_playfield,
 )
 from alpaca.parser import Parser
 from alpaca.playfield import Playfield
     default_state = get_default_state(ast)
     repr_map = construct_representation_map(ast)
 
-    # XXX if has_own_defined_playfield(ast): pf = get_playfield_from(ast): else...
-    file = open(args[1])
-    pf = Playfield(default_state, repr_map)
-    pf.load(file)
-    file.close()
+    pf = get_defined_playfield(ast)
+    if pf is None:
+        file = open(args[1])
+        pf = Playfield(default_state, repr_map)
+        pf.load(file)
+        file.close()
 
     count = 0
     print str(pf)

File src/alpaca/parser.py

 
     def alpaca(self):
         defns = []
-        playfield = AST('Playfield', value=None)
         defns.append(self.defn())
+        pf = None
         while self.scanner.consume(';'):
             defns.append(self.defn())
-        if self.scanner.consume('begin'):
-            playfield = self.scanner.read_playfield()
+        # we shan't consume() this token, lest the scanner jump
+        # ahead assuming that the next token is normal.  If the
+        # scanner is already on this token, the rest of the scanner
+        # text is the playfield; so we just check on() here.
+        if self.scanner.on('begin'):
+            pf = self.scanner.scan_playfield()
         else:
             self.scanner.expect('.')
+        playfield = AST('Playfield', value=pf)
         return AST('Alpaca', [AST('Definitions', defns), playfield])
 
     def defn(self):

File src/alpaca/playfield.py

         self.map = map
         self._inverted_map = dict([(v, k) for (k, v) in map.iteritems()])
 
+    def copy(self, pf):
+        y = pf.min_y
+        while y <= pf.max_y:
+            x = pf.min_x
+            while x <= pf.max_x:
+                self.set(x, y, pf.get(x, y))
+                x += 1
+            y += 1
+        self.recalculate_limits()
+
     def load(self, f):
         y = 0
         for line in f:
     def __str__(self):
         s = ''
         y = self.min_y
+        if y is None:
+            return ''
         while y <= self.max_y:
             x = self.min_x
             while x <= self.max_x:

File src/alpaca/scanner.py

             raise ValueError("this should never happen, "
                              "self.text=(%s)" % self.text)
 
+    def scan_playfield(self):
+        """Called when the token which introduces the playfield has
+        already just been scanned.
+
+        """
+        self.scan_pattern(r'[ \t]*', 'whitespace')
+        self.scan_pattern(r'[\n\r]', 'eol')
+        elems = []
+        y = 0
+        while self.text:
+            x = 0
+            while self.scan_pattern(r'[^\n\r]', 'arbitrary character'):
+                #print repr((x, y, self.token))
+                elems.append((x, y, self.token))
+                x += 1
+            self.scan_pattern(r'[\n\r]', 'eol')
+            y += 1
+        return elems
+
     def expect(self, token):
         if self.token == token:
             self.scan()