1 | """Definition of the OMBinding object""" |
---|
2 | from objects import OMObjectBase, OMSymbol |
---|
3 | from cd import OMCD |
---|
4 | from omexceptions import UnsupportedOperationError |
---|
5 | from itertools import izip |
---|
6 | from copy import copy |
---|
7 | cdFns1 = OMCD("fns1") |
---|
8 | lambdasym = OMSymbol("lambda", cdFns1) |
---|
9 | |
---|
10 | def islambda(sym): |
---|
11 | "return True, iff sym is the lambda binder" |
---|
12 | return lambdasym == sym |
---|
13 | |
---|
14 | class OMBinding(OMObjectBase): |
---|
15 | """hopefully fixed possible problems: reevaluation writes new scope, |
---|
16 | if it isn't |
---|
17 | meant so, references do not work correctly because of scopes |
---|
18 | solve this by first evaluation to bounded OMBinding""" |
---|
19 | def __init__(self, binder, variables, block): |
---|
20 | super(OMBinding, self).__init__() |
---|
21 | self.block = block |
---|
22 | self.binder = binder |
---|
23 | self.variables = variables |
---|
24 | self.bounded = False |
---|
25 | def evaluate(self, context): |
---|
26 | "evaluate the OMbinding in context" |
---|
27 | assert islambda(self.binder) |
---|
28 | if not self.bounded: |
---|
29 | mycopy = copy(self) |
---|
30 | mycopy.scope = context.scopeFromCurrentScope() |
---|
31 | mycopy.bounded = True |
---|
32 | return mycopy |
---|
33 | else: |
---|
34 | return self |
---|
35 | def bind(self, args): |
---|
36 | "bind arguments to values" |
---|
37 | #print args, self.variables |
---|
38 | assert len(args) == len(self.variables) |
---|
39 | varBindings = dict(izip([i.name for i in self.variables], args)) |
---|
40 | self.scope.push(varBindings) |
---|
41 | def unbind(self): |
---|
42 | "unbind the arguments" |
---|
43 | self.scope.pop() |
---|
44 | |
---|
45 | def calcErg(self, context): |
---|
46 | "do the actual computation" |
---|
47 | return context.evaluateInScope(self.block, self.scope) |
---|
48 | def __call__(self, context, *args): |
---|
49 | self.bind(args) |
---|
50 | erg = self.calcErg(context) |
---|
51 | self.unbind() |
---|
52 | #print "__call__ erg is", erg |
---|
53 | return erg |
---|
54 | |
---|
55 | XMLtag = "OMBIND" |
---|
56 | def getChildren(self): |
---|
57 | "get children for (XML) representation" |
---|
58 | return [self.binder]+self.variables+[self.block] |
---|
59 | |
---|