Advertisement
Guest User

Untitled

a guest
Feb 20th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.27 KB | None | 0 0
  1. import sys
  2.  
  3. class StackEntry(object):
  4. def __init__(self, var_map):
  5. self.var_map = var_map
  6.  
  7. @classmethod
  8. def empty(cls):
  9. return StackEntry(dict())
  10.  
  11. class Stack(object):
  12. def __init__(self):
  13. self.entries = [StackEntry.empty()]
  14.  
  15. def push(self, entry):
  16. self.entries.append(entry)
  17.  
  18. def pop(self):
  19. return self.entries.pop()
  20.  
  21. def define_name(self, name, val):
  22. self.entries[-1].var_map[name] = val
  23.  
  24. def lookup_name(self, name):
  25. """Dynamic scope"""
  26.  
  27. # Look up the stack
  28. for e in reversed(self.entries):
  29. if name in e.var_map:
  30. return e.var_map[name]
  31.  
  32.  
  33. class Function(object):
  34. def __init__(self, params, body):
  35. self.params = params
  36. self.body = body
  37.  
  38. def stack_entry(self, args):
  39. return StackEntry(dict(zip(self.params, args)))
  40.  
  41.  
  42.  
  43. # Expressions
  44. class Expression(object):
  45. pass
  46.  
  47. class FunCallExpr(Expression):
  48. def __init__(self, function_name, args):
  49. self.function_name = function_name
  50. self.args = args
  51.  
  52. def evaluate(self, stack):
  53. func = stack.lookup_name(self.function_name)
  54. stack.push(func.stack_entry(self.args))
  55. return run_body(stack, func.body)
  56.  
  57. class LiteralExpr(Expression):
  58. def __init__(self, literal):
  59. self.literal = literal
  60.  
  61. def evaluate(self, stack):
  62. return self.literal
  63. class VariableExpr(Expression):
  64. def __init__(self, name):
  65. self.name = name
  66.  
  67. def evaluate(self, stack):
  68. return stack.lookup_name(self.name)
  69.  
  70. class OperatorExpr(Expression):
  71. def __init__(self, operator, opArgExprs):
  72. self.operator = operator
  73. self.opArgExprs = opArgExprs
  74.  
  75. def evaluate(self, stack):
  76. return self.operator(*[e.evaluate(stack) for e in self.opArgExprs])
  77.  
  78. # Statements
  79. class Command(object):
  80. pass
  81.  
  82. class EvalCmd(Command):
  83. def __init__(self, expr):
  84. self.expr = expr
  85.  
  86. def run(self, stack):
  87. self.expr.evaluate(stack)
  88.  
  89. class PrintCmd(Command):
  90. def __init__(self, expr):
  91. self.expr = expr
  92.  
  93. def run(self, stack):
  94. print("Stdout:", self.expr.evaluate(stack))
  95.  
  96. class DefineCmd(Command):
  97. def __init__(self, name, expr):
  98. self.name = name
  99. self.expr = expr
  100.  
  101. def run(self, stack):
  102. stack.define_name(self.name, self.expr.evaluate(stack))
  103.  
  104. class ReturnCmd(Command):
  105. def __init__(self, return_value):
  106. self.return_value = return_value
  107.  
  108.  
  109. def run_body(stack, body):
  110. for cmd in body:
  111. if isinstance(cmd, ReturnCmd):
  112. return cmd.return_value
  113.  
  114. cmd.run(stack)
  115.  
  116.  
  117. # Shorthands
  118. def lit(l):
  119. return LiteralExpr(l)
  120.  
  121. def add(l,r):
  122. return OperatorExpr(lambda x,y: x + y, [l, r])
  123.  
  124. def pr(exp):
  125. return PrintCmd(exp)
  126.  
  127. def defun(name, args, *body):
  128. return DefineCmd(name, LiteralExpr(Function(args, body)))
  129.  
  130. def var(name):
  131. return VariableExpr(name)
  132.  
  133. def ret(expr):
  134. return ReturnCmd(expr)
  135.  
  136. def funcall(name, *args):
  137. return FunCallExpr(name, args)
  138.  
  139. def ev(expr):
  140. return EvalCmd(expr)
  141.  
  142. if __name__ == "__main__":
  143. run_body(Stack(), [
  144. # define a function f
  145. defun("f", ["x"],
  146. # That prints it's argument incremented
  147. pr(add(lit(1), var("x")))),
  148.  
  149. # Evaluate call to the funxtion
  150. ev(funcall("f", 2))])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement