Changeset 30
- Timestamp:
- 23/08/04 15:51:52 (4 years ago)
- Files:
-
- trunk/airspeed.py (modified) (6 diffs)
- trunk/airspeed_test.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/airspeed.py
r29 r30 46 46 if len(got) > 40: 47 47 got = got[:36] + ' ...' 48 Exception.__init__(self, "line %d, column %d: expected %s , got: %s ..." % (self.line, self.column, expected, got))48 Exception.__init__(self, "line %d, column %d: expected %s in %s, got: %s ..." % (self.line, self.column, expected, self.element_name(), got)) 49 49 50 50 def get_position_strings(self): … … 57 57 caret_pos = self.column 58 58 return [error_line, ' ' * (caret_pos - 1) + '^'] 59 60 def element_name(self): 61 return re.sub('([A-Z])', lambda m: ' ' + m.group(1).lower(), self.element.__class__.__name__).strip() 59 62 60 63 … … 230 233 231 234 232 class Range Literal(_Element):233 RANGE = re.compile(r' \[[ \t]*(\-?\d+)[ \t]*\.\.[ \t]*(\-?\d+)[ \t]*\](.*)$')235 class Range(_Element): 236 RANGE = re.compile(r'(\-?\d+)[ \t]*\.\.[ \t]*(\-?\d+)(.*)$') 234 237 235 238 def parse(self): … … 242 245 243 246 247 class ValueList(_Element): 248 COMMA = re.compile(r'\s*,\s*(.*)$', re.S) 249 250 def parse(self): 251 self.values = [] 252 try: value = self.next_element(Value) 253 except NoMatch: 254 pass 255 else: 256 self.values.append(value) 257 while self.optional_match(self.COMMA): 258 value = self.require_next_element(Value, 'value') 259 self.values.append(value) 260 261 def calculate(self, namespace): 262 for value in self.values: 263 yield value.calculate(namespace) 264 265 266 class _EmptyValues: 267 def calculate(self, namespace): 268 return [] 269 270 271 class ArrayLiteral(_Element): 272 START = re.compile(r'\[[ \t]*(.*)$') 273 END = re.compile(r'[ \t]*\](.*)$') 274 values = _EmptyValues() 275 276 def parse(self): 277 self.identity_match(self.START) 278 try: 279 self.values = self.next_element((Range, ValueList)) 280 except NoMatch: 281 pass 282 self.require_match(self.END, ']') 283 self.calculate = self.values.calculate 284 285 244 286 class Value(_Element): 245 287 def parse(self): 246 self.expression = self.next_element((SimpleReference, IntegerLiteral, StringLiteral, SingleQuotedStringLiteral, RangeLiteral))288 self.expression = self.next_element((SimpleReference, IntegerLiteral, StringLiteral, SingleQuotedStringLiteral, ArrayLiteral)) 247 289 248 290 def calculate(self, namespace): … … 273 315 return None ## TODO: an explicit 'not found' exception? 274 316 if self.parameters is not None: 275 values = [value.calculate(top_namespace) for value in self.parameters.values] 276 result = result(*values) 317 result = result(*self.parameters.calculate(top_namespace)) 277 318 return result 278 319 … … 308 349 class ParameterList(_Element): 309 350 START = re.compile(r'\(\s*(.*)$', re.S) 351 COMMA = re.compile(r'\s*,\s*(.*)$', re.S) 310 352 END = re.compile(r'\s*\)(.*)$', re.S) 311 COMMA = re.compile(r'\s*,\s*(.*)$', re.S) 312 313 def parse(self): 314 self.values = [] 315 self.identity_match(self.START) 316 try: value = self.next_element(Value) 317 except NoMatch: 318 pass 319 else: 320 self.values.append(value) 321 while self.optional_match(self.COMMA): 322 value = self.require_next_element(Value, 'value') 323 self.values.append(value) 353 values = _EmptyValues() 354 355 def parse(self): 356 self.identity_match(self.START) 357 try: self.values = self.next_element(ValueList) 358 except NoMatch: pass 324 359 self.require_match(self.END, ')') 360 361 def calculate(self, namespace): 362 return self.values.calculate(namespace) 325 363 326 364 trunk/airspeed_test.py
r29 r30 377 377 self.assertEquals('2,1,0,-1,-2,', template.merge({})) 378 378 379 def test_local_namespace_methods_ not_available(self):379 def test_local_namespace_methods_are_not_available_in_context(self): 380 380 template = airspeed.Template('#macro(tryme)$values#end#tryme()') 381 381 self.assertEquals('$values', template.merge({})) 382 383 def test_array_literal(self): 384 template = airspeed.Template('#set($values = ["Hello ", $person, ", your lucky number is ", 7])#foreach($value in $values)$value#end') 385 self.assertEquals('Hello Chris, your lucky number is 7', template.merge({'person': 'Chris'})) 386 387 def test_nested_array_literals(self): 388 template = airspeed.Template('#set($values = [["Hello ", "Steve"], ["Hello", " Chris"]])#foreach($pair in $values)#foreach($word in $pair)$word#end. #end') 389 self.assertEquals('Hello Steve. Hello Chris. ', template.merge({})) 382 390 383 391 # … … 386 394 # Math expressions 387 395 # Gobbling up whitespace (tricky!) 388 # range literals389 396 # list literals 390 397 # Bind #macro calls at compile time? 391 398 # #stop ? 392 # Interpolated strings 399 # Interpolated strings -- what about \$ etc? 393 400 # Directives inside string literals 394 401 # map literals
