from core.builtin_concepts import BuiltinConcepts from core.tokenizer import TokenKind, Token from parsers.BaseParser import BaseParser from parsers.ConceptLexerParser import ConceptNode, UnrecognizedTokensNode, SourceCodeNode from parsers.MultipleConceptsParser import MultipleConceptsParser from core.concept import VARIABLE_PREFIX import logging multiple_concepts_parser = MultipleConceptsParser() class ConceptsWithConceptsParser(BaseParser): def __init__(self, **kwargs): super().__init__("ConceptsWithConcepts", 25) @staticmethod def get_tokens(nodes): tokens = [] for node in nodes: if isinstance(node, ConceptNode): index, line, column = node.tokens[0].index, node.tokens[0].line, node.tokens[0].column tokens.append(Token(TokenKind.CONCEPT, node.concept, index, line, column)) else: for token in node.tokens: if token.type == TokenKind.EOF: break elif token.type in (TokenKind.NEWLINE, TokenKind.WHITESPACE): continue else: tokens.append(token) return tokens @staticmethod def get_key(nodes): key = "" index = 0 for node in nodes: if key: key += " " if isinstance(node, UnrecognizedTokensNode): key += node.source.strip() else: key += f"{VARIABLE_PREFIX}{index}" index += 1 return key def finalize_concept(self, context, concept, nodes): index = 0 for node in nodes: if isinstance(node, ConceptNode): prop_name = list(concept.props.keys())[index] concept.cached_asts[prop_name] = node.concept context.log( self.verbose_log, f"Setting property '{prop_name}='{node.concept}'.", self.name) index += 1 elif isinstance(node, SourceCodeNode): prop_name = list(concept.props.keys())[index] sheerka = context.sheerka value = sheerka.new(BuiltinConcepts.PARSER_RESULT, parser=self, source=node.source, body=node.node) concept.cached_asts[prop_name] = [context.sheerka.ret(self.name, True, value)] context.log( self.verbose_log, f"Setting property '{prop_name}'='Python({node.source})'.", self.name) index += 1 return concept def parse(self, context, text): sheerka = context.sheerka if not sheerka.isinstance(text, BuiltinConcepts.PARSER_RESULT): return None if not text.parser == multiple_concepts_parser: return None nodes = text.body concept_key = self.get_key(nodes) concept = sheerka.new(concept_key) if sheerka.isinstance(concept, BuiltinConcepts.UNKNOWN_CONCEPT): return sheerka.ret( self.name, False, sheerka.new(BuiltinConcepts.NOT_FOR_ME, body=text.body)) concepts = concept if hasattr(concept, "__iter__") else [concept] for concept in concepts: self.finalize_concept(context, concept, nodes) res = [] for concept in concepts: res.append(sheerka.ret( self.name, True, sheerka.new( BuiltinConcepts.PARSER_RESULT, parser=self, source=text.source, body=concept, try_parsed=None))) return res[0] if len(res) == 1 else res