Changeset 10

Show
Ignore:
Timestamp:
12/08/04 13:12:04 (4 years ago)
Author:
steve
Message:

set integer vars

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/airspeed.py

    r9 r10  
    44import cStringIO as StringIO 
    55 
     6 
    67class TemplateSyntaxError(Exception): pass 
    78 
    89class Tokeniser: 
    9     PLAIN, IF, PLACEHOLDER, FOREACH, END = range(5
     10    PLAIN, IF, PLACEHOLDER, FOREACH, END, SET = range(6
    1011 
    1112    UP_TO_NEXT_TEMPLATE_BIT = re.compile('^(.*?)((?:#|\$).*)', re.MULTILINE + re.DOTALL) 
     
    1516    EXPRESSION = '(' + NAME_OR_CALL + '(?:\.' + NAME_OR_CALL + ')*)' 
    1617    PLACEHOLDER_PATTERN = re.compile('^\$(!?)({?)' + EXPRESSION + '(}?)' + REST, re.IGNORECASE + re.DOTALL + re.MULTILINE) 
     18    SET_PATTERN = re.compile('^#set[ \t]*\([ \t]*\$(' + NAME + ')[ \t]*=[ \t]*(\d+)[ \t]*\)' + REST, re.IGNORECASE + re.DOTALL + re.MULTILINE) 
    1719    BEGIN_IF_PATTERN = re.compile('^#if[ \t]*\([ \t]*\$' + EXPRESSION + '[ \t]*\)' + REST, re.IGNORECASE + re.DOTALL + re.MULTILINE) 
    1820    BEGIN_FOREACH_PATTERN = re.compile('^#foreach[ \t]*\([ \t]*\$(' + NAME + ')[ \t]+in[ \t]+\$' + EXPRESSION + '[ \t]*\)' + REST, re.IGNORECASE + re.DOTALL + re.MULTILINE) 
     
    4648                yield self.END, None 
    4749                (text,) = m.groups() 
     50                continue 
     51            m = self.SET_PATTERN.match(interesting) 
     52            if m: 
     53                (var_name, rvalue, text) = m.groups() 
     54                yield self.SET, (var_name, rvalue) 
     55                continue 
     56            if interesting.startswith('$'): 
     57                text = interesting[1:] 
     58                yield self.PLAIN, '$' 
    4859                continue 
    4960            raise TemplateSyntaxError("invalid token: %s" % text[:40]) 
     
    93104 
    94105    def evaluate(self, output_stream, namespace): 
     106        self.evaluate_block(output_stream, BlockEvaluator.LocalNamespace(namespace)) 
     107 
     108    def evaluate_block(self, output_stream, namespace): 
    95109        for child in self.children: 
    96110            child.evaluate(output_stream, namespace) 
     
    116130        elif token_type == Tokeniser.FOREACH: self.add_evaluator(ForeachEvaluator(token_value)) 
    117131        elif token_type == Tokeniser.IF: self.add_evaluator(IfEvaluator(token_value)) 
     132        elif token_type == Tokeniser.SET: self.add_evaluator(SetEvaluator(token_value)) 
    118133        else: raise TemplateSyntaxError("illegal token in block: %s, %s" % (token_type, token_value)) 
    119134        return True 
     
    147162        self.condition_expression = token_value 
    148163 
    149     def evaluate(self, output_stream, namespace): 
     164    def evaluate_block(self, output_stream, namespace): 
    150165        value = self.eval_expression(self.condition_expression, namespace) 
    151166        if value: 
    152             BlockEvaluator.evaluate(self, output_stream, namespace) 
     167            BlockEvaluator.evaluate_block(self, output_stream, namespace) 
    153168 
    154169 
     
    158173        self.expression, self.iter_var = token_value 
    159174 
    160     def evaluate(self, output_stream, namespace): 
     175    def evaluate_block(self, output_stream, namespace): 
    161176        values = self.eval_expression(self.expression, namespace) 
    162177        counter = 1 
    163178        for value in values: 
    164             local_namespace = BlockEvaluator.LocalNamespace(namespace) 
    165             local_namespace[self.iter_var] = value 
    166             local_namespace['velocityCount'] = counter 
    167             BlockEvaluator.evaluate(self, output_stream, local_namespace) 
     179            namespace[self.iter_var] = value 
     180            namespace['velocityCount'] = counter 
     181            BlockEvaluator.evaluate_block(self, output_stream, namespace) 
    168182            counter += 1 
     183 
     184 
     185class SetEvaluator(Evaluator): 
     186    def __init__(self, token_value): 
     187        self.var_name, self.rvalue = token_value 
     188 
     189    def evaluate(self, output_stream, namespace): 
     190        namespace[self.var_name] = int(self.rvalue) 
    169191 
    170192 
  • trunk/airspeed_test.py

    r9 r10  
    1414        template = airspeed.Template("Hello $name") 
    1515        self.assertEquals("Hello Chris", template.merge({"name": "Chris"})) 
     16 
     17    def test_dollar_left_untouched(self): 
     18        template = airspeed.Template("Hello $ ") 
     19        self.assertEquals("Hello $ ", template.merge({})) 
    1620 
    1721    def test_unmatched_name_does_not_get_substituted(self): 
     
    109113 
    110114    def test_loop_counter_variables_do_not_clash_in_nested_loops(self): 
    111         template = airspeed.Template("#foreach ($word in $greetings)outer $velocityCount#foreach ($word in $names), inner $velocityCount#end. #end") 
     115        template = airspeed.Template("#foreach ($word in $greetings)Outer $velocityCount#foreach ($word in $names), inner $velocityCount#end. #end") 
    112116        namespace = {"greetings": ["Hello", "Goodbye"], "names": ["Chris", "Steve"]} 
    113         self.assertEquals("outer 1, inner 1, inner 2. outer 2, inner 1, inner 2. ", template.merge(namespace)) 
     117        self.assertEquals("Outer 1, inner 1, inner 2. Outer 2, inner 1, inner 2. ", template.merge(namespace)) 
     118 
     119    def test_can_use_an_integer_variable_defined_in_template(self): 
     120        template = airspeed.Template("#set ($value = 10)$value") 
     121        self.assertEquals("10", template.merge({})) 
     122 
     123    def test_passed_in_namespace_not_modified_by_set(self): 
     124        template = airspeed.Template("#set ($value = 10)$value") 
     125        namespace = {} 
     126        template.merge(namespace) 
     127        self.assertEquals({}, namespace) 
    114128 
    115129