def make_node(parent, parent_node=None, name=None, node_type="data"): if name == None: name = '' # If we don't have a parent node, create a start node if parent_node == None: raise Exception("This should never happen") #cur_node = Node([Node(name="Start")], name=name, node_type=node_type) else: cur_node = Node(parent_node, name=name, node_type=node_type) # Make a starting node original_node = cur_node first_loop = True # For each block, see if it's a loop or a statement for block in parent: # If it's a loop, enter it # Don't recurse into scripts, but any other variable references should be noted def find_references(block): for b in block.findall('block'): if 'var' in b.attrib: yield b.attrib['var'] yield find_references(b) cur_node.add_reference(find_references(block)) cur_node.lines_of_code += 1 if block.attrib['s'] == 'doRepeat' or block.attrib['s'] == 'doUntil': # Recurse on the loops loop # First add the loop node inline # If this is a loop right after a loop, the current node should be made into a loop node loop_node = cur_node if first_loop: loop_node._name = block.attrib['s'] loop_node.node_type='loop' else: # Else, create a new loop node loop_node = Node([cur_node], name=block.attrib['s'], node_type='loop') # Then continue to the loop statement r = make_node(block[1], [loop_node]) # Add this loop_node as a child to the tail node r.add_child(loop_node) # If there are more nodes to be had cur_node = Node([loop_node]) # If it's a conditional, enter it elif block.attrib['s'] == 'doIf': # If we have a data node with no data, convert it to an if if cur_node.data_node() and len(cur_node.variables()) == 0: cur_node.node_type = "if" cur_node._name = "doIf" # Else, create a new node else: cur_node = Node([cur_node], name="doIf", node_type="if") r = make_node(block[1], [cur_node]) cur_node = Node([r, cur_node]) # if it's a statement, add it to the node else: if block.attrib['s'] == 'doSetVar': cur_node.add_variable(block.findall('l')[0].text) cur_node._name += '\n' + block.attrib['s'] if node_type=="loop": cur_node.add_child(original_node) cur_node = original_node return cur_node