mirror of
https://github.com/unisonweb/unison.git
synced 2024-11-15 14:35:01 +03:00
Function for extracting the search key from a given term
This commit is contained in:
parent
78084e3ecf
commit
b4735700e5
@ -239,7 +239,8 @@ refreshPanel searchbox origin model =
|
||||
{ rootMetadata = Metadata.anonymousTerm
|
||||
, availableWidth = availableWidth - fst origin
|
||||
, metadata h = Metadata.anonymousTerm
|
||||
, overrides x = Nothing }
|
||||
, overrides x = Nothing
|
||||
, overall = model.term }
|
||||
layouts = model.layouts
|
||||
explorerRefresh = case searchbox of
|
||||
Nothing -> identity
|
||||
@ -269,7 +270,8 @@ refreshExplorer searchbox model = case model.localInfo of
|
||||
{ rootMetadata = Metadata.anonymousTerm
|
||||
, availableWidth = availableWidth
|
||||
, metadata = metadata
|
||||
, overrides x = Nothing }
|
||||
, overrides x = Nothing
|
||||
, overall = term }
|
||||
in List.map show (explorerValues model)
|
||||
|
||||
aboveMsg = "Allowed: " ++ toString localInfo.admissible ++ "\n" ++
|
||||
|
@ -23,7 +23,7 @@ type alias Metadata = {
|
||||
sort : Sort,
|
||||
names : Names,
|
||||
-- for each var, and each scope (which points to a lambda body), what are the names of that var w/in that scope
|
||||
locals : M.Dict I (List (Path,Names)),
|
||||
locals : List (Path, Symbol),
|
||||
description : Maybe R.Reference,
|
||||
annotation : R.Reference
|
||||
}
|
||||
@ -32,7 +32,7 @@ anonymousSymbol : Symbol
|
||||
anonymousSymbol = Symbol "anonymousSymbol" Prefix 9
|
||||
|
||||
anonymousTerm : Metadata
|
||||
anonymousTerm = Metadata Term [] M.empty Nothing (R.Builtin "unknown type")
|
||||
anonymousTerm = Metadata Term [] [] Nothing (R.Builtin "unknown type")
|
||||
|
||||
firstSymbol : String -> Metadata -> Symbol
|
||||
firstSymbol defaultName md = case md.names of
|
||||
@ -45,21 +45,12 @@ firstName ifEmpty md =
|
||||
then ifEmpty
|
||||
else (List.head md.names).name
|
||||
|
||||
resolveLocal : Metadata -> Path -> I -> Symbol
|
||||
resolveLocal md p v =
|
||||
let ns = localNames md p v
|
||||
in if List.isEmpty ns then { name = "v"++toString v, fixity = Prefix, precedence = 9 }
|
||||
else List.head ns
|
||||
|
||||
localNames : Metadata -> Path -> I -> Names
|
||||
localNames env p v =
|
||||
localSymbol : Metadata -> Path -> Maybe Symbol
|
||||
localSymbol env p =
|
||||
let trimmed = Path.trimToScope p
|
||||
in case M.get v env.locals of
|
||||
Nothing -> []
|
||||
Just psns -> let go (p,ns) acc = case acc of
|
||||
Nothing -> if p == trimmed then Just ns else Nothing
|
||||
Just acc -> Just acc
|
||||
in Maybe.withDefault [] (List.foldl go Nothing psns)
|
||||
in case List.filter (\(p',sym) -> p == p') env.locals of
|
||||
[] -> Nothing
|
||||
(_,s) :: _ -> Just s
|
||||
|
||||
type Fixity = InfixL | InfixR | Infix | Prefix
|
||||
|
||||
@ -126,12 +117,12 @@ decodeMetadata =
|
||||
(Decoder.maybe R.decode)
|
||||
R.decode
|
||||
|
||||
decodeLocals : Decoder (M.Dict I (List (Path,Names)))
|
||||
decodeLocals : Decoder (List (Path,Symbol))
|
||||
decodeLocals =
|
||||
Decoder.map M.fromList (Decoder.list (Decoder.tuple2 V.decode (Decoder.list (Decoder.tuple2 Path.decodePath decodeNames))))
|
||||
Decoder.list (Decoder.tuple2 Path.decodePath decodeSymbol)
|
||||
|
||||
encodeLocals : Encoder (M.Dict I (List (Path,Names)))
|
||||
encodeLocals m = Encoder.list (Encoder.tuple2 V.encode (Encoder.list (Encoder.tuple2 Path.encodePath encodeNames))) (M.toList m)
|
||||
encodeLocals : Encoder (List (Path,Symbol))
|
||||
encodeLocals = Encoder.list (Encoder.tuple2 Path.encodePath encodeSymbol)
|
||||
|
||||
encodeMetadata : Encoder Metadata
|
||||
encodeMetadata md = Encoder.tag' "Metadata"
|
||||
|
@ -1,14 +1,15 @@
|
||||
module Unison.Path where
|
||||
|
||||
import List
|
||||
import List ((::))
|
||||
import Array (Array)
|
||||
import Array as A
|
||||
import Elmz.Json.Encoder as Encoder
|
||||
import Elmz.Json.Encoder (Encoder)
|
||||
import Debug
|
||||
import Elmz.Json.Decoder as Decoder
|
||||
import Elmz.Json.Encoder (Encoder)
|
||||
import Elmz.Json.Encoder as Encoder
|
||||
import Json.Decode (Decoder)
|
||||
import Json.Decode as Decode
|
||||
import List
|
||||
import List ((::))
|
||||
import String
|
||||
|
||||
type E
|
||||
|
@ -144,6 +144,29 @@ delete p e =
|
||||
_ -> Nothing
|
||||
in if valid e p then go p e else Nothing
|
||||
|
||||
{-| If the given `Path` points to a `Var`, returns the path where that var is bound. -}
|
||||
boundAt : Path -> Term -> Maybe Path
|
||||
boundAt path e = case at path e of
|
||||
Just (Var n) ->
|
||||
let go rem e = case e of
|
||||
Lam n2 body ->
|
||||
if n == n2
|
||||
then List.reverse path
|
||||
|> List.drop (List.length path - List.length rem)
|
||||
|> List.reverse
|
||||
|> Just
|
||||
else case rem of
|
||||
hd :: rem -> case (hd,e) of
|
||||
(_, Ann e _) -> go (hd :: rem) e
|
||||
(Fn,App e _) -> go rem e
|
||||
(Arg,App _ e) -> go rem e
|
||||
(Body,Lam _ e) -> go rem e
|
||||
(Index i,Vector es) -> Array.get i es `Maybe.andThen` go rem
|
||||
_ -> Nothing
|
||||
[] -> Nothing
|
||||
in go path e
|
||||
_ -> Nothing
|
||||
|
||||
{-| Returns `True` if the path points to a valid subterm -}
|
||||
valid : Term -> Path -> Bool
|
||||
valid e p = case at p e of
|
||||
|
@ -2,6 +2,7 @@ module Unison.View (layout, L) where
|
||||
|
||||
import Array
|
||||
import Color
|
||||
import Debug
|
||||
import Elmz.Distance as Distance
|
||||
import Elmz.Layout (Layout)
|
||||
import Elmz.Layout as L
|
||||
@ -30,7 +31,30 @@ type alias Env =
|
||||
{ rootMetadata : Metadata
|
||||
, availableWidth : Int
|
||||
, metadata : R.Reference -> Metadata
|
||||
, overrides : Path -> Maybe (Layout L) }
|
||||
, overrides : Path -> Maybe (Layout L)
|
||||
, overall : Term }
|
||||
|
||||
resolveLocal : String -> Metadata -> Path -> Term -> Metadata.Symbol
|
||||
resolveLocal notfound md p e =
|
||||
let sym = Metadata.anonymousSymbol
|
||||
in (boundAt p e `Maybe.andThen` Metadata.localSymbol md) |>
|
||||
Maybe.withDefault { sym | name <- notfound }
|
||||
|
||||
key : Env -> { path : Path, term : Term } -> String
|
||||
key env cur = case cur.term of
|
||||
Blank -> "_"
|
||||
Var v -> (resolveLocal ("v"++toString v) env.rootMetadata cur.path env.overall).name
|
||||
Lit (Number n) -> toString n
|
||||
Lit (Str s) -> "\"" ++ toString s ++ "\""
|
||||
Lit (Distance d) -> toString d
|
||||
Ref r -> Metadata.firstName "anonymous" (env.metadata r)
|
||||
App f arg -> key env { path = cur.path `snoc` Fn, term = f } ++
|
||||
key env { path = cur.path `snoc` Arg, term = arg }
|
||||
Ann e t -> key env { cur | term <- e }
|
||||
Vector terms ->
|
||||
let ki i term = key env { path = cur.path `snoc` Index i, term = term }
|
||||
in "[" ++ String.join "," (Array.toList (Array.indexedMap ki terms)) ++ "]"
|
||||
Lam v body -> key env { path = cur.path `snoc` Body, term = body }
|
||||
|
||||
{-|
|
||||
|
||||
@ -129,7 +153,8 @@ impl env allowBreak ambientPrec availableWidth cur =
|
||||
Just l -> l
|
||||
Nothing -> case cur.term of
|
||||
Embed l -> l
|
||||
Var n -> codeText (Metadata.resolveLocal env.rootMetadata cur.path n).name |> L.embed (tag cur.path)
|
||||
Var n -> codeText (resolveLocal ("v"++toString n) env.rootMetadata cur.path env.overall).name
|
||||
|> L.embed (tag cur.path)
|
||||
Ref h -> codeText (Metadata.firstName (R.toString h) (env.metadata h)) |> L.embed (tag cur.path)
|
||||
Blank -> Styles.blank |> L.embed (tag cur.path)
|
||||
Lit (Number n) -> Styles.numericLiteral (toString n) |> L.embed (tag cur.path)
|
||||
@ -137,7 +162,7 @@ impl env allowBreak ambientPrec availableWidth cur =
|
||||
_ -> case builtins env allowBreak ambientPrec availableWidth cur of
|
||||
Just l -> l
|
||||
Nothing -> let space' = L.embed (tag cur.path) space in
|
||||
case break env.rootMetadata env.metadata cur.path cur.term of
|
||||
case break env env.rootMetadata env.metadata cur.path cur.term of
|
||||
Prefix f args ->
|
||||
let f' = impl env False 9 availableWidth f
|
||||
lines = f' :: List.map (impl env False 10 0) args
|
||||
@ -189,12 +214,13 @@ type Break a
|
||||
| Bracketed (List a) -- `Bracketed [x,y,z] == [x,y,z]`
|
||||
| Lambda (List a) a -- `Lambda [x,y,z] e == x -> y -> z -> e`
|
||||
|
||||
break : Metadata
|
||||
break : Env
|
||||
-> Metadata
|
||||
-> (R.Reference -> Metadata)
|
||||
-> Path
|
||||
-> Term
|
||||
-> Break { path : Path, term : Term }
|
||||
break rootMd md path expr =
|
||||
break env rootMd md path expr =
|
||||
let prefix f acc path = case f of
|
||||
App f arg -> prefix f ({ path = path `snoc` Arg, term = arg } :: acc) (path `snoc` Fn)
|
||||
_ -> Prefix { path = path, term = f } acc
|
||||
@ -225,14 +251,14 @@ break rootMd md path expr =
|
||||
App (App op l) r ->
|
||||
let sym = case op of
|
||||
Ref h -> Metadata.firstSymbol (R.toString h) (md h)
|
||||
Var v -> Metadata.resolveLocal rootMd path v
|
||||
Var v -> resolveLocal ("v"++toString v) rootMd path env.overall
|
||||
_ -> Metadata.anonymousSymbol
|
||||
in case sym.fixity of
|
||||
Metadata.Prefix -> prefix (App (App op l) r) [] path -- not an operator chain, fall back
|
||||
Metadata.InfixL -> opsL op sym.precedence (App (App op l) r) [] path -- left associated operator chain
|
||||
Metadata.InfixR -> opsR op sym.precedence (App (App op l) r) path
|
||||
Lam v body -> case body of -- audit this
|
||||
Lam _ _ -> let trim p = { p | path <- path } in case break rootMd md (path `snoc` Body) body of
|
||||
Lam _ _ -> let trim p = { p | path <- path } in case break env rootMd md (path `snoc` Body) body of
|
||||
Lambda args body2 -> Lambda ({ path = path, term = Var v } :: args) body2
|
||||
_ -> Lambda [{path = path, term = Var v }] { path = path `snoc` Body, term = body }
|
||||
_ -> Lambda [{path = path, term = Var v }] { path = path `snoc` Body, term = body }
|
||||
|
Loading…
Reference in New Issue
Block a user