git @ Cat's Eye Technologies ALPACA / 4a2fd5f
Merge pull request #14 from catseye/support-python3 Support python3 Chris Pressey authored 2 years ago GitHub committed 2 years ago
7 changed file(s) with 23 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
2323 The `test.sh` script does this.
2424
2525 This distribution also contains the reference implementation of ALPACA
26 version 1.1, written in Python 2.7. Its source is in the `src` directory
26 version 1.1, written in Python (runs under both Python 2.7 and Python 3.x).
27 Its source is in the `src` directory
2728 and `bin/alpaca` is a script to start it from the command line (no
2829 installation is required; just put this `bin` directory on your executable
2930 search path.) See below for more information on the reference
0 #!/usr/bin/env python
0 #!/usr/bin/env python3
11
22 from os.path import realpath, dirname, join
33 import sys
77
88
99 def find_defn(alpaca, type, id):
10 assert isinstance(id, basestring)
1110 for defn in alpaca.defns:
1211 if defn.type == type and defn.id == id:
1312 return defn
14 raise KeyError, "No such %s '%s'" % (type, id)
13 raise KeyError("No such %s '%s'" % (type, id))
1514
1615
1716 def find_state_defn(alpaca, state_id):
2928 def state_defn_is_a(alpaca, state_ast, class_id, verbose=False):
3029 for class_decl in state_ast.classes:
3130 if verbose:
32 print " ===> checking for {} in {}".format(class_id, repr(class_decl))
31 print(" ===> checking for {} in {}".format(class_id, repr(class_decl)))
3332 assert class_decl.type == 'ClassDecl'
3433 if class_id == class_decl.id:
3534 return True
9594 state_map[defn.id] = membership
9695 if defn.type == 'ClassDefn':
9796 class_map[defn.id] = set()
98 for (state_id, class_set) in state_map.iteritems():
97 for (state_id, class_set) in state_map.items():
9998 for class_id in class_set:
10099 class_map.setdefault(class_id, set()).add(state_id)
101100 return class_map
4949 # write the CA's load and dump mappers
5050 repr_map = construct_representation_map(self.alpaca)
5151 self.file.write("function loadMapper(c) {\n")
52 for (char, state_id) in repr_map.iteritems():
52 for (char, state_id) in repr_map.items():
5353 self.file.write(" if (c === '%s') return '%s';\n" %
5454 (char, state_id))
5555 self.file.write("};\n")
5656
5757 self.file.write("function dumpMapper(s) {\n")
58 for (char, state_id) in repr_map.iteritems():
58 for (char, state_id) in repr_map.items():
5959 self.file.write(" if (s === '%s') return '%s';\n" %
6060 (state_id, char))
6161 self.file.write("};\n")
6262
6363 class_map = get_class_map(self.alpaca)
64 for (class_id, state_set) in class_map.iteritems():
64 for (class_id, state_set) in class_map.items():
6565 self.file.write("function is_%s(st) {\n" % class_id)
6666 self.file.write(" return ");
6767 for state_id in state_set:
7878 if pf is not None:
7979 self.file.write("var defaultCell = '%s';\n" % pf.default)
8080 self.file.write("var initialPlayfield = [{}];\n".format(
81 ','.join("[%d, %d, '%s']" % (x, y, c) for (x, y, c) in pf.iteritems())
81 ','.join("[%d, %d, '%s']" % (x, y, c) for (x, y, c) in pf.items())
8282 ))
8383 return True
8484
2929 state_ast = find_state_defn(alpaca, state_id)
3030 result = state_defn_is_a(alpaca, state_ast, class_id, verbose=verbose)
3131 if verbose:
32 print " => checking if {} is_a {}: {}".format(state_id, class_id, result)
32 print(" => checking if {} is_a {}: {}".format(state_id, class_id, result))
3333 return result
3434 elif ast.type in ('StateRefEq', 'StateRefRel'):
3535 pf_state_id = eval_state_ref(playfield, x, y, ast)
6464 pf_state_id = playfield.get(x + dx, y + dy)
6565 if eval_relation(alpaca, playfield, x, y, pf_state_id, rel, verbose=verbose):
6666 count += 1
67 #print "(%d,%d) has %d neighbours that are %r" % (x, y, count, rel)
67 #print("(%d,%d) has %d neighbours that are %r" % (x, y, count, rel))
6868 return count >= int(ast.count)
6969 elif ast.type == 'Relational':
7070 state_id = eval_state_ref(playfield, x, y, ast.lhs)
112112 while x <= playfield.max_x - bb.min_dx:
113113 state_id = playfield.get(x, y)
114114 if verbose:
115 print "state at (%d,%d): %s" % (x, y, state_id)
115 print("state at (%d,%d): %s" % (x, y, state_id))
116116 state_ast = find_state_defn(alpaca, state_id)
117117 if verbose:
118 print " => %r" % state_ast
118 print(" => %r" % state_ast)
119119 classes = state_ast.classes
120120 rules = state_ast.rules
121121 new_state_id = apply_rules(alpaca, playfield, x, y, rules, classes, verbose=verbose)
122122 if new_state_id is None:
123123 new_state_id = state_id
124124 if verbose:
125 print "new state: %s" % new_state_id
125 print("new state: %s" % new_state_id)
126126 new_pf.set(x, y, new_state_id)
127127 x += 1
128128 y += 1
9090 import doctest
9191 (fails, something) = doctest.testmod(analysis)
9292 if fails == 0:
93 print "All tests passed."
93 print("All tests passed.")
9494 sys.exit(0)
9595 else:
9696 sys.exit(1)
118118 if success:
119119 sys.exit(0)
120120 else:
121 print "unsupported backend '%s'" % options.compile_to
121 print("unsupported backend '%s'" % options.compile_to)
122122 sys.exit(1)
123123
124124 display_x1, display_y1, display_x2, display_y2 = None, None, None, None
129129 int(match.group(1)), int(match.group(2)), int(match.group(3)), int(match.group(4))
130130 )
131131 except Exception as e:
132 print "Could not parse '{}'".format(options.display_window)
132 print("Could not parse '{}'".format(options.display_window))
133133 raise
134134
135135 pf = get_defined_playfield(ast)
136136 if pf is None:
137137 if not options.initial_configuration:
138 print "source file does not define an initial configuration,"
139 print "and no cellular automaton configuration file given"
138 print("source file does not define an initial configuration,")
139 print("and no cellular automaton configuration file given")
140140 sys.exit(1)
141141 with open(options.initial_configuration) as f:
142142 pf = Playfield(default_state, repr_map)
148148 # TODO: allow formatting string in the divider, esp.
149149 # to show the # of this generation
150150 if options.divider != '':
151 print options.divider
151 print(options.divider)
152152
153153 def begin_output():
154154 if not options.write_discrete_files_to:
33 self.default = default
44 self.recalculate_limits()
55 self.repr_to_state = map
6 self.state_to_repr = dict([(v, k) for (k, v) in map.iteritems()])
6 self.state_to_repr = dict([(v, k) for (k, v) in map.items()])
77
8 def iteritems(self):
8 def items(self):
99 y = self.min_y
1010 while y <= self.max_y:
1111 x = self.min_x