source: git/modules/openmathserver/objects.py @ 666465b

spielwiese
Last change on this file since 666465b was 666465b, checked in by Michael Brickenstein <bricken@…>, 19 years ago
*bricken real xml encoder git-svn-id: file:///usr/local/Singular/svn/trunk@8664 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 11.8 KB
Line 
1"""Implementation of openmath basic objects"""
2from omexceptions import UnsupportedOperationError
3from  omexceptions import OutOfScopeError, EvaluationFailedError
4from exceptions import NotImplementedError
5from copy import copy
6from xml.sax.xmlreader import AttributesImpl as attr
7import base64
8#TODO: OMOBJ, OME, OMATTR
9#from cd import *
10try:
11    import psyco
12    def optimize(f):
13        psyco.bind(f)
14except:
15    def optimize(f):
16        pass
17
18class XMLAttribute(object):
19    def __init__(self, name, value):
20        self.name = name
21        self.value = value
22    def encode(self, context):
23        return "".join([self.name,"=\"",self.value,"\""])
24class OMObjectBase(object):
25    """ at the moment only a base class"""
26    #def __init__(self):
27    #    self.attributes={}
28    attributes={}
29    #dangerous, if you change attributes, always copy attributes
30   
31    def __getChildren(self):
32        try:
33            return self.getChildren()
34        except AttributeError:
35            try:
36                return self.__children
37            except AttributeError:
38                return []
39    def __delChildren(self):
40        try:
41            self.delChildren()
42            return
43        except AttributeError:
44            try:
45                del self.__children
46            except AttributeError:
47                pass
48    def __setChildren(self,children):
49        try:
50            self.setChildren(children)
51        except AttributeError:
52            raise UnsupportedOperationError
53    def __getBody(self):
54        try:
55            return self.getBody()
56        except AttributeError:
57            try:
58                return self.__body
59            except AttributeError:
60                return None
61    def __delBody(self):
62        try:
63            self.delBody()
64            return
65        except AttributeError:
66            try:
67                del self.__body
68            except AttributeError:
69                pass
70    def __setBody(self,body):
71        try:
72            self.setBody(body)
73        except AttributeError:
74            raise UnsupportedOperationError
75    def __getXMLAttributes(self):
76        if hasattr(self, "getXMLAttributes"):
77            return self.getXMLAttributes()
78        if hasattr(self,"__XMLAttributes"):
79            return self.__XMLAttributes
80        return {}
81            #except AttributeError:
82                #do return None, cause if modifiying a new list, changes will not be saved
83            #    return {}
84    def __delXMLAttributes(self):
85        try:
86            self.delXMLAttributes()
87            return
88        except AttributeError:
89            try:
90                del self.__XMLAttributes
91            except AttributeError:
92                pass
93    def __setXMLAttributes(self,XMLAttributes):
94        try:
95            self.setBody(XMLAttributes)
96        except AttributeError:
97            raise UnsupportedOperationError
98    children=property(__getChildren, __setChildren,__delChildren,\
99                      """ children in an OMtree""")
100    body=property(__getBody,__setBody,__delBody,\
101        "xml body,FIXME: at the moment only char data")
102    XMLAttributes=property(__getXMLAttributes,\
103        __setXMLAttributes,__delXMLAttributes,\
104        "xml attributes")
105    def XMLEncode(self, context):
106       
107        attr=self.XMLAttributes
108        if attr:
109            attrstr = " "+" ".join([a.encode(context) for a in attr])
110        else:
111            attrstr = ""
112        opening = "".join(["<", self.XMLtag, attrstr,">"])
113        children = self.children
114        if children:
115            body = "".join([context.XMLEncodeObject(c) for c in children])
116        else:
117            body = self.body
118            if not body:
119                body = ""
120            assert body != None
121            body = context.XMLEncodeBody(body)
122            assert body != None
123        closing = "".join(["</"+self.XMLtag+">"])
124        return "".join([opening,body,closing])
125    def XMLPreEncode(self, context, encodingList=None):
126        #works not for attp
127        if encodingList==None:
128            encodingList=[]
129        encodingList.extend(["<", self.XMLtag])
130        attr=self.XMLAttributes
131        if attr:
132            for a in attr:
133                encodingList.append(" ")
134                encodingList.append(a.encode(context))
135        encodingList.append(">")
136        children = self.children
137        if children:
138            for c in children:
139                c.XMLPreEncode(context, encodingList)
140        else:
141            body = self.body
142            if body:
143                encodingList.append(context.XMLEncodeBody(body))
144        encodingList.extend(["</"+self.XMLtag+">"])
145        return encodingList
146    def XMLSAXEncode(self, context, generator):
147        #works not for attp
148        generator.startElement(self.XMLtag, attr(self.XMLAttributes))
149        for c in self.children:
150          c.XMLSAXEncode(context, generator)
151        if not self.children:
152          body=self.body
153          if body:
154            generator.characters(self.body)
155        generator.endElement(self.XMLtag)
156class OMObject(OMObjectBase):
157    def __init__(self, children):
158        #super(OMObject, self).__init__()
159        self.children = children
160    def getChildren(self):
161        return self.__children
162    def setChildren(self ,children):
163        self.__children=children
164    XMLtag = "OMOBJ"
165    def evaluate(self, context):
166        return OMObject([context.evaluate(c) for c in self.children])
167class OMVar(OMObjectBase):
168    def __init__(self,name):
169        #super(OMVar, self).__init__()
170        self.name = name
171    def evaluate(self, context):
172        try:
173            return context[self.name]
174        except OutOfScopeError:
175            return self
176    def __str__(self):
177        return "OMV(" + self.name +")"
178    XMLtag = "OMV"
179    def getXMLAttributes(self):
180        return [XMLAttribute("name", self.name)]
181       
182class OMApply(OMObjectBase):
183    def __init__(self, func, args):
184        #super(OMApply, self).__init__()
185        self.func = func
186        self.args = args
187    def evaluate(self, context):
188        efunc = context.evaluate(self.func)
189        eargs = [context.evaluate(a) for a in self.args]
190        if callable(efunc):
191            try:
192                return context.apply(efunc, eargs)
193            except EvaluationFailedError, NotImplementedError:
194                return OMApply(efunc, eargs)
195                #return self
196        else:
197            return OMApply(efunc, eargs)
198    XMLtag="OMA"
199    def getChildren(self):
200        return [self.func]+self.args
201    def setChildren(self):
202        raise UnsupportedOperationError
203       
204class OMSymbol(OMObjectBase):
205    def __init__(self,name,cd = None):
206        #super(OMSymbol,self).__init__()
207        self.cd = cd
208        self.name = name
209    def __eq__(self, other):
210        try:
211            return bool(other.name == self.name and self.cd == other.cd)
212        except:
213            return False
214    def __str__(self):
215        return "OMS(" + self.name + ", " + self.cd.name + ")"
216    def __hash__(self):#
217        return hash((self.name,self.cd.__hash__()))
218    def evaluate(self,context):
219        return context.evaluateSymbol(self)
220    XMLtag="OMS"
221    def getXMLAttributes(self):
222        #return [XMLAttribute("name", self.name),\
223        #         XMLAttribute("cdbase", self.cd.base),\
224        #         XMLAttribute("cd", self.cd.name)]
225        return {"name":self.name, "cdbase":self.cd.base, "cd": self.cd.name}
226    def setXMLAttributes(self):
227        raise UnsupportedOperationError
228class SimpleValue(OMObjectBase):
229    def __init__(self, value):
230        #super(SimpleValue, self).__init__()
231        if (isinstance(value, str)):
232            value = self.parse(value)
233        self.value = value
234    def evaluate(self, context):
235        return self
236    def getValue(self):
237        return self.value
238    def __str__(self):
239        return "OM("+repr(self.value)+")"
240
241class OMint(SimpleValue):
242    def __init__(self, value):
243        if not isinstance(value, int):
244            value = self.parse(value)
245        #super(OMint, self).__init__(value)
246        self.value=value
247    def parse(self, value):
248        """FIXME: Not fully standard compliant,
249        -> hex encodings"""
250        return int(value, 10)
251    def __str__(self):
252        return "OMint("+repr(self.value)+")"
253    def getBody(self):
254        return str(self.value)
255    def setBody(self, value):
256        raise UnsupportedOperationError
257    XMLtag = "OMI"
258class OMfloat(SimpleValue):
259    def __init__(self, value):
260        #super(OMfloat, self).__init__(value)
261        self.value=value
262    def parse(self, value):
263        """FIXME: Not fully standard compliant,
264        -> hex encodings"""
265        return float(value)
266    def __str__(self):
267        return "OMfloat("+repr(self.value)+")"
268    XMLtag = "OMF"
269    def getXMLAttributes(self):
270        return {"dec":str(self.value)}
271class OMString(SimpleValue):
272    def __init__(self,value):
273        #super(OMString,self).__init__(value)
274        self.value=value
275    def __str__(self):
276        return "OMSTR("+repr(self.value)+")"
277    XMLtag = "OMSTR"
278    def getBody(self):
279        return self.value
280class OMByteArray(SimpleValue):
281    def __init__(self, value):
282        #super(OMByteArray,self).__init__(value)
283        self.value=value
284    def __str__(self):
285        return "OMByteArray(" + repr(self.value) + ")"
286    def parse(self, value):
287        return value
288    XMLtag = "OMB"
289    def getBody(self):
290        return base64.encodestring(self.value)
291class OMRef(OMObjectBase):
292    def __init__(self, ref):
293        self.ref=ref
294    def evaluate(self, context):
295        return context.evaluate(self.ref)
296    def XMLEncode(self, context):
297        "FIXME: maybe it should also be able to encode as reference"
298        return context.XMLEncodeObject(self.ref)
299class OMAttributePair(OMObjectBase):
300    def __init__(self, key, value):
301        super(OMAttributePair,self).__init__()
302        self.key = key
303        self.value = value
304    def getChildren(self):
305        return [self.key, self.value]
306    XMLtag = "OMATP"
307    def evaluate(self, context):
308        return OMAttributePair(context.evaluate(self.key),\
309            context.evaluate(self.value))
310class OMAttribution(OMObjectBase):
311    def __init__(self, *args):
312        #super(OMAttribution,self).__init__()
313        self.attr = list(args[:-1])
314        self.value = args[-1]
315    def getChildren(self):
316        #print type(self.attr)
317        #print type(self.value)
318        return self.attr+[self.value]
319    def evaluate(self, context):
320        value = copy(self.value)
321        value.attributes = copy(value.attributes)
322        for attribute in self.attr:
323            attribute_evaluated=context.evaluate(attribute)
324            value.attributes[attribute_evaluated.key] = attribute_evaluated.value
325        return value
326    XMLtag = "OMATTR"
327if __name__ == '__main__':
328    from context import Context
329
330    from binding import OMBinding, lambdasym
331
332    context = Context()
333
334    context.push({})
335
336    context["x"] = OMint(1)
337
338    x = OMVar("x")
339
340    y = OMVar("y")
341
342    print context.evaluate(x)
343    print context.evaluate(y)
344    firstArg=OMBinding(lambdasym,[OMVar("x"), OMVar("y")], OMVar("x"))
345    #print context.evaluate(firstArg)
346    application = OMApply(firstArg, [x,y])
347    print context.evaluate(application)
348    application = OMApply(firstArg, [y,x])
349    print context.evaluate(application)
350    import CD.arith1 as arith1
351    context.addCDImplementation(arith1.implementation)
352    #print type(context.lookupImplementation(arith1.plussym))
353    #application=OMApply(arith1.plussym,[x])
354    #application=OMApply(arith1.plussym,[x,x])
355    application = OMApply(OMSymbol("plus", arith1.content), [x, x])
356   
357    print context.evaluate(application)
358    application = OMApply(OMSymbol("plus", arith1.content), [x, x, x])
359   
360    print context.evaluate(application)
361    i =  OMint(22482489)
362    print i.body
363    print i.XMLEncode(context)
364    #i.body="dshj"
365   
366#optimize(OMObjectBase.__init__)
367optimize(OMObjectBase.XMLPreEncode)
368optimize(SimpleValue.__init__)
369optimize(OMint.__init__)
370optimize(OMApply.__init__)
Note: See TracBrowser for help on using the repository browser.