git @ Cat's Eye Technologies ALPACA / 7df1e95
Support including initial configuration in ALPACA description. catseye 12 years ago
6 changed file(s) with 74 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
0 /*
1 John Conway's Game of Life, plus an initial configuration.
2 */
3
4 state Dead " " to Alive when 3 Alive and 5 Dead;
5 state Alive "*" to Dead when 4 Alive or 7 Dead
6 begin
7 **
8 * *
9 *
00 """
11 Direct evaluator of ALPACA AST nodes.
2
3 XXX move some of these out into alpaca.analysis
24
35 """
46
57 from alpaca.ast import AST
8 from alpaca.playfield import Playfield
69
710
811 def eval_state_ref(playfield, x, y, ast):
99102
100103
101104 def get_default_state(ast):
102 map = {}
103105 assert ast.type == 'Alpaca'
104106 defns = ast.children[0]
105107 assert defns.type == 'Definitions'
108110 return defn.value
109111
110112
113 def get_defined_playfield(ast):
114 assert ast.type == 'Alpaca'
115 playast = ast.children[1]
116 assert playast.type == 'Playfield'
117 repr_map = construct_representation_map(ast)
118 pf = Playfield(get_default_state(ast), repr_map)
119 for (x, y, ch) in playast.value:
120 pf.set(x, y, repr_map[ch])
121 pf.recalculate_limits()
122 return pf
123
124
111125 def evolve_playfield(playfield, new_pf, ast):
112126 # XXX TODO + 1, - 1's in here should reflect the maximum
113127 # neighbourhood used by any rule
128 if playfield.min_y is None:
129 return
114130 y = playfield.min_y - 1
115131 while y <= playfield.max_y + 1:
116132 x = playfield.min_x - 1
1111 from alpaca.eval import (
1212 evolve_playfield,
1313 construct_representation_map,
14 get_default_state
14 get_default_state,
15 get_defined_playfield,
1516 )
1617 from alpaca.parser import Parser
1718 from alpaca.playfield import Playfield
5152 default_state = get_default_state(ast)
5253 repr_map = construct_representation_map(ast)
5354
54 # XXX if has_own_defined_playfield(ast): pf = get_playfield_from(ast): else...
55 file = open(args[1])
56 pf = Playfield(default_state, repr_map)
57 pf.load(file)
58 file.close()
55 pf = get_defined_playfield(ast)
56 if pf is None:
57 file = open(args[1])
58 pf = Playfield(default_state, repr_map)
59 pf.load(file)
60 file.close()
5961
6062 count = 0
6163 print str(pf)
7070
7171 def alpaca(self):
7272 defns = []
73 playfield = AST('Playfield', value=None)
7473 defns.append(self.defn())
74 pf = None
7575 while self.scanner.consume(';'):
7676 defns.append(self.defn())
77 if self.scanner.consume('begin'):
78 playfield = self.scanner.read_playfield()
77 # we shan't consume() this token, lest the scanner jump
78 # ahead assuming that the next token is normal. If the
79 # scanner is already on this token, the rest of the scanner
80 # text is the playfield; so we just check on() here.
81 if self.scanner.on('begin'):
82 pf = self.scanner.scan_playfield()
7983 else:
8084 self.scanner.expect('.')
85 playfield = AST('Playfield', value=pf)
8186 return AST('Alpaca', [AST('Definitions', defns), playfield])
8287
8388 def defn(self):
44 self.recalculate_limits()
55 self.map = map
66 self._inverted_map = dict([(v, k) for (k, v) in map.iteritems()])
7
8 def copy(self, pf):
9 y = pf.min_y
10 while y <= pf.max_y:
11 x = pf.min_x
12 while x <= pf.max_x:
13 self.set(x, y, pf.get(x, y))
14 x += 1
15 y += 1
16 self.recalculate_limits()
717
818 def load(self, f):
919 y = 0
5262 def __str__(self):
5363 s = ''
5464 y = self.min_y
65 if y is None:
66 return ''
5567 while y <= self.max_y:
5668 x = self.min_x
5769 while x <= self.max_x:
5151 raise ValueError("this should never happen, "
5252 "self.text=(%s)" % self.text)
5353
54 def scan_playfield(self):
55 """Called when the token which introduces the playfield has
56 already just been scanned.
57
58 """
59 self.scan_pattern(r'[ \t]*', 'whitespace')
60 self.scan_pattern(r'[\n\r]', 'eol')
61 elems = []
62 y = 0
63 while self.text:
64 x = 0
65 while self.scan_pattern(r'[^\n\r]', 'arbitrary character'):
66 #print repr((x, y, self.token))
67 elems.append((x, y, self.token))
68 x += 1
69 self.scan_pattern(r'[\n\r]', 'eol')
70 y += 1
71 return elems
72
5473 def expect(self, token):
5574 if self.token == token:
5675 self.scan()