def concat_string_templates(self, fake_tree, orig_node, string_objs): """ Concatenates the to-be-inserted string templates. For example, a string template like "a{exp}b" gets flatten to: "a" + fake_path_to_exp as string + "b" Strings can be inserted directly, but string templates must be evaluated to new AST nodes and the reference to their fake_node assignment should be used instead. """ ks = [] for s in string_objs: if s['$OBJECT'] == 'string': # plain string -> insert directly str_node = self.build_string_value(orig_node=orig_node, text=s['string']) string_tree = Tree('expression', [ Tree('entity', [ str_node ]) ]) string_tree.kind = 'primary_expression' ks.append(string_tree) else: assert s['$OBJECT'] == 'code' # string template -> eval # ignore newlines in string interpolation code = ''.join(s['code'].split('\n')) evaled_node = self.eval(orig_node, code, fake_tree) # cast to string (`as string`) base_type = orig_node.create_token('STRING_TYPE', 'string') as_operator = Tree('as_operator', [ Tree('types', [ Tree('base_type', [ base_type ]) ]) ]) as_tree = Tree('expression', [ Tree('expression', [ Tree('entity', [ evaled_node ]), ]), as_operator ]) as_tree.kind = 'pow_expression' as_tree.child(0).kind = 'primary_expression' ks.append(as_tree) return ks
def add_strings(n1, *other_nodes): """ Create an AST for concating two or more nodes. """ # concatenation is currently defined as # expression = expression arith_operator expression base_tree = Tree("expression", [n1]) base_tree.kind = "arith_expression" # if we only got one node, no concatenation is required. return # directly if len(other_nodes) == 0: return base_tree.children[0] base_tree.children.append( Tree("arith_operator", [n1.create_token("PLUS", "+")]), ) # Technically, the grammar only supports binary expressions, but # the compiler and engine can handle n-ary expressions, so we can # directly flatten the tree and add all additional nodes as extra # expressions for n2 in other_nodes: base_tree.children.append(n2) return base_tree
def concat_string_templates(self, fake_tree, orig_node, string_objs): """ Concatenates the to-be-inserted string templates. For example, a string template like "a{exp}b" gets flatten to: "a" + fake_path_to_exp as string + "b" Strings can be inserted directly, but string templates must be evaluated to new AST nodes and the reference to their fake_node assignment should be used instead. """ ks = [] for s in string_objs: if s["$OBJECT"] == "string": # plain string -> insert directly str_node = self.build_string_value( orig_node=orig_node, text=s["string"] ) string_tree = Tree("expression", [Tree("entity", [str_node])]) string_tree.kind = "primary_expression" ks.append(string_tree) else: assert s["$OBJECT"] == "code" # string template -> eval # ignore newlines in string interpolation code = "".join(s["code"].split("\n")) evaled_node = self.eval(orig_node, code, fake_tree) # cast to string (`as string`) base_type = orig_node.create_token("STRING_TYPE", "string") to_operator = Tree( "to_operator", [Tree("types", [Tree("base_type", [base_type])])], ) as_tree = Tree( "expression", [ Tree("expression", [Tree("entity", [evaled_node]),]), to_operator, ], ) as_tree.kind = "pow_expression" as_tree.child(0).kind = "primary_expression" ks.append(as_tree) return ks