Nix flake for RPython interpreters
修訂 | 1530ce8f9d6c265874e059a13bf32ebdfae834cf (tree) |
---|---|
時間 | 2024-05-15 11:09:37 |
作者 | Corbin <cds@corb...> |
Commiter | Corbin |
reguix: Wire up basic inherits.
@@ -4,6 +4,10 @@ class WrongType(Exception): | ||
4 | 4 | "A runtime typecheck failed." |
5 | 5 | def __init__(self, message): self.message = message |
6 | 6 | |
7 | +class MissingAttr(Exception): | |
8 | + "An attrset was missing an attr at runtime." | |
9 | + def __init__(self, attr): self.attr = attr | |
10 | + | |
7 | 11 | class HeapObject(object): |
8 | 12 | "A possibly-cyclic possibly-incomplete value." |
9 | 13 | # .resolve() is implementation-internal, always call .evaluate() |
@@ -20,16 +24,16 @@ class HeapObject(object): | ||
20 | 24 | self.__class__.__name__) |
21 | 25 | |
22 | 26 | class MutableObject(HeapObject): |
23 | - evaluated = loop = False | |
27 | + loop = False | |
28 | + cache = None | |
24 | 29 | def evaluate(self): |
25 | - if not self.evaluated: | |
30 | + if not self.cache: | |
26 | 31 | if self.loop: raise InfiniteLoop() |
27 | 32 | try: |
28 | 33 | self.loop = True |
29 | - return self.resolve() | |
30 | - finally: | |
31 | - self.loop = False | |
32 | - self.evaluated = True | |
34 | + self.cache = self.resolve() | |
35 | + finally: self.loop = False | |
36 | + return self.cache | |
33 | 37 | |
34 | 38 | class HeapInt(HeapObject): |
35 | 39 | _immutable_ = True |
@@ -57,19 +61,19 @@ class HeapAttrSet(MutableObject): | ||
57 | 61 | return "{ <attrset with %d items> }" % len(self.attrs) |
58 | 62 | return "{ %s }" % " ".join(["%s = %s;" % (name, obj) for (name, obj) in self.attrs.items()]) |
59 | 63 | def resolve(self): |
60 | - # XXX update dict? | |
61 | 64 | for obj in self.attrs.values(): obj.evaluate() |
62 | 65 | return self |
63 | - def getAttr(self, name): return self.attrs.get(name) | |
66 | + def getAttr(self, name): | |
67 | + try: return self.attrs[name] | |
68 | + except KeyError: raise MissingAttr(name) | |
64 | 69 | |
65 | 70 | class HeapList(MutableObject): |
66 | 71 | def __init__(self, objs): self.objs = objs |
67 | 72 | def asStr(self): |
68 | - if self.evaluated: | |
73 | + if self.cache: | |
69 | 74 | return "[ %s ]" % " ".join([obj.asStr() for obj in self.objs]) |
70 | 75 | else: return "[ <list of %d items> ]" % len(self.objs) |
71 | 76 | def resolve(self): |
72 | - # XXX update list? | |
73 | 77 | for obj in self.objs: obj.evaluate() |
74 | 78 | return self |
75 | 79 | def length(self): return len(self.objs) |
@@ -81,9 +85,7 @@ class HeapSelect(MutableObject): | ||
81 | 85 | def asStr(self): return self.obj.asStr() + "." + ".".join(self.path) |
82 | 86 | def resolve(self): |
83 | 87 | obj = self.obj |
84 | - for segment in self.path: | |
85 | - obj = obj.evaluate().getAttr(segment) | |
86 | - if obj is None: raise ValueError("Missing attr!") | |
88 | + for segment in self.path: obj = obj.evaluate().getAttr(segment) | |
87 | 89 | return obj |
88 | 90 | |
89 | 91 | class HeapApp(MutableObject): |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import sys |
2 | 2 | |
3 | -from heap import defaultScope, WrongType | |
4 | -from parser import parse, NotAnExpr, ParseError | |
3 | +from heap import defaultScope, InfiniteLoop, MissingAttr, WrongType | |
4 | +from parser import parse, MissingVar, NotAnExpr, ParseError | |
5 | 5 | |
6 | 6 | def entryPoint(argv): |
7 | 7 | if len(argv) < 2: |
@@ -31,6 +31,17 @@ def entryPoint(argv): | ||
31 | 31 | print "Error while compiling" |
32 | 32 | print "Input syntax was not an expr, but:", e.cls |
33 | 33 | return 1 |
34 | + except MissingVar as e: | |
35 | + print "Error while compiling" | |
36 | + print "Name was missing:", e.name | |
37 | + return 1 | |
38 | + except InfiniteLoop as e: | |
39 | + print "Error while executing: infinite loop" | |
40 | + return 1 | |
41 | + except MissingAttr as e: | |
42 | + print "Error while executing" | |
43 | + print "Attr was missing:", e.attr | |
44 | + return 1 | |
34 | 45 | except WrongType as e: |
35 | 46 | print "Error while executing" |
36 | 47 | print "Type error:", e.message |
@@ -65,6 +65,9 @@ lexer = lg.build() | ||
65 | 65 | class NotAnExpr(Exception): |
66 | 66 | def __init__(self, cls): self.cls = cls |
67 | 67 | |
68 | +class MissingVar(Exception): | |
69 | + def __init__(self, name): self.name = name | |
70 | + | |
68 | 71 | class RegiuxBox(BaseBox): |
69 | 72 | "A box for any syntax." |
70 | 73 | cls = "unknown" |
@@ -96,8 +99,9 @@ class BindsBox(EBox): | ||
96 | 99 | def compile(self, scope): |
97 | 100 | attrs = {} |
98 | 101 | for bind in self.binds: |
99 | - # XXX do actual codegen | |
100 | - for name in bind.getnames(): attrs[name] = heap.HeapStr("...") | |
102 | + for name in bind.getnames(): | |
103 | + if name not in scope: raise MissingVar(name) | |
104 | + attrs[name] = scope[name] | |
101 | 105 | return heap.HeapAttrSet(attrs) |
102 | 106 | |
103 | 107 | class ListBox(EBox): |
@@ -133,7 +137,7 @@ class VarBox(EBox): | ||
133 | 137 | def pretty(self): return self.name |
134 | 138 | def compile(self, scope): |
135 | 139 | if self.name in scope: return scope[self.name] |
136 | - raise ValueError("Name not in scope") | |
140 | + raise MissingVar(self.name) | |
137 | 141 | |
138 | 142 | class AppBox(EBox): |
139 | 143 | def __init__(self, func, arg): |