def test_slots_rt(): ns = Namespace("root", None) rs = Resolver(ns) e = Entity("xx", ns) qs = QueueScheduler(None, [], [], None, set()) r = RelationAttribute(e, None, "xx", Location("", 1)) i = Instance(e, rs, qs) assert_slotted(ResultVariable()) assert_slotted(AttributeVariable(None, None)) assert_slotted(Promise(None, None)) assert_slotted(ListVariable(r, i, qs)) assert_slotted(OptionVariable(r, i, qs)) assert_slotted(qs) assert_slotted(DelegateQueueScheduler(qs, None)) assert_slotted(Waiter(qs)) assert_slotted( ExecutionUnit(qs, r, ResultVariable(), {}, Literal(""), None)) assert_slotted(HangUnit(qs, r, {}, None, Resumer())) assert_slotted(RawUnit(qs, r, {}, Resumer())) assert_slotted(FunctionUnit(qs, rs, ResultVariable(), {}, None)) assert_slotted(i)
def resume(self, requires: Dict[object, ResultVariable], resolver: Resolver, queue_scheduler: QueueScheduler) -> None: """ Instance is ready to execute, do it and see if the attribute is already present """ try: # get the Instance obj = self.instance.execute( {k: v.get_value() for k, v in requires.items()}, resolver, queue_scheduler) if isinstance(obj, list): raise RuntimeException( self, "can not get a attribute %s, %s is a list" % (self.attribute, obj)) # get the attribute result variable attr = obj.get_attribute(self.attribute) # Cache it self.attr = attr if attr.is_ready(): # go ahead # i.e. back to the AttributeReference itself attr.get_value() self.target.set_value(True, self.location) else: requires["x"] = attr # reschedule on the attribute, XU will assign it to the target variable RawUnit(queue_scheduler, resolver, requires, self) except RuntimeException: self.target.set_value(False, self.location)
def resume(self, requires: Dict[object, ResultVariable], resolver: Resolver, queue: QueueScheduler) -> None: if self.condition_value is None: condition_value: object = self.expression.condition.execute( {k: v.get_value() for k, v in requires.items()}, resolver, queue) if isinstance(condition_value, Unknown): self.result.set_value(Unknown(self), self.location) return if not isinstance(condition_value, bool): raise RuntimeException( self, "Invalid value `%s`: the condition for a conditional expression must be a boolean expression" ) self.condition_value = condition_value # Schedule execution of appropriate subexpression subexpression: ExpressionStatement = ( self.expression.if_expression if self.condition_value else self.expression.else_expression) RawUnit( queue, resolver, subexpression.requires_emit(resolver, queue), self, ) else: value: object = ( self.expression.if_expression if self.condition_value else self.expression.else_expression).execute( {k: v.get_value() for k, v in requires.items()}, resolver, queue) self.result.set_value(value, self.location)
def requires_emit(self, resolver: Resolver, queue: QueueScheduler) -> Dict[object, ResultVariable]: # introduce temp variable to contain the eventual result of this stmt temp = ResultVariable() temp.set_provider(self) # construct waiter resumer = IsDefinedReferenceHelper(temp, self.attr, self.name) self.copy_location(resumer) # wait for the instance RawUnit(queue, resolver, self.attr.requires_emit(resolver, queue), resumer) return {self: temp}
def requires_emit_gradual(self, resolver: Resolver, queue: QueueScheduler, resultcollector) -> Dict[object, ResultVariable]: # The tricky one! # introduce temp variable to contain the eventual result of this stmt temp = ResultVariable() temp.set_provider(self) # construct waiter resumer = AttributeReferenceHelper(temp, self.instance, self.attribute, resultcollector) self.copy_location(resumer) # wait for the instance RawUnit(queue, resolver, self.instance.requires_emit(resolver, queue), resumer) return {self: temp}
def requires_emit(self, resolver: Resolver, queue: QueueScheduler) -> Dict[object, ResultVariable]: # This ResultVariable will receive the result of this expression result: ResultVariable = ResultVariable() result.set_provider(self) # Schedule execution to resume when the condition can be executed resumer: RawResumer = ConditionalExpressionResumer(self, result) self.copy_location(resumer) RawUnit(queue, resolver, self.condition.requires_emit(resolver, queue), resumer) # Wait for the result variable to be populated return {self: result}
def resume(self, requires: Dict[object, ResultVariable], resolver: Resolver, queue_scheduler: QueueScheduler) -> None: """ Instance is ready to execute, do it and see if the variable is already present """ if not self.variable: # this is a first time we are called, variable is not cached yet self.variable = self.fetch_variable(requires, resolver, queue_scheduler) if self.is_ready(): self.target.set_value(self.target_value(), self.location) else: if self.resultcollector: self.variable.listener(self.resultcollector, self.location) requires[self] = self.variable # reschedule on the variable, XU will assign it to the target variable RawUnit(queue_scheduler, resolver, requires, self)