From: Tim Vieira Date: Fri, 12 Jul 2013 20:24:13 +0000 (-0400) Subject: better cleanup when an initializer fails. X-Git-Url: https://hydra-www.ietfng.org/gitweb/?a=commitdiff_plain;h=7d43439aa60d73a1987cfceda8202fa74063b115;p=dyna2 better cleanup when an initializer fails. --- diff --git a/src/Dyna/Backend/Python/interpreter.py b/src/Dyna/Backend/Python/interpreter.py index f90de61..d174450 100644 --- a/src/Dyna/Backend/Python/interpreter.py +++ b/src/Dyna/Backend/Python/interpreter.py @@ -100,14 +100,12 @@ class Rule(object): @property def span(self): - if self.init or self.query: - span = parse_attrs(self.init or self.query)['Span'] - return hide_ugly_filename(span) + span = parse_attrs(self.init or self.query)['Span'] + return hide_ugly_filename(span) @property def src(self): - if self.init or self.query: - return strip_comments(parse_attrs(self.init or self.query)['rule']) + return strip_comments(parse_attrs(self.init or self.query)['rule']) def __repr__(self): return 'Rule(%s, %r)' % (self.index, self.src) @@ -570,40 +568,42 @@ class Interpreter(object): self.new_fn(k, v) new_rules = set() - for _, r, _ in env.queries: + for fn, r, h in env.queries: + self.new_query(fn, r, h) new_rules.add(r) - for r, _ in env.initializers: + for fn, r, h in env.updaters: + self.new_updater(fn, r, h) + for r, h in env.initializers: + self.new_initializer(r, h) new_rules.add(r) self.new_rules = new_rules - for fn, r, h in env.queries: - self.new_query(fn, r, h) - try: if initialize: - # only run new initializers + # run new initializers for _, init in env.initializers: init(emit=_emit) except (TypeError, ZeroDivisionError) as e: - raise DynaInitializerException(e, init) + # remove new rules + for r in new_rules: + self.retract_rule(r) + self.new_rules = set() - finally: + # if multiple rules were added we reject all of them (in order to + # avoid an bizarre parser state. + raise DynaInitializerException(e, init) + + else: # process emits for e in emits: self.emit(*e, delete=False) - for fn, r, h in env.updaters: - self.new_updater(fn, r, h) - for r, h in env.initializers: - self.new_initializer(r, h) - # accept the new parser state self.parser_state = env.parser_state - # ------ $rule for fun and profit ------- interp = self def rule(ix, *a): diff --git a/src/Dyna/Backend/Python/post/trace.py b/src/Dyna/Backend/Python/post/trace.py index c431959..bec70c7 100644 --- a/src/Dyna/Backend/Python/post/trace.py +++ b/src/Dyna/Backend/Python/post/trace.py @@ -62,7 +62,6 @@ def groupby(key, data): def dig(head, visited, tail, groups, interp, depth_limit=-1): - print head, len(tail), depth_limit if depth_limit >= 0 and len(tail) >= depth_limit: return [yellow % '*max depth*'] @@ -232,13 +231,3 @@ class Crux(object): return self.get_function(e) return self.get_function(e) + (cyan % '=%s' % self.values(x)) - - -class Expr(object): - pass -class Fn(Expr): - pass -class Infix(Expr): - pass -class Unif(Expr): - pass diff --git a/src/Dyna/Backend/Python/stdlib.py b/src/Dyna/Backend/Python/stdlib.py index 516a83e..7035878 100644 --- a/src/Dyna/Backend/Python/stdlib.py +++ b/src/Dyna/Backend/Python/stdlib.py @@ -18,7 +18,7 @@ def and_(x, y): def not_(x): if not isbool(x): - raise TypeError('') + raise TypeError(repr(x)) if x: return false else: @@ -140,7 +140,7 @@ def iter_cons(x): def in_list(x, a): if not islist(a): raise TypeError("Attemping to iterate something which isn't a list. %r" % (a,)) - return x in a.aslist + return todyna(x in a.aslist) # should probably be done with memoized backchaining... diff --git a/src/Dyna/Backend/Python/term.py b/src/Dyna/Backend/Python/term.py index 14a5cf1..3ac67fd 100644 --- a/src/Dyna/Backend/Python/term.py +++ b/src/Dyna/Backend/Python/term.py @@ -69,11 +69,11 @@ class Cons(Term): def __repr__(self): return '[%s]' % (', '.join(map(_repr, self.aslist))) - def __contains__(self, x): - if x in self.aslist: - return true - else: - return false +# def __contains__(self, x): +# if x in self.aslist: +# return true +# else: +# return false def like_chart(self): for a in self.aslist: @@ -111,8 +111,8 @@ class _Nil(Term): def __repr__(self): return '[]' - def __contains__(self, x): - return false +# def __contains__(self, x): +# return false def like_chart(self): return iter([]) diff --git a/test/repl/error.dynadoc b/test/repl/error.dynadoc deleted file mode 100644 index e86fb24..0000000 --- a/test/repl/error.dynadoc +++ /dev/null @@ -1,83 +0,0 @@ - -> b := 0. -| a += 1/b. -| -| c += "" + b. -| -| e := 0. -| -| b := e/0. -| a += e/0. -| -| d += null. -| d += 1. -| -| a(X) := f(X,Y). -| -| f(1,1) := 1. -| f(1,2) := 2. -| -| f(2,1) := 1. -| f(2,2) := 2. - -Changes -======= -a(1) = $error. -a(2) = $error. -b = 0. -d = $error. -e = 0. -f(1,1) = 1. -f(1,2) = 2. -f(2,1) = 1. -f(2,2) = 2. - -> sol - -Solution -======== -b = 0. -d = $error. -e = 0. - -a/1 -=== -a(1) = $error. -a(2) = $error. - -f/2 -=== -f(1,1) = 1. -f(1,2) = 2. -f(2,1) = 1. -f(2,2) = 2. - -Errors -====== -Error(s) aggregating a/1: - AggregatorError: - `a(1)`: `:=` got conflicting values [1, 2] for rule index 8 - `a(2)`: `:=` got conflicting values [1, 2] for rule index 8 -Error(s) aggregating d/0: - TypeError: - `d`: unsupported operand type(s) for *: 'NoneType' and 'int' -Error(s) in rule: - a += 1/b. - ZeroDivisionError: - when `b` = 0 - division by zero -Error(s) in rule: - c += "" + b. - TypeError: - when `b` = 0 - cannot concatenate 'str' and 'int' objects -Error(s) in rule: - b := e/0. - ZeroDivisionError: - when `e` = 0 - division by zero -Error(s) in rule: - a += e/0. - ZeroDivisionError: - when `e` = 0 - division by zero