def __init__(self, lib_name, astnode_names, astnode_kinds, prefix): """ :param str lib_name: Lower-case name for the generated library. :param list[str] astnode_names: List of camel-with-mixed-case names for all node types. :param dict[int, str] astnode_kinds: Mapping of kinds ('Enum_Rep) to camel-with-mixed-case node names. :param str prefix: Prefix to use for command names. """ self.lib_name = lib_name self.astnode_names = [Name(name) for name in astnode_names] self.astnode_kinds = { kind: Name(name) for kind, name in astnode_kinds.items() } self.prefix = prefix self.node_record = ('{}__implementation__root_node_record'.format( self.lib_name)) """ Name of the record type used to represent node data. """ self.entity_struct_names = self._entity_struct_names() self.reparse_debug_info()
def construct_operand(op): from langkit.expressions import Cast, New expr = construct(op) check_source_language( expr.type == LogicVarType or expr.type.matches(T.root_node) or expr.type.matches(T.root_node.env_el()), "Operands to a logic bind operator should be either " "a logic variable or an ASTNode, got {}".format(expr.type) ) if expr.type.matches(T.root_node.env_el()): if expr.type is not T.root_node.env_el(): expr = Cast.Expr(expr, T.root_node.env_el()) elif expr.type.matches(T.root_node): # Cast the ast node type if necessary if expr.type is not T.root_node: expr = Cast.Expr(expr, T.root_node) # If the expression is a root node, implicitly construct an # env_element from it. expr = New.StructExpr(T.root_node.env_el(), { Name('El'): expr, Name('MD'): LiteralExpr('<>', None), Name('Parents_Bindings'): LiteralExpr('null', None) }) return expr
def check_token_families(self, context): """ Pass that checks that either there are no defined token families, or that they form a partition of existing tokens. """ def format_token_list(tokens): return ', '.join(sorted( t.dsl_name if isinstance(t, TokenAction) else str(t) for t in tokens )) # Sort token families by name to ensure legality checks and code # generation determinism. self.tokens.token_families.sort(key=lambda tf: tf.name) all_tokens = set(self.tokens) seen_tokens = set() for family in self.tokens.token_families: with family.diagnostic_context: not_tokens = family.tokens - all_tokens check_source_language( not not_tokens, 'Invalid tokens: {}'.format(format_token_list(not_tokens)) ) already_seen_tokens = seen_tokens & family.tokens check_source_language( not already_seen_tokens, 'Tokens must belong to one family exclusively: {}' .format(format_token_list(already_seen_tokens)) ) seen_tokens.update(family.tokens) # Create a token family to host all tokens that are not associated with # a specific token family. default_family = TokenFamily(*list(all_tokens - seen_tokens)) default_family.name = Name('Default_Family') self.tokens.token_families.append(default_family) # Make it easy to get the family a token belongs to for tf in self.tokens.token_families: for t in tf.tokens: self.tokens.token_to_family[t] = tf