Mercurial > lbo > hg > arith
view arith/eval.py @ 0:e85652916197 draft
Initial commit
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Fri, 17 May 2019 22:28:13 +0200 |
parents | |
children |
line wrap: on
line source
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Fri May 17 21:55:20 2019 @author: lbo """ from tree import Product, Term, Power, Value, Symbol class NotBoundError(Exception): def __init__(self, symbol): super(Exception, self).__init__('Symbol {} not bound!'.format(symbol)) class Bindings: _bindings = {} def __init__(self, bind={}): self._bindings = bind def set(self, sym, val): self._bindings[sym] = val def unset(self, sym): self._bindings.pop(sym) def get(self, sym): sym = sym.c if sym in self._bindings: return self._bindings[sym] raise NotBoundError(sym) def evaluate(node, bindings=None): bindings = Bindings() if not bindings else bindings assert isinstance(node, Symbol) or isinstance(node, Value) or (node.left and node.right) if isinstance(node, Symbol): return bindings.get(node) elif isinstance(node, Value): return node.v elif isinstance(node, Product): if node.typ == Product.PROD: return evaluate(node.left, bindings) * evaluate(node.right, bindings) elif node.typ == Product.QUOT: right = evaluate(node.right, bindings) assert right != 0 return evaluate(node.left, bindings) / right elif isinstance(node, Term): if node.typ == Term.PLUS: return evaluate(node.left, bindings) + evaluate(node.right, bindings) elif node.typ == Term.MINUS: return evaluate(node.left, bindings) - evaluate(node.right, bindings) elif isinstance(node, Power): if node.typ == Power.POWER: return evaluate(node.left, bindings) ** evaluate(node.right, bindings)