Package VisionEgg :: Package PyroApps :: Module AST_ext
[frames] | no frames]

Source Code for Module VisionEgg.PyroApps.AST_ext

  1  ## Automatically adapted for numpy.oldnumeric Jun 18, 2007 by alter_code1.py 
  2   
  3  # The Vision Egg: AST_ext 
  4  # 
  5  # Copyright (C) 2004 Imran S. Ali, Lachlan Dowd 
  6  # 
  7  # Authors: Imran S. Ali, Lachlan Dowd 
  8  # URL: <http://www.visionegg.org/> 
  9  # 
 10  # Distributed under the terms of the GNU Lesser General Public License 
 11  # (LGPL). See LICENSE.TXT that came with this file. 
 12  # 
 13  # $Id$ 
 14   
 15  # This "AST extensions" module works for Python 2.2.1 
 16  # Because the structure of code trees changes with different Python versions, this module may not work with some 
 17  # previous Python releases, or future releases. 
 18   
 19  import pprint 
 20  import parser 
 21  import symbol 
 22  import token 
 23  import tokenize 
 24  import sys 
 25   
 26  # Hopefully, the node ID numbers in the name sequence is all that 
 27  # needs to be changed in order to get this module working with 
 28  # different Python release versions. 
 29   
 30  name_sequence = [292, 293, 294, 295, 297, 298, 299, 300, 301, 302, 
 31  303, 304, 305] 
 32   
 33  # Method for generating an AST sub tree (in list form) suitable for a 
