def _call_eager(self, expr: E.Apply, arguments: List[V.Base]) -> V.Base: ans_type = self.infer_type(expr) if not isinstance(ans_type, T.String): return super()._call_eager(expr, arguments) # TODO: in a command interpolation, return missing if either operand is missing ans = self.op( str(arguments[0].coerce(T.String()).value), str(arguments[1].coerce(T.String()).value) ) assert isinstance(ans, str) return V.String(ans)
def _basename(*args) -> V.String: assert len(args) in (1, 2) assert isinstance(args[0], V.String) path = args[0].value if len(args) > 1: assert isinstance(args[1], V.String) suffix = args[1].value if path.endswith(suffix): path = path[: -len(suffix)] return V.String(os.path.basename(path))
def __call__(self, expr: E.Apply, env: E.Env) -> V.Base: ans_type = self.infer_type(expr) if not isinstance(ans_type, T.String): return super().__call__(expr, env) # TODO: return missing if either operand is missing ans = self.op( str(expr.arguments[0].eval(env).coerce(T.String()).value), str(expr.arguments[1].eval(env).coerce(T.String()).value), ) assert isinstance(ans, str) return V.String(ans)
def eval(self, env: Env.Values) -> V.String: "" ans = [] for part in self.parts: if isinstance(part, Placeholder): # evaluate interpolated expression & stringify ans.append(part.eval(env).value) elif isinstance(part, str): # use python builtins to decode escape sequences ans.append(str.encode(part).decode("unicode_escape")) else: assert False # concatenate the stringified parts and trim the surrounding quotes return V.String("".join(ans)[1:-1]) # pyre-ignore
def eval(self, env: Env.Values) -> V.String: "" v = self.expr.eval(env) if isinstance(v, V.Null): if "default" in self.options: return V.String(self.options["default"]) return V.String("") if isinstance(v, V.String): return v if isinstance(v, V.Array): return V.String(self.options["sep"].join( str(item.value) for item in v.value)) if v == V.Boolean(True) and "true" in self.options: return V.String(self.options["true"]) if v == V.Boolean(False) and "false" in self.options: return V.String(self.options["false"]) return V.String(str(v))
def _call_eager(self, expr: E.Apply, arguments: List[V.Base]) -> V.Base: pfx = arguments[0].coerce(T.String()).value return V.Array( T.Array(T.String()), [V.String(pfx + s.coerce(T.String()).value) for s in arguments[1].value], )
def _sub(input: V.String, pattern: V.String, replace: V.String) -> V.String: return V.String(re.compile(pattern.value).sub(replace.value, input.value))