A categorical programming language
修订版 | f36a6db0034bf03bb209dc9539ebb04e3e04d075 (tree) |
---|---|
时间 | 2022-02-21 08:24:56 |
作者 | Corbin <cds@corb...> |
Commiter | Corbin |
Refactor canonicalization.
@@ -1,18 +1,6 @@ | ||
1 | 1 | import os.path |
2 | 2 | |
3 | 3 | from cammylib.parser import parse |
4 | -from cammylib.sexp import Atom, Functor, Hole | |
5 | - | |
6 | -BASIS_ATOMS = ( | |
7 | - "id", "ignore", "fst", "snd", "left", "right", | |
8 | - "zero", "succ", "nil", "cons", "t", "f", "not", "conj", "disj", | |
9 | - "f-zero", "f-one", "f-pi", "f-sign", "f-floor", "f-negate", "f-recip", | |
10 | - "f-lt", "f-add", "f-mul", "f-sqrt", "f-sin", "f-cos", "f-atan2" | |
11 | -) | |
12 | - | |
13 | -BASIS_FUNCTORS = ( | |
14 | - "comp", "pair", "case", "curry", "uncurry", "pr", "fold", "either", | |
15 | -) | |
16 | 4 | |
17 | 5 | |
18 | 6 | class Hive(object): |
@@ -28,25 +16,7 @@ class Hive(object): | ||
28 | 16 | fullpath = os.path.join(self.hivepath, filename) |
29 | 17 | with open(fullpath, "r") as handle: |
30 | 18 | sexp, trail = parse(handle.read()) |
31 | - sexp = self.canonicalize(sexp) | |
19 | + sexp = sexp.canonicalize(self) | |
32 | 20 | self.exprs[atom] = sexp |
33 | 21 | print "Loaded", atom, sexp |
34 | 22 | return sexp |
35 | - | |
36 | - def canonicalize(self, expr): | |
37 | - if isinstance(expr, Atom): | |
38 | - if expr.symbol in BASIS_ATOMS: | |
39 | - return expr | |
40 | - else: | |
41 | - return self.load(expr.symbol) | |
42 | - elif isinstance(expr, Functor): | |
43 | - args = [self.canonicalize(arg) for arg in expr.arguments] | |
44 | - if expr.constructor in BASIS_FUNCTORS: | |
45 | - return Functor(expr.constructor, args) | |
46 | - else: | |
47 | - functor = self.load(expr.constructor) | |
48 | - return functor.substitute(args) | |
49 | - elif isinstance(expr, Hole): | |
50 | - return expr | |
51 | - else: | |
52 | - assert False, "not ready yet" |
@@ -1,6 +1,19 @@ | ||
1 | +BASIS_ATOMS = ( | |
2 | + "id", "ignore", "fst", "snd", "left", "right", | |
3 | + "zero", "succ", "nil", "cons", "t", "f", "not", "conj", "disj", | |
4 | + "f-zero", "f-one", "f-pi", "f-sign", "f-floor", "f-negate", "f-recip", | |
5 | + "f-lt", "f-add", "f-mul", "f-sqrt", "f-sin", "f-cos", "f-atan2" | |
6 | +) | |
7 | + | |
8 | +BASIS_FUNCTORS = ( | |
9 | + "comp", "pair", "case", "curry", "uncurry", "pr", "fold", "either", | |
10 | +) | |
11 | + | |
12 | + | |
1 | 13 | class SExp(object): |
2 | 14 | "An S-expression." |
3 | 15 | |
16 | + | |
4 | 17 | class Atom(SExp): |
5 | 18 | "An S-expression atom." |
6 | 19 |
@@ -15,6 +28,13 @@ class Atom(SExp): | ||
15 | 28 | def substitute(self, args): |
16 | 29 | return self |
17 | 30 | |
31 | + def canonicalize(self, hive): | |
32 | + if self.symbol in BASIS_ATOMS: | |
33 | + return self | |
34 | + else: | |
35 | + return hive.load(self.symbol) | |
36 | + | |
37 | + | |
18 | 38 | class Functor(SExp): |
19 | 39 | "A list of S-expressions with a distinguished head." |
20 | 40 |
@@ -32,6 +52,15 @@ class Functor(SExp): | ||
32 | 52 | return Functor(self.constructor, |
33 | 53 | [arg.substitute(args) for arg in self.arguments]) |
34 | 54 | |
55 | + def canonicalize(self, hive): | |
56 | + args = [arg.canonicalize(hive) for arg in self.arguments] | |
57 | + if self.constructor in BASIS_FUNCTORS: | |
58 | + return Functor(self.constructor, args) | |
59 | + else: | |
60 | + functor = hive.load(self.constructor) | |
61 | + return functor.substitute(args) | |
62 | + | |
63 | + | |
35 | 64 | class Hole(SExp): |
36 | 65 | "A hole where an S-expression could be." |
37 | 66 |
@@ -45,3 +74,6 @@ class Hole(SExp): | ||
45 | 74 | |
46 | 75 | def substitute(self, args): |
47 | 76 | return args[self.index] |
77 | + | |
78 | + def canonicalize(self, hive): | |
79 | + return self |
@@ -19,7 +19,7 @@ def repl(hive, stdin, stdout): | ||
19 | 19 | print "Got:", line |
20 | 20 | print "S-expression:", sexp.asStr() |
21 | 21 | print "Trail:", trail |
22 | - sexp = hive.canonicalize(sexp) | |
22 | + sexp = sexp.canonicalize(hive) | |
23 | 23 | print "Canonicalized:", sexp.asStr() |
24 | 24 | try: |
25 | 25 | arrow = buildArrow(sexp) |