This PR redefines `String.take` and variants to operate on `String.Slice`. While previously functions returning a substring of the input sometimes returned `String` and sometimes returned `Substring.Raw`, they now uniformly return `String.Slice`. This is a BREAKING change, because many functions now have a different return type. So for example, if `s` is a string and `f` is a function accepting a string, `f (s.drop 1)` will no longer compile because `s.drop 1` is a `String.Slice`. To fix this, insert a call to `copy` to restore the old behavior: `f (s.drop 1).copy`. Of course, in many cases, there will be more efficient options. For example, don't write `f <| s.drop 1 |>.copy |>.dropEnd 1 |>.copy`, write `f <| s.drop 1 |>.dropEnd 1 |>.copy` instead. Also, instead of `(s.drop 1).copy = "Hello"`, write `s.drop 1 == "Hello".toSlice` instead.
55 lines
1.9 KiB
Text
55 lines
1.9 KiB
Text
/-
|
|
Copyright (c) 2022 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Authors: Leonardo de Moura
|
|
-/
|
|
module
|
|
|
|
prelude
|
|
public import Lean.Environment
|
|
import Init.Data.String.TakeDrop
|
|
|
|
public section
|
|
|
|
namespace Lean
|
|
namespace Compiler
|
|
|
|
/-! Helper functions for creating auxiliary names used in (old) compiler passes. -/
|
|
|
|
def mkEagerLambdaLiftingName (n : Name) (idx : Nat) : Name :=
|
|
Name.mkStr n ("_elambda_" ++ toString idx)
|
|
|
|
def isEagerLambdaLiftingName : Name → Bool
|
|
| .str p s => "_elambda".isPrefixOf s || isEagerLambdaLiftingName p
|
|
| .num p _ => isEagerLambdaLiftingName p
|
|
| _ => false
|
|
|
|
/-- Return the name of new definitions in the a given declaration.
|
|
Here we consider only declarations we generate code for.
|
|
We use this definition to implement `add_and_compile`. -/
|
|
def getDeclNamesForCodeGen : Declaration → Array Name
|
|
| .defnDecl { name, .. } => #[name]
|
|
| .opaqueDecl { name, .. } => #[name]
|
|
| .axiomDecl { name, .. } => #[name] -- axiom may be tagged with `@[extern ...]`
|
|
| .mutualDefnDecl defs => defs.toArray.map (·.name)
|
|
| _ => #[]
|
|
|
|
def checkIsDefinition (env : Environment) (n : Name) : Except String Unit := do
|
|
let some info := env.findAsync? n
|
|
| throw s!"Unknown declaration `{n}`"
|
|
unless info.kind matches .defn | .opaque do
|
|
throw s!"Declaration `{n}` is not a definition"
|
|
|
|
/--
|
|
We generate auxiliary unsafe definitions for regular recursive definitions.
|
|
The auxiliary unsafe definition has a clear runtime cost execution model.
|
|
This function returns the auxiliary unsafe definition name for the given name. -/
|
|
def mkUnsafeRecName (declName : Name) : Name :=
|
|
Name.mkStr declName "_unsafe_rec"
|
|
|
|
/-- Return `some _` if the given name was created using `mkUnsafeRecName` -/
|
|
def isUnsafeRecName? : Name → Option Name
|
|
| .str n "_unsafe_rec" => some n
|
|
| _ => none
|
|
|
|
end Compiler
|