111 lines
3.7 KiB
Python
111 lines
3.7 KiB
Python
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.compiled[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.compiled[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
|