Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # author: Anastasia Gaydashenko (a.v.gaydashenko@gmail.com)
- class Scope(object):
- def __init__(self, parent = None):
- self.parent = parent
- self.dictionary = {}
- def __setitem__(self, key, value):
- self.dictionary[key] = value
- def __getitem__(self, item):
- if (item in self.dictionary):
- return self.dictionary[item]
- elif (self.parent != None):
- return self.parent[item]
- class Node(object):
- pass
- class Number(Node):
- def __init__(self, value):
- self.value = int(value)
- def evaluate(self, scope):
- return self
- class Function(Node):
- def __init__(self, args, body):
- self.args = args
- self.body = body
- def evaluate(self, scope):
- result = None
- for element in self.body:
- result = element.evaluate(scope)
- return result
- class FunctionDefinition(Node):
- def __init__(self, name, function):
- self.name = name
- self.function = function
- def evaluate(self, scope):
- scope[self.name] = self.function
- class Conditional(Node):
- def __init__(self, condition, if_true, if_false = None):
- self.condition = condition
- self.if_true = if_true
- self.if_false = if_false
- def evaluate(self, scope):
- result = None
- value = self.condition.evaluate(scope).value
- if (value) and (self.if_true != None):
- for element in self.if_true:
- result = element.evaluate(scope)
- elif (self.if_false != None):
- for element in self.if_false:
- result = element.evaluate(scope)
- return result
- class Print(Node):
- def __init__(self, expr):
- self.expr = expr
- def evaluate(self, scope = None):
- print (self.expr.evaluate(scope).value)
- class Read(Node):
- def __init__(self, name):
- self.name = name
- def evaluate(self, scope):
- value = input()
- scope[self.name] = Number(value)
- class FunctionCall(Node):
- def __init__(self, fun_expr, args):
- self.fun_expr = fun_expr
- self.args = args
- def evaluate(self, scope):
- function = self.fun_expr.evaluate(scope)
- call_scope = Scope(scope)
- for i in range(len(function.args)):
- call_scope[function.args[i]] = self.args[i].evaluate(scope)
- return function.evaluate(call_scope)
- class Reference(Node):
- def __init__(self, name):
- self.name = name
- def evaluate(self, scope):
- return scope[self.name]
- class BinaryOperation(Node):
- def __init__(self, lhs, op, rhs):
- self.lhs = lhs
- self.op = op
- self.rhs = rhs
- def evaluate(self, scope):
- if (self.op == "+"):
- return Number(self.lhs.evaluate(scope).value + self.rhs.evaluate(scope).value)
- elif (self.op == "-"):
- return Number(self.lhs.evaluate(scope).value - self.rhs.evaluate(scope).value)
- elif (self.op == "*"):
- return Number(self.lhs.evaluate(scope).value * self.rhs.evaluate(scope).value)
- elif (self.op == "/"):
- return Number(self.lhs.evaluate(scope).value / self.rhs.evaluate(scope).value)
- elif (self.op == "%"):
- return Number(self.lhs.evaluate(scope).value % self.rhs.evaluate(scope).value)
- elif (self.op == "=="):
- return Number(self.lhs.evaluate(scope).value == self.rhs.evaluate(scope).value)
- elif (self.op == "!="):
- return Number(self.lhs.evaluate(scope).value != self.rhs.evaluate(scope).value)
- elif (self.op == "<"):
- return Number(self.lhs.evaluate(scope).value < self.rhs.evaluate(scope).value)
- elif (self.op == ">"):
- return Number(self.lhs.evaluate(scope).value > self.rhs.evaluate(scope).value)
- elif (self.op == "<="):
- return Number(self.lhs.evaluate(scope).value <= self.rhs.evaluate(scope).value)
- elif (self.op == ">="):
- return Number(self.lhs.evaluate(scope).value >= self.rhs.evaluate(scope).value)
- elif (self.op == "&&"):
- return Number(self.lhs.evaluate(scope).value and self.rhs.evaluate(scope).value)
- elif (self.op == "||"):
- return Number(self.lhs.evaluate(scope).value or self.rhs.evaluate(scope).value)
- class UnaryOperation(Node):
- def __init__(self, op, expr):
- self.op = op
- self.expr = expr
- def evaluate(self, scope):
- if (self.op == "-"):
- return Number(-self.expr.evaluate(scope).value)
- elif (self.op == "!"):
- return Number(not self.expr.evaluate(scope).value)
- if __name__ == "__main__":
- scope = Scope()
- frac = Function(["a", "b"], [BinaryOperation(Reference("a"), "/", Reference("b"))])
- FunctionDefinition("frac", frac).evaluate(scope)
- Print(FunctionCall(Reference("frac"), [Number(-30), Number(20)]).evaluate(scope)).evaluate(scope)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement