forked from GitHub/gf-core
Editor with some commands, using PGF API, with demo shell in exper/EditShell; still buggy
This commit is contained in:
@@ -1,42 +1,71 @@
|
|||||||
module PGF.Editor where
|
module PGF.Editor where
|
||||||
|
|
||||||
|
import PGF.Data
|
||||||
|
import PGF.CId
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
|
||||||
-- API
|
-- API
|
||||||
|
|
||||||
replace :: Tree -> State -> State
|
new :: Type -> State
|
||||||
|
new (DTyp _ t _) = etree2state (uETree t)
|
||||||
|
|
||||||
|
refine :: Dict -> CId -> State -> State
|
||||||
|
refine dict f = replace (mkRefinement dict f)
|
||||||
|
|
||||||
|
replace :: ETree -> State -> State
|
||||||
replace t = doInState (const t)
|
replace t = doInState (const t)
|
||||||
|
|
||||||
delete :: State -> State
|
delete :: State -> State
|
||||||
delete s = replace (uTree (typ (tree s))) s
|
delete s = replace (uETree (typ (tree s))) s
|
||||||
|
|
||||||
new :: Type -> State
|
goNextMeta :: State -> State
|
||||||
new t = tree2state (uTree t)
|
goNextMeta = untilPosition isMetaFocus goNext
|
||||||
|
|
||||||
refineMenu :: Dict -> State -> [(Id,FType)]
|
goTop :: State -> State
|
||||||
|
goTop = navigate (const top)
|
||||||
|
|
||||||
|
refineMenu :: Dict -> State -> [(CId,FType)]
|
||||||
refineMenu dict s = maybe [] id $ M.lookup (focusType s) (refines dict)
|
refineMenu dict s = maybe [] id $ M.lookup (focusType s) (refines dict)
|
||||||
|
|
||||||
|
pgf2dict :: PGF -> Dict
|
||||||
|
pgf2dict pgf = Dict (M.fromAscList fus) refs where
|
||||||
|
fus = [(f,mkFType ty) | (f,(ty,_)) <- M.toList (funs abs)]
|
||||||
|
refs = M.fromAscList [(c, fusTo c) | (c,_) <- M.toList (cats abs)]
|
||||||
|
fusTo c = [(f,ty) | (f,ty@(_,k)) <- fus, k==c] ---- quadratic
|
||||||
|
mkFType (DTyp hyps c _) = ([k | Hyp _ (DTyp _ k _) <- hyps],c) ----dep types
|
||||||
|
abs = abstract pgf
|
||||||
|
|
||||||
----
|
etree2tree :: ETree -> Tree
|
||||||
|
etree2tree t = case atom t of
|
||||||
|
ACon f -> Fun f (map etree2tree (children t))
|
||||||
|
AMeta i -> Meta i
|
||||||
|
|
||||||
data Tree = Tree {
|
--tree2etree :: Tree -> ETree
|
||||||
|
|
||||||
|
|
||||||
|
---- TODO
|
||||||
|
-- getPosition :: Language -> Int -> ETree -> Position
|
||||||
|
|
||||||
|
---- Trees and navigation
|
||||||
|
|
||||||
|
data ETree = ETree {
|
||||||
atom :: Atom,
|
atom :: Atom,
|
||||||
typ :: Type,
|
typ :: BType,
|
||||||
children :: [Tree]
|
children :: [ETree]
|
||||||
}
|
}
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
data Atom =
|
data Atom =
|
||||||
ACon Id
|
ACon CId
|
||||||
| AMeta Int
|
| AMeta Int
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
uTree :: Type -> Tree
|
uETree :: BType -> ETree
|
||||||
uTree ty = Tree (AMeta 0) ty []
|
uETree ty = ETree (AMeta 0) ty []
|
||||||
|
|
||||||
data State = State {
|
data State = State {
|
||||||
position :: Position,
|
position :: Position,
|
||||||
tree :: Tree
|
tree :: ETree
|
||||||
}
|
}
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
@@ -61,37 +90,67 @@ right p = case p of
|
|||||||
(n:ns) -> n+1 : ns
|
(n:ns) -> n+1 : ns
|
||||||
_ -> top
|
_ -> top
|
||||||
|
|
||||||
tree2state :: Tree -> State
|
etree2state :: ETree -> State
|
||||||
tree2state = State top
|
etree2state = State top
|
||||||
|
|
||||||
doInState :: (Tree -> Tree) -> State -> State
|
doInState :: (ETree -> ETree) -> State -> State
|
||||||
doInState f s = s{tree = change (position s) (tree s)} where
|
doInState f s = s{tree = change (position s) (tree s)} where
|
||||||
change p t = case p of
|
change p t = case p of
|
||||||
[] -> f t
|
[] -> f t
|
||||||
n:ns -> let (ts1,t0:ts2) = splitAt n (children t) in
|
n:ns -> let (ts1,t0:ts2) = splitAt n (children t) in
|
||||||
t{children = ts1 ++ [change ns t0] ++ ts2}
|
t{children = ts1 ++ [change ns t0] ++ ts2}
|
||||||
|
|
||||||
subtree :: Position -> Tree -> Tree
|
subtree :: Position -> ETree -> ETree
|
||||||
subtree p t = case p of
|
subtree p t = case p of
|
||||||
[] -> t
|
[] -> t
|
||||||
n:ns -> subtree ns (children t !! n)
|
n:ns -> subtree ns (children t !! n)
|
||||||
|
|
||||||
focus :: State -> Tree
|
focus :: State -> ETree
|
||||||
focus s = subtree (position s) (tree s)
|
focus s = subtree (position s) (tree s)
|
||||||
|
|
||||||
focusType :: State -> Type
|
focusType :: State -> BType
|
||||||
focusType s = typ (focus s)
|
focusType s = typ (focus s)
|
||||||
|
|
||||||
navigate :: (Position -> Position) -> State -> State
|
navigate :: (Position -> Position) -> State -> State
|
||||||
navigate p s = s{position = p (position s)}
|
navigate p s = s{position = p (position s)}
|
||||||
|
|
||||||
|
-- p is a fix-point aspect of state change
|
||||||
|
untilFix :: Eq a => (State -> a) -> (State -> Bool) -> (State -> State) -> State -> State
|
||||||
|
untilFix p b f s =
|
||||||
|
if b s
|
||||||
|
then s
|
||||||
|
else let fs = f s in if p fs == p s
|
||||||
|
then s
|
||||||
|
else untilFix p b f fs
|
||||||
|
|
||||||
|
untilPosition :: (State -> Bool) -> (State -> State) -> State -> State
|
||||||
|
untilPosition = untilFix position
|
||||||
|
|
||||||
|
goNext :: State -> State
|
||||||
|
goNext s = case focus s of
|
||||||
|
st | not (null (children st)) -> navigate down s
|
||||||
|
_ -> navigate right (untilPosition hasYoungerSisters (navigate up) s)
|
||||||
|
where
|
||||||
|
hasYoungerSisters s = case position s of
|
||||||
|
n:ns -> length (children (subtree ns (tree s))) > n + 1
|
||||||
|
|
||||||
|
isMetaFocus :: State -> Bool
|
||||||
|
isMetaFocus s = case atom (focus s) of
|
||||||
|
AMeta _ -> True
|
||||||
|
_ -> False
|
||||||
|
|
||||||
|
|
||||||
-------
|
-------
|
||||||
|
|
||||||
type Id = String ----
|
type BType = CId ----
|
||||||
type Type = Id ----
|
type FType = ([BType],BType) ----
|
||||||
type FType = ([Id],Id) ----
|
|
||||||
|
|
||||||
data Dict = Dict {
|
data Dict = Dict {
|
||||||
funs :: M.Map Id FType,
|
functs :: M.Map CId FType,
|
||||||
refines :: M.Map Type [(Id,FType)]
|
refines :: M.Map BType [(CId,FType)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mkRefinement :: Dict -> CId -> ETree
|
||||||
|
mkRefinement dict f = ETree (ACon f) val (map uETree args) where
|
||||||
|
(args,val) = maybe undefined id $ M.lookup f (functs dict)
|
||||||
|
|
||||||
|
|||||||
39
src/exper/EditShell.hs
Normal file
39
src/exper/EditShell.hs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
import PGF.Editor
|
||||||
|
import PGF
|
||||||
|
|
||||||
|
import System (getArgs)
|
||||||
|
|
||||||
|
main = do
|
||||||
|
putStrLn "Hi, I'm the Editor!"
|
||||||
|
file:_ <- getArgs
|
||||||
|
pgf <- readPGF file
|
||||||
|
let dict = pgf2dict pgf
|
||||||
|
let st0 = new (startCat pgf)
|
||||||
|
editLoop pgf dict st0
|
||||||
|
|
||||||
|
editLoop :: PGF -> Dict -> State -> IO State
|
||||||
|
editLoop pgf dict st = do
|
||||||
|
putStrLn ("I want something of type " ++ prCId (focusType st))
|
||||||
|
c <- getLine
|
||||||
|
st' <- interpret pgf dict st c
|
||||||
|
let t = etree2tree (tree st')
|
||||||
|
putStrLn (unlines ([
|
||||||
|
"Now I have",
|
||||||
|
showTree t] ++
|
||||||
|
linearizeAll pgf t))
|
||||||
|
editLoop pgf dict st'
|
||||||
|
|
||||||
|
interpret :: PGF -> Dict -> State -> String -> IO State
|
||||||
|
interpret pgf dict st c = case words c of
|
||||||
|
"r":f:_ -> do
|
||||||
|
return $ goNextMeta (refine dict (mkCId f) st)
|
||||||
|
"m":_ -> do
|
||||||
|
putStrLn (unwords (map (prCId . fst) (refineMenu dict st)))
|
||||||
|
return st
|
||||||
|
_ -> do
|
||||||
|
putStrLn "command not understood"
|
||||||
|
return st
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user