Fixed variable recognition when it is a concept

This commit is contained in:
2020-11-20 17:24:52 +01:00
parent 315f8ea09b
commit 0e945fe0fd
8 changed files with 79 additions and 36 deletions
+3
View File
@@ -691,6 +691,9 @@ class Sheerka(Concept):
return None
return new_instances(concept) if return_new else concept
def fast_get_by_name(self, name):
return self.cache_manager.get(self.CONCEPTS_BY_NAME_ENTRY, name)
def has_id(self, concept_id):
"""
Returns True if a concept with this id exists in cache
@@ -21,6 +21,7 @@ class SheerkaCreateNewConcept(BaseService):
def initialize(self):
self.sheerka.bind_service_method(self.create_new_concept, True)
self.sheerka.bind_service_method(self.not_is_variable, False, visible=False)
def create_new_concept(self, context, concept: Concept):
"""
@@ -108,3 +109,11 @@ class SheerkaCreateNewConcept(BaseService):
refs.add(concept.id)
return refs
def not_is_variable(self, name):
"""
Given a name tells if it refers to a variable name
:param name:
:return:
"""
return not self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_BY_NAME_ENTRY, name)
+7 -9
View File
@@ -8,7 +8,7 @@ from evaluators.BaseEvaluator import OneReturnValueEvaluator
from parsers.BaseParser import NotInitializedNode
from parsers.BnfNodeParser import ParsingExpression, ParsingExpressionVisitor
from parsers.DefConceptParser import DefConceptNode, NameNode
from parsers.PythonParser import PythonNode
from parsers.PythonParser import PythonNode, get_python_node
class ConceptOrRuleNameVisitor(ParsingExpressionVisitor):
@@ -129,15 +129,13 @@ class DefConceptEvaluator(OneReturnValueEvaluator):
This function can only be a draft, as there may be tons of different situations
I guess that it can only be complete when will we have access to Sheerka memory
"""
#
# Case of NameNode
#
if isinstance(ret_value, NameNode):
names = [str(t.value) for t in ret_value.tokens if t.type in (
TokenKind.IDENTIFIER, TokenKind.STRING, TokenKind.KEYWORD)]
variables = filter(lambda x: x in concept_name, names)
return set(variables)
return set(filter(lambda x: x in concept_name and context.sheerka.not_is_variable(x), names))
#
# case of BNF
@@ -150,13 +148,13 @@ class DefConceptEvaluator(OneReturnValueEvaluator):
#
# Case of python code
#
if isinstance(ret_value.value, ParserResultConcept) and isinstance(ret_value.value.value, PythonNode):
if (python_node := get_python_node(ret_value.value.value)) is not None:
if len(concept_name) > 1:
python_node = ret_value.value.value
visitor = UnreferencedVariablesVisitor(context)
names = visitor.get_names(python_node.ast_)
variables = filter(lambda x: x in concept_name, names)
return set(variables)
return set(filter(lambda x: x in concept_name and context.sheerka.not_is_variable(x), names))
else:
return set()
#
# Concept
@@ -172,4 +170,4 @@ class DefConceptEvaluator(OneReturnValueEvaluator):
variables.add(identifier)
return variables
return []
return set()
+2 -3
View File
@@ -12,7 +12,7 @@ from core.rule import Rule
from core.sheerka.ExecutionContext import ExecutionContext
from core.tokenizer import Token, TokenKind
from evaluators.BaseEvaluator import OneReturnValueEvaluator
from parsers.PythonParser import PythonNode
from parsers.PythonParser import PythonNode, get_python_node
TO_DISABLED = ["breakpoint", "callable", "compile", "delattr", "eval", "exec", "exit", "input", "locals", "open",
"print", "quit", "setattr"]
@@ -88,8 +88,7 @@ class PythonEvaluator(OneReturnValueEvaluator):
def eval(self, context, return_value):
sheerka = context.sheerka
node = return_value.value.value if isinstance(return_value.value.value, PythonNode) else \
return_value.value.value.python_node
node = get_python_node(return_value.value.value)
debugger = context.get_debugger(PythonEvaluator.NAME, "eval")
debugger.debug_entering(node=node)
+7 -1
View File
@@ -18,6 +18,12 @@ class ChickenAndEggError(Exception):
concepts: Set[str]
@dataclass
class NoFirstTokenError(ErrorNode):
concept: Concept
key: str
@dataclass()
class LexerNode(Node):
start: int # starting index in the tokens list
@@ -891,7 +897,7 @@ class BaseNodeParser(BaseParser):
if keywords is None:
# no first token found for a concept ?
return sheerka.ret(sheerka.name, False, concept)
return sheerka.ret(sheerka.name, False, NoFirstTokenError(concept, concept.key))
for keyword in keywords:
res.setdefault(keyword, []).append(concept.id)
+8
View File
@@ -11,6 +11,14 @@ from parsers.BaseParser import BaseParser, Node, ErrorNode
log = logging.getLogger(__name__)
def get_python_node(obj):
if isinstance(obj, PythonNode):
return obj
if hasattr(obj, "python_node"):
return obj.python_node
return None
@dataclass()
class PythonErrorNode(ErrorNode):
source: str