Added RET keyword

This commit is contained in:
2020-07-07 11:34:40 +02:00
parent 56e1cb4587
commit c4399d631c
21 changed files with 245 additions and 87 deletions
+17 -33
View File
@@ -22,7 +22,7 @@ class SheerkaDump(BaseService):
def initialize(self):
self.sheerka.bind_service_method(self.dump_desc, "desc")
self.sheerka.bind_service_method(self.dump_state, "state")
self.sheerka.bind_service_method(self.dump_sdp, "dump_sdp")
def dump_desc(self, *concept_names, eval=False):
first = True
@@ -47,17 +47,24 @@ class SheerkaDump(BaseService):
if not first:
self.sheerka.log.info("")
self.sheerka.log.info(f"name : {c.name}")
self.sheerka.log.info(f"key : {c.key}")
self.sheerka.log.info(f"bnf : {c.metadata.definition}")
self.sheerka.log.info(f"body : {c.metadata.body}")
self.sheerka.log.info(f"where : {c.metadata.where}")
self.sheerka.log.info(f"name : {c.name}")
self.sheerka.log.info(f"key : {c.key}")
self.sheerka.log.info(f"definition : {c.metadata.definition}")
self.sheerka.log.info(f"type : {c.metadata.definition_type}")
self.sheerka.log.info(f"body : {c.metadata.body}")
self.sheerka.log.info(f"where : {c.metadata.where}")
self.sheerka.log.info(f"pre : {c.metadata.pre}")
self.sheerka.log.info(f"post : {c.metadata.post}")
self.sheerka.log.info(f"ret : {c.metadata.ret}")
self.sheerka.log.info(f"vars : {c.metadata.variables}")
self.sheerka.log.info(f"props : {c.metadata.props}")
if eval:
self.sheerka.log.info(f"value : {value}")
for v in c.values:
self.sheerka.log.info(f"{v}: {c.get_value(v)}")
if c.values:
for v in c.values:
self.sheerka.log.info(f"{v}: {c.get_value(v)}")
else:
self.sheerka.log.info("No property")
self.sheerka.log.info("No variable")
self.sheerka.log.info(f"digest : {c.get_origin()}")
@@ -67,30 +74,7 @@ class SheerkaDump(BaseService):
first = False
# def dump_history(self, page=20, start=0):
# count = 0
# resolved_page = page if page > 0 else 50
# page_count = 0
#
# while count < page if page > 0 else True:
# history = self.sheerka.history(resolved_page, start + page_count * resolved_page)
# try:
# h = next(history)
# except StopIteration:
# break
#
# while True:
# try:
# if h.result:
# self.sheerka.log.info(h)
# count += 1
# h = next(history)
# except StopIteration:
# break
#
# page_count += 1
def dump_state(self):
def dump_sdp(self):
snapshot = self.sheerka.sdp.get_snapshot(SheerkaDataProvider.HeadFile)
state = self.sheerka.sdp.load_state(snapshot)
self.sheerka.log.info(get_pp().pformat(state.data))
@@ -145,10 +145,12 @@ class SheerkaEvaluateConcept(BaseService):
if self.sheerka.has_id(concept.id):
self.sheerka.get_by_id(concept.id).compiled = concept.compiled
def resolve(self, context, to_resolve, current_prop, current_concept, force_evaluation):
def resolve(self, context, to_resolve, current_prop, current_concept, force_evaluation, expect_success):
def get_path(context_, prop_name):
prefix = context_.path if hasattr(context_, "path") else "<N/A>"
concept_name = f'"{context_.action_context.name}"' if isinstance(context_.action_context, Concept) \
else "'N/A'"
prefix = context_.path if hasattr(context_, "path") else concept_name
value = prop_name.name if isinstance(current_prop, ConceptParts) else prop_name
return prefix + "." + value
@@ -178,6 +180,9 @@ class SheerkaEvaluateConcept(BaseService):
if force_evaluation:
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
if expect_success:
sub_context.local_hints.add(BuiltinConcepts.EVAL_SUCCESS_REQUESTED)
# when it's a concept, evaluate it
if isinstance(to_resolve, Concept) and \
not context.sheerka.isinstance(to_resolve, BuiltinConcepts.RETURN_VALUE):
@@ -206,7 +211,7 @@ class SheerkaEvaluateConcept(BaseService):
concept=current_concept,
property_name=current_prop)
def resolve_list(self, context, list_to_resolve, current_prop, current_concept, force_evaluation):
def resolve_list(self, context, list_to_resolve, current_prop, current_concept, force_evaluation, expect_success):
"""When dealing with a list, there are two possibilities"""
# It may be a list of ReturnValueConcept to execute (always the case for metadata)
# or a list of single values (may be the case for properties)
@@ -215,7 +220,12 @@ class SheerkaEvaluateConcept(BaseService):
return []
if self.sheerka.isinstance(list_to_resolve[0], BuiltinConcepts.RETURN_VALUE):
return self.resolve(context, list_to_resolve, current_prop, current_concept, force_evaluation)
return self.resolve(context,
list_to_resolve,
current_prop,
current_concept,
force_evaluation,
expect_success)
res = []
for to_resolve in list_to_resolve:
@@ -226,7 +236,7 @@ class SheerkaEvaluateConcept(BaseService):
concept=current_concept,
property_name=current_prop)
r = self.resolve(context, to_resolve, current_prop, current_concept, force_evaluation)
r = self.resolve(context, to_resolve, current_prop, current_concept, force_evaluation, expect_success)
if self.sheerka.isinstance(r, BuiltinConcepts.CONCEPT_EVAL_ERROR):
return r
res.append(r)
@@ -258,10 +268,10 @@ class SheerkaEvaluateConcept(BaseService):
if isinstance(prop_ast, list):
# Do not send the current concept for the properties
resolved = self.resolve_list(context, prop_ast, var_name, None, True)
resolved = self.resolve_list(context, prop_ast, var_name, None, True, False)
else:
# Do not send the current concept for the properties
resolved = self.resolve(context, prop_ast, var_name, None, True)
resolved = self.resolve(context, prop_ast, var_name, None, True, False)
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
resolved.set_value("concept", concept) # since current concept was not sent
@@ -278,10 +288,20 @@ class SheerkaEvaluateConcept(BaseService):
if part_key in concept.compiled and concept.compiled[part_key] is not None:
metadata_ast = concept.compiled[part_key]
# if part_key is PRE, POST or WHERE, the concepts need to be evaluated
# otherwise the predicates cannot be resolved
# if part_key is PRE, POST or WHERE, the concept need to be evaluated
# if we want the predicates to be resolved => so force_eval = True
# otherwise no need to force
force_concept_eval = False if part_key == ConceptParts.BODY else True
resolved = self.resolve(context, metadata_ast, part_key, concept, force_concept_eval)
# when resolving predicate (where or pre), we need to make sure that PythonEvaluator
# will try every possibilities before returning False
expect_success = part_key in (ConceptParts.WHERE, ConceptParts.PRE)
resolved = self.resolve(context,
metadata_ast,
part_key,
concept,
force_concept_eval,
expect_success)
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
return resolved
else:
@@ -312,9 +332,9 @@ class SheerkaEvaluateConcept(BaseService):
def choose_metadata_to_eval(self, context, concept):
if context.in_context(BuiltinConcepts.EVAL_BODY_REQUESTED):
return ["pre", "post", "variables", "body", "where"]
return ["pre", "post", "variables", "body", "where", "ret"]
metadata = ["pre", "post"]
metadata = ["pre", "post", "ret"]
if context.in_context(BuiltinConcepts.EVAL_WHERE_REQUESTED) or concept.metadata.need_validation:
needed = self.needed_metadata(concept, ConceptParts.WHERE)
for e in needed:
+2 -2
View File
@@ -326,13 +326,13 @@ class SheerkaExecute(BaseService):
result = evaluator.eval(sub_context, item)
if result is None:
# match() was successful but nothing was done in eval
# most of the time, it's because checks made in eval were unsuccessful
# most of the time, it's because extra checks are unsuccessful
debug_result.append({"input": item, "return_value": None})
continue
if id(result) == id(item):
# eval was successful, but we don't want to alter the processing flow
debug_result.append({"input": item, "return_value": item})
debug_result.append({"input": item, "return_value": result})
continue
# otherwise, item will be removed and replaced by result