from enum import Enum from core.concept import Concept class BuiltinConcepts(Enum): """ List of builtin concepts that do no need any specific implementation Please note that the value of the enum is informal. It is not used in the system For example, the concept 'NODE' DOES NOT have the key, the id or whatever 200 The key if the name of the concept The id is a sequential number given just before the concept is saved in sdp The values of the enum are just a convenient way for me to group the concepts """ SHEERKA = 1 SUCCESS = 2 ERROR = 3 UNKNOWN_CONCEPT = 4 # the request concept is not recognized RETURN_VALUE = 5 # a value is returned CONCEPT_TOO_LONG = 6 # concept cannot be processed by exactConcept parser NEW_CONCEPT = 7 # when a new concept is added UNKNOWN_PROPERTY = 8 # when requesting for a unknown property PARSER_RESULT = 9 TOO_MANY_SUCCESS = 10 # when expecting a limited number of successful return value TOO_MANY_ERRORS = 11 # when expecting a limited number of successful return value NOT_FOR_ME = 12 # a parser recognize that the entry is not meant for it IS_EMPTY = 13 # when a set is empty INVALID_RETURN_VALUE = 14 # the return value of an evaluator is not correct BEFORE_PARSING = 15 # activated before evaluation by the parsers PARSING = 16 # activated during the parsing. It contains the text to parse AFTER_PARSING = 17 # after parsing BEFORE_EVALUATION = 18 # before evaluation EVALUATION = 19 # activated when the parsing process seems to be finished AFTER_EVALUATION = 20 # activated when the parsing process seems to be finished CONCEPT_ALREADY_DEFINED = 21 # when you try to add the same concept twice NOP = 22 # no operation concept. Does nothing PROPERTY_EVAL_ERROR = 23 # cannot evaluate a property of a concept ENUMERATION = 24 # represents a list or a set LIST = 25 # represents a list CANNOT_RESOLVE_VALUE_ERROR = 26 # In presence of a concept where the default value is not know NODE = 200 GENERIC_NODE = 201 IDENTIFIER_NODE = 202 """ Some concepts have a specific implementation It's mainly to a have proper __repr__ implementation, or redefine the is_unique attribut """ class SuccessConcept(Concept): def __init__(self): super().__init__(BuiltinConcepts.SUCCESS, True, True, BuiltinConcepts.SUCCESS) class ErrorConcept(Concept): def __init__(self, error=None): super().__init__(BuiltinConcepts.ERROR, True, False, BuiltinConcepts.ERROR, body=error) def __repr__(self): return f"({self.id}){self.name}: {self.body}" class ReturnValueConcept(Concept): """ This class represents the result of a data flow processing It's the main input for the evaluators """ def __init__(self, who=None, status=None, value=None, message=None, parents=None): super().__init__(BuiltinConcepts.RETURN_VALUE, True, False, BuiltinConcepts.RETURN_VALUE) self.set_prop("who", who) self.set_prop("status", status) self.body = value self.set_prop("message", message) self.set_prop("parents", parents) @property def who(self): return self.props["who"].value @who.setter def who(self, value): self.set_prop("who", value) @property def status(self): return self.props["status"].value @status.setter def status(self, value): self.set_prop("status", value) @property def value(self): return self.body @value.setter def value(self, value): self.body = value @property def message(self): return self.props["message"].value @message.setter def message(self, value): self.set_prop("message", value) @property def parents(self): return self.props["parents"].value @parents.setter def parents(self, value): self.set_prop("parents", value) def __repr__(self): return f"ReturnValue(who={self.who}, status={self.status}, value={self.value}, message={self.message})" def __eq__(self, other): if not isinstance(other, ReturnValueConcept): return False return self.who == other.who and \ self.status == other.status and \ self.value == other.value and \ self.message == other.message def __hash__(self): return hash((self.who, self.status, self.value)) class UnknownPropertyConcept(Concept): """ This error is raised when, during sheerka.new(), an unknown property is asked """ def __init__(self, property_name=None, concept=None): super().__init__(BuiltinConcepts.UNKNOWN_PROPERTY, True, False, BuiltinConcepts.UNKNOWN_PROPERTY) self.set_prop("concept", concept) self.body = property_name def __repr__(self): return f"UnknownProperty(property={self.property_name}, concept={self.concept})" @property def concept(self): return self.props["concept"].value @property def property_name(self): return self.body class ParserResultConcept(Concept): """ Result of a parsing """ def __init__(self, parser=None, source=None, value=None, try_parsed=None): super().__init__(BuiltinConcepts.PARSER_RESULT, True, False, BuiltinConcepts.PARSER_RESULT) self.set_prop("parser", parser) self.set_prop("source", source) self.set_prop("try_parsed", try_parsed) # in case of error, what was found before the error self.body = value def __repr__(self): return f"ParserResult({self.body})" def __eq__(self, other): if not isinstance(other, ParserResultConcept): return False return self.source == other.source and \ self.parser == other.parser and \ self.body == other.body and \ self.try_parsed == other.try_parsed @property def value(self): return self.body @property def try_parsed(self): return self.props["try_parsed"].value @property def source(self): return self.props["source"].value @property def parser(self): return self.props["parser"].value class InvalidReturnValueConcept(Concept): """ Error returned when an evaluator is not correctly coded The accepted return value are ReturnValueConcept, list of ReturnValueConcept or None """ def __init__(self, return_value=None, evaluator=None): super().__init__(BuiltinConcepts.INVALID_RETURN_VALUE, True, False, BuiltinConcepts.INVALID_RETURN_VALUE) self.set_prop("evaluator", evaluator) self.body = return_value class BeforeParsingConcept(Concept): def __init__(self): super().__init__(BuiltinConcepts.BEFORE_PARSING, True, True, BuiltinConcepts.BEFORE_PARSING) class EvaluationConcept(Concept): def __init__(self): super().__init__(BuiltinConcepts.EVALUATION, True, True, BuiltinConcepts.EVALUATION) class AfterEvaluationConcept(Concept): def __init__(self): super().__init__(BuiltinConcepts.AFTER_EVALUATION, True, True, BuiltinConcepts.AFTER_EVALUATION) class PropertyEvalError(Concept): def __init__(self, property_name=None, concept=None, error=None): super().__init__(BuiltinConcepts.PROPERTY_EVAL_ERROR, True, False, BuiltinConcepts.PROPERTY_EVAL_ERROR) self.set_prop("concept", concept) self.set_prop("error", error) self.body = property_name def __repr__(self): return f"PropertyEvalError(property={self.property_name}, concept={self.concept}), error={self.error})" @property def concept(self): return self.props["concept"].value @property def error(self): return self.props["error"].value @property def property_name(self): return self.body class EnumerationConcept(Concept): def __init__(self, iteration=None): super().__init__(BuiltinConcepts.ENUMERATION, True, False, BuiltinConcepts.ENUMERATION) self.body = iteration def __iter__(self): return iter(self.body) class ListConcept(Concept): def __init__(self, items=None): super().__init__(BuiltinConcepts.LIST, True, False, BuiltinConcepts.LIST) self.body = items or [] def append(self, obj): self.body.append(obj) def __len__(self): return len(self.body) def __getitem__(self, key): return self.body[key] def __setitem__(self, key, value): self.body[key] = value def __iter__(self): return iter(self.body) def __contains__(self, item): return item in self.body