def chain_comp(self, tree: TypeTree): symbol_to_data = { "<=": "less_equals", ">=": "greater_equals", "<": "less", ">": "greater", } # Separate expressions and comparison operators. expressions = tree.children[::2] comparisons = tree.children[1::2] # Generate comparison trees. comp_trees = [ TypeTree(symbol_to_data[symbol], [a, b], tree.meta) for symbol, a, b in zip(comparisons, expressions[:-1], expressions[1:]) ] # Build up nested tree. prev_tree = comp_trees[0] for comp_tree in comp_trees[1:]: prev_tree = TypeTree("logic_and", [prev_tree, comp_tree], tree.meta) # Override this node with last. tree.data = prev_tree.data tree.children = prev_tree.children self.visit(tree)
def __init__(self, tree: TypeTree, scope: Callable, args=None, stack_trace: Optional[List[TypeTree]] = None): self.scope = scope self.local_scope = dict() self.used = set() self.stack_trace: List[ TypeTree] = [] if stack_trace is None else stack_trace if args is not None: assign(self, self.local_scope, args[0], args[1]) if tree.data != "block": tree.children = [TypeTree(tree.data, tree.children, tree.meta)] tree.data = "block" tree.children[-1] = TypeTree("return_n", [tree.children[-1]], tree.meta) def ret(value_type): if tree.return_type is None: tree.return_type = value_type self.assert_(tree.return_type == value_type, "block has different return types", tree) self.ret = ret self.visit_children(tree) # sets tree.return_type
def math_assign(self, tree: TypeTree): symbol = tree.children[0] expression = tree.children[1] # Make the current node an assign. operation = tree.data.replace("_assign", "") tree.data = "assign" # Make a child node with the math operation. tree.children[1] = TypeTree(operation, [symbol, expression], tree.meta) return self.visit(tree)
def string(self, tree: TypeTree): tree.data = "array" # Evaluate string using Python try: text = eval(tree.children[0]) except SyntaxError as err: raise VolpeError(err.msg, tree, self.stack_trace) self.assert_(is_ascii(text), "strings can only have ascii characters", tree) tree.children = [] for eval_character in text: tree.children.append( TypeTree("character", [Token("CHARACTER", "'" + eval_character + "'")], tree.meta)) self.visit_children(tree) return VolpeArray(char, len(tree.children))
def if_then(self, tree: TypeTree): tree.data = "implication" tree.children[1] = TypeTree("return_n", [tree.children[1]], tree.meta) return self.visit(tree)
def constant_array_like(self, tree: TypeTree): tree.data = "constant_array" element_type, parent_array = self.visit_children(tree) self.assert_(isinstance(parent_array, VolpeArray), "can only get size of arrays", tree) return VolpeArray(element_type, parent_array.count)