def eval(self, env: Env.Values) -> V.Base: "" if self.namespace and (self.name in ["left", "right"]): pair_name = self.namespace[-1] pair_namespace = self.namespace[:-1] try: ans: V.Base = Env.resolve(env, pair_namespace, pair_name) if isinstance(ans, V.Pair): assert ans.value is not None return ans.value[0] if self.name == "left" else ans.value[1] except KeyError: pass try: ans: V.Base = Env.resolve(env, self.namespace, self.name) return ans except KeyError: raise Error.UnknownIdentifier(self) from None
def resolve(self, doc: TVDocument) -> None: # Set self.callee to the Task/Workflow being called. Use exactly once # prior to add_to_type_env() or typecheck_input() if self.callee: return if not self.callee_id.namespace: callee_doc = doc elif len(self.callee_id.namespace) == 1: for _, ns, subdoc in doc.imports: if ns == self.callee_id.namespace[0]: callee_doc = subdoc if callee_doc: assert isinstance(callee_doc, Document) if callee_doc.workflow and callee_doc.workflow.name == self.callee_id.name: self.callee = callee_doc.workflow else: for task in callee_doc.tasks: if task.name == self.callee_id.name: self.callee = task if self.callee is None: raise Err.UnknownIdentifier(self.callee_id) assert isinstance(self.callee, (Task, Workflow))
def _infer_type(self, type_env: Env.Types) -> T.Base: if self.namespace and (self.name in ["left", "right"]): # Special case for pair access, IDENT.left or IDENT.right # Pair access through non-identifier expressions goes a different # path, through the get_left and get_right terminals. # TODO: avoid having two paths by ensuring .left and .right can't # parse as Ident pair_name = self.namespace[-1] pair_namespace = self.namespace[:-1] try: ans: T.Base = Env.resolve(type_env, pair_namespace, pair_name) except KeyError: pass if isinstance(ans, T.Pair): self.ctx = Env.resolve_ctx(type_env, pair_namespace, pair_name) return ans.left_type if self.name == "left" else ans.right_type try: ans: T.Base = Env.resolve(type_env, self.namespace, self.name) except KeyError: raise Error.UnknownIdentifier(self) from None self.ctx = Env.resolve_ctx(type_env, self.namespace, self.name) return ans