34 -def gen_assign_val_subtree(assign_val, assign_val_type):
35 name_sequence.reverse() 36 sublist = [] 37 if assign_val_type == 2: 38 sublist = [2, '%(assign_val)d' % vars()] 39 elif assign_val_type == 1: 40 sublist = [2, '%(assign_val)f' % vars()] 41 elif assign_val_type == 3: 42 sublist = [3, '"%(assign_val)s"' % vars()] 43 for val in name_sequence[0:len(name_sequence) - 1]: 44 sublist = [val, sublist] 45 name_sequence.reverse() 46 return sublist
47 48
49 -class AST_Visitor:
50 - def __init__(self, modifying_AST):
51 # Flags: 52 53 # Checking assignment name (ie. "x = ..." where we are 54 # checking if 'x' == 'assign_name'): 55 self.checking_assign_name = 0 56 57 # Setting assignment value (we are changing a found occurrence 58 # of "assign_name = x" to "assign_name = assign_val"): 59 self.setting_assign_val = 0 60 61 # Index of where the AST visitor is currently at in the 62 # 'name_sequence' defined earlier: 63 self.name_seq_index = 0 64 65 # AST visitor expects a subtree associated with 66 # assignment/"=": 67 self.expecting_equals = 0 68 69 # Extracting assignment value (we are extracting the 'x' from 70 # a found occurrence of "assign_name = x"): 71 self.extracting_assign_val = 0 72 73 # Extracted assignment value: 74 self.extracted_val = "not found" 75 76 # Are we modifying an AST? Otherwise we're extracting 77 # information from an AST: 78 self.modifying_AST = modifying_AST
79
80 - def traverse(self, AST_sublist, assign_name, assign_val_subtree):
81 82 # If we have a single element (terminating leaf node): 83 if type(AST_sublist) != list: 84 return AST_sublist 85 86 # If we have a sub tree of the form [x, [....]]: 87 elif len(AST_sublist) == 2: 88 89 # If we are somewhere in the 'name_sequence' defined 90 # earlier: [292, [293, [294, [295, [297, [298, [299, [300, 91 # [301, [302, [303, [304, [305, ... 92 93 if self.name_seq_index > 0: 94 # If we are at the end of the 'name_sequence': 95 if self.name_seq_index == len(name_sequence) - 1 and AST_sublist[0] == name_sequence[self.name_seq_index]: 96 if len(AST_sublist[1]) == 3: 97 if self.extracting_assign_val == 1: 98 extracted_val = AST_sublist[1][1] 99 self.extracted_val = extracted_val 100 self.extracting_assign_val = 0 101 else: 102 # Enter new mode: AST visitor will check 103 # the name associated with the 104 # 'name_sequence' to see if it will match 105 # 'assign_name': 106 self.checking_assign_name = 1 107 self.name_seq_index = 0 108 109 else: 110 expected_val = name_sequence[self.name_seq_index] 111 if AST_sublist[0] == expected_val: 112 # Update position in 'name_sequence': 113 self.name_seq_index = self.name_seq_index + 1 114 else: 115 self.name_seq_index = 0 116 return AST_sublist[0:1] + [self.traverse(AST_sublist[1], assign_name, assign_val_subtree)] 117 118 # Else we are in some arbitrary sequence: 119 # [a, [b, [c, [d, [e, [... 120 else: 121 # If we are at the start of the 'name_sequence': 122 if AST_sublist[0] == 292: 123 if self.setting_assign_val == 1: 124 AST_sublist[1] = assign_val_subtree 125 self.setting_assign_val = 0 126 else: 127 # Enter new mode: AST visitor will check to 128 # see if we are progressing through the 129 # 'name_sequence' defined earlier: 130 self.name_seq_index = 1 131 return AST_sublist[0:1] + [self.traverse(AST_sublist[1], assign_name, assign_val_subtree)] 132 else: 133 return AST_sublist[0:1] + [self.traverse(AST_sublist[1], assign_name, assign_val_subtree)] 134 135 # If we have a sub tree with 3 parent nodes: 136 elif len(AST_sublist) == 3: 137 138 # If the second parent node is a single element 139 # (terminating leaf node): 140 if type(AST_sublist[1]) != list: 141 # If the current AST visitor mode is set to checking 142 # for equality with "assign_name" (ie. "x = ..." where 143 # we are checking if 'x' == 'assign_name'):: 144 if self.checking_assign_name == 1: 145 # If 'x' == 'assign_name' (see above): 146 if AST_sublist[1] == assign_name: 147 # Enter new mode: AST visitor will check to 148 # see if the current sub tree is associated 149 # with assignment/"=": 150 self.expecting_equals = 1 151 self.checking_assign_name = 0 152 153 # If the current AST visitor mode is set to check if 154 # the current sub tree is associated with 155 # assignment/"=": 156 elif self.expecting_equals == 1: 157 # If the current AST sub tree is associated with 158 # assignment/"=": 159 if AST_sublist[1] == '=': 160 if self.modifying_AST == 1: 161 # Enter new mode: AST visitor will change 162 # the assignment value to 163 # "assign_val_subtree": 164 self.setting_assign_val = 1 165 elif self.modifying_AST == 0: 166 # Enter new mode: AST visitor will extract 167 # the assignment value of "assign_name": 168 self.extracting_assign_val = 1 169 self.expecting_equals = 0 170 171 return AST_sublist[0:2] 172 173 # If we are somewhere within the 'name_sequence': 174 if self.name_seq_index > 0 or self.name_seq_index < len(name_sequence) - 1: 175 # If the AST visitor is extracting the value of "assign_name": 176 if self.extracting_assign_val == 1: 177 self.extracted_val = "compound" 178 self.extracting_assign_val = 0 179 180 181 # For all other types of sub trees, AST visitor will traverse 182 # in a depth first search pattern: 183 sub_list = [] 184 for x in AST_sublist: 185 sub_list = sub_list + [self.traverse(x, assign_name, assign_val_subtree)] 186 return sub_list
187
188 -def modify_AST(myAST, assign_name, assign_val):
189 myAST_Visitor = AST_Visitor(1) 190 old_AST_list = myAST.tolist(1) 191 assign_val_type = 0 192 if isinstance(assign_val, int): 193 assign_val_type = 2 194 elif isinstance(assign_val, float): 195 assign_val_type = 1 196 elif type(assign_val) == str: 197 assign_val_type = 3 198 new_AST_list = myAST_Visitor.traverse(old_AST_list, assign_name, gen_assign_val_subtree(assign_val, assign_val_type)) 199 myNewAST = parser.sequence2ast(new_AST_list) 200 return myNewAST
201 202 # Extract the assigned value of a variable from an AST. Retains the type.
203 -def extract_from_AST(myAST, assign_name):
204 myAST_Visitor = AST_Visitor(0) 205 old_AST_list = myAST.tolist(1) 206 new_AST_list = myAST_Visitor.traverse(old_AST_list, assign_name, 0) 207 return myAST_Visitor.extracted_val
208