|
32 | 32 | from SimpleDataTypes import * |
33 | 33 | from TypeChecker import * |
34 | 34 |
|
35 | | -class BaseAggregate(object): |
36 | | - """ A class that define common properties to ARRAY, LIST, SET and BAG. |
| 35 | +def type_from_string(type_str): |
| 36 | + """ Look for the type definition in the global scope from the type string. |
| 37 | + @TODO: find a better implementation than testing all modules! |
37 | 38 | """ |
38 | | - def __init__( self , bound1 , bound2 , base_type ): |
39 | | - # check that bound1<bound2 |
40 | | - if (bound1!=None and bound2!=None): |
41 | | - if bound1>bound2: |
42 | | - raise AssertionError("bound1 shall be less than or equal to bound2") |
43 | | - self._bound1 = bound1 |
44 | | - self._bound2 = bound2 |
45 | | - self._base_type = base_type |
46 | | - |
47 | | - def __getitem__(self, index): |
48 | | - if index<self._bound1: |
49 | | - raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound1,index)) |
50 | | - elif(self._bound2!=None and index>self._bound2): |
51 | | - raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound2,index)) |
52 | | - else: |
53 | | - return list.__getitem__(self,index) |
54 | | - |
55 | | - def __setitem__(self,index,value): |
56 | | - if index<self._bound1: |
57 | | - raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound1,index)) |
58 | | - elif (self._bound2!=None and index>self._bound2): |
59 | | - raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound2,index)) |
60 | | - elif not isinstance(value,self._base_type): |
61 | | - raise TypeError("%s type expected, passed %s."%(self._base_type, type(value))) |
62 | | - else: |
63 | | - # first find the length of the list, and extend it if ever |
64 | | - # the index is |
65 | | - list.__setitem__(self,index,value) |
| 39 | + modules = sys.modules |
| 40 | + for module in modules.values(): |
| 41 | + if (module is not None) and (not '__' in module.__name__): |
| 42 | + module_variables = vars(module) |
| 43 | + if module_variables.has_key(type_str): |
| 44 | + typ = module_variables[type_str] |
| 45 | + return True, vars(module)[type_str] |
| 46 | + return False,None |
66 | 47 |
|
67 | 48 | class ARRAY(object): |
68 | 49 | """An array data type has as its domain indexed, fixed-size collections of like elements. The lower |
@@ -144,52 +125,97 @@ def __init__( self , bound_1 , bound_2 , base_type , UNIQUE = False): |
144 | 125 | if not type(bound_1)==int: |
145 | 126 | raise TypeError("LIST lower bound must be an integer") |
146 | 127 | # bound_2 can be set to None |
147 | | - if not type(bound_2)==int: |
| 128 | + self._unbounded = False |
| 129 | + if bound_2 == None: |
| 130 | + self._unbounded = True |
| 131 | + elif not type(bound_2)==int: |
148 | 132 | raise TypeError("LIST upper bound must be an integer") |
149 | 133 | if not bound_1>=0: |
150 | 134 | raise AssertionError("LIST lower bound must be greater of equal to 0") |
151 | | - if not (bound_1 <= bound_2): |
| 135 | + if (type(bound_2)==int and not (bound_1 <= bound_2)): |
152 | 136 | raise AssertionError("ARRAY lower bound must be less than or equal to upper bound") |
153 | 137 | # set up class attributes |
154 | 138 | self._bound_1 = bound_1 |
155 | 139 | self._bound_2 = bound_2 |
156 | 140 | self._base_type = base_type |
157 | 141 | self._unique = UNIQUE |
158 | | - self._optional = OPTIONAL |
159 | | - # preallocate list elements |
160 | | - list_size = bound_2 - bound_1 + 1 |
161 | | - self._container = list_size*[None] |
162 | | - |
| 142 | + # preallocate list elements if bounds are both integers |
| 143 | + if not self._unbounded: |
| 144 | + list_size = bound_2 - bound_1 + 1 |
| 145 | + self._container = list_size*[None] |
| 146 | + # for unbounded list, this will come after |
| 147 | + else: |
| 148 | + self._container = [None] |
| 149 | + |
163 | 150 | def bound_1(self): |
164 | 151 | return self._bound_1 |
165 | 152 |
|
166 | 153 | def bound_2(self): |
167 | 154 | return self._bound_2 |
168 | 155 |
|
169 | 156 | def __getitem__(self, index): |
170 | | - if index<self._bound_1: |
171 | | - raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound_1,index)) |
172 | | - elif(index>self._bound_2): |
173 | | - raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound_2,index)) |
| 157 | + # case bounded |
| 158 | + if not self._unbounded: |
| 159 | + if index<self._bound_1: |
| 160 | + raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound_1,index)) |
| 161 | + elif(index>self._bound_2): |
| 162 | + raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound_2,index)) |
| 163 | + else: |
| 164 | + value = self._container[index-self._bound_1] |
| 165 | + if value == None: |
| 166 | + raise AssertionError("Value with index %i not defined. Please set the value first."%index) |
| 167 | + return value |
| 168 | + #case unbounded |
174 | 169 | else: |
175 | | - value = self._container[index-self._bound_1] |
176 | | - if not self._optional and value==None: |
177 | | - raise AssertionError("Not OPTIONAL prevent the value with index %i from being None (default). Please set the value first."%index) |
178 | | - return value |
| 170 | + if index-self._bound_1>len(self._container): |
| 171 | + raise AssertionError("Value with index %i not defined. Please set the value first."%index) |
| 172 | + else: |
| 173 | + value = self._container[index-self._bound_1] |
| 174 | + if value == None: |
| 175 | + raise AssertionError("Value with index %i not defined. Please set the value first."%index) |
| 176 | + return value |
179 | 177 |
|
180 | 178 | def __setitem__(self, index, value): |
181 | | - if index<self._bound_1: |
182 | | - raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound_1,index)) |
183 | | - elif(index>self._bound_2): |
184 | | - raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound_2,index)) |
| 179 | + # case bounded |
| 180 | + if not self._unbounded: |
| 181 | + if index<self._bound_1: |
| 182 | + raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound_1,index)) |
| 183 | + elif(index>self._bound_2): |
| 184 | + raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound_2,index)) |
| 185 | + else: |
| 186 | + # first check the type of the value |
| 187 | + check_type(value,self._base_type) |
| 188 | + # then check if the value is already in the array |
| 189 | + if self._unique: |
| 190 | + if value in self._container: |
| 191 | + raise AssertionError("UNIQUE keyword prevent inserting this instance.") |
| 192 | + self._container[index-self._bound_1] = value |
| 193 | + # case unbounded |
185 | 194 | else: |
186 | | - # first check the type of the value |
187 | | - check_type(value,self._base_type) |
188 | | - # then check if the value is already in the array |
189 | | - if self._unique: |
190 | | - if value in self._container: |
191 | | - raise AssertionError("UNIQUE keyword prevent inserting this instance.") |
192 | | - self._container[index-self._bound_1] = value |
| 195 | + if index<self._bound_1: |
| 196 | + raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound_1,index)) |
| 197 | + # if the _container list is of good size, just do like the bounded case |
| 198 | + if (index-self._bound_1<len(self._container)): |
| 199 | + # first check the type of the value |
| 200 | + check_type(value,self._base_type) |
| 201 | + # then check if the value is already in the array |
| 202 | + if self._unique: |
| 203 | + if value in self._container: |
| 204 | + raise AssertionError("UNIQUE keyword prevent inserting this instance.") |
| 205 | + self._container[index-self._bound_1] = value |
| 206 | + # in the other case, we have to extend the base _container list |
| 207 | + else: |
| 208 | + delta_size = (index-self._bound_1) - len(self._container) + 1 |
| 209 | + #create a list of None, and extend the list |
| 210 | + list_extension = delta_size*[None] |
| 211 | + self._container.extend(list_extension) |
| 212 | + # first check the type of the value |
| 213 | + check_type(value,self._base_type) |
| 214 | + # then check if the value is already in the array |
| 215 | + if self._unique: |
| 216 | + if value in self._container: |
| 217 | + raise AssertionError("UNIQUE keyword prevent inserting this instance.") |
| 218 | + self._container[index-self._bound_1] = value |
193 | 219 |
|
194 | 220 | class BAG(tuple, BaseAggregate): |
195 | 221 | """A bag data type has as its domain unordered collections of like elements. The optional lower |
|
0 commit comments