load loads.
This commit is contained in:
parent
8a7d54a74e
commit
cce22d561b
|
@ -16,8 +16,10 @@ import Code
|
||||||
, newHeapVars
|
, newHeapVars
|
||||||
)
|
)
|
||||||
import qualified Compiler as Co
|
import qualified Compiler as Co
|
||||||
|
import Control.Exception (IOException, catch)
|
||||||
import Control.Monad.IO.Class (liftIO)
|
import Control.Monad.IO.Class (liftIO)
|
||||||
import Control.Monad.Trans.Class (lift)
|
import Control.Monad.Trans.Class (lift)
|
||||||
|
import Control.Monad.Trans.Except (runExceptT)
|
||||||
import Control.Monad.Trans.State.Lazy (get, gets, modify)
|
import Control.Monad.Trans.State.Lazy (get, gets, modify)
|
||||||
import Data.Functor.Identity (runIdentity)
|
import Data.Functor.Identity (runIdentity)
|
||||||
import Data.List (intercalate)
|
import Data.List (intercalate)
|
||||||
|
@ -26,6 +28,7 @@ import Data.Maybe (fromJust)
|
||||||
import Env (PrlgEnv(..), findAtom, findStruct, prlgError)
|
import Env (PrlgEnv(..), findAtom, findStruct, prlgError)
|
||||||
import qualified IR
|
import qualified IR
|
||||||
import Interpreter (backtrack)
|
import Interpreter (backtrack)
|
||||||
|
import Load (processInput)
|
||||||
import qualified Operators as O
|
import qualified Operators as O
|
||||||
import System.Console.Haskeline (getInputChar, outputStr, outputStrLn)
|
import System.Console.Haskeline (getInputChar, outputStr, outputStrLn)
|
||||||
|
|
||||||
|
@ -299,6 +302,25 @@ addBi :: InterpFn -> String -> Int -> PrlgEnv ()
|
||||||
addBi b n a =
|
addBi b n a =
|
||||||
addProc [[U (LocalRef $ r - 1) | r <- [1 .. a]] ++ [Invoke $ bi b]] n a
|
addProc [[U (LocalRef $ r - 1) | r <- [1 .. a]] ++ [Invoke $ bi b]] n a
|
||||||
|
|
||||||
|
{- loading code -}
|
||||||
|
load :: Bool -> InterpFn
|
||||||
|
load queryMode =
|
||||||
|
withArgs [0] $ \[arg] -> do
|
||||||
|
heap <- gets (heap . cur)
|
||||||
|
IR.StrTable _ _ itos <- gets strtable --TODO the argument here should preferably be a string, right?
|
||||||
|
case derefHeap heap arg of
|
||||||
|
BoundRef _ (Atom a) -> do
|
||||||
|
let fn = itos M.! a
|
||||||
|
src' <- liftIO $ catch (Right <$> readFile fn) (pure . Left)
|
||||||
|
case src' of
|
||||||
|
Right src -> do
|
||||||
|
res <- runExceptT $ processInput fn queryMode src
|
||||||
|
case res of
|
||||||
|
Right _ -> continue
|
||||||
|
Left e -> prlgError $ "loading from '" ++ fn ++ "': " ++ e
|
||||||
|
Left e -> prlgError $ show (e :: IOException)
|
||||||
|
_ -> prlgError "load needs an atom"
|
||||||
|
|
||||||
{- actual prlgude -}
|
{- actual prlgude -}
|
||||||
addPrelude :: PrlgEnv ()
|
addPrelude :: PrlgEnv ()
|
||||||
addPrelude = do
|
addPrelude = do
|
||||||
|
@ -330,6 +352,9 @@ addPrelude = do
|
||||||
addBi retractall "retractall" 1
|
addBi retractall "retractall" 1
|
||||||
addBi call "call" 1
|
addBi call "call" 1
|
||||||
addBi struct "struct" 3
|
addBi struct "struct" 3
|
||||||
|
{- code loading -}
|
||||||
|
addBi (load False) "load" 1
|
||||||
|
addBi (load True) "source" 1
|
||||||
{- operators -}
|
{- operators -}
|
||||||
addBi op "op" 3
|
addBi op "op" 3
|
||||||
addBi stashOps "stash_operators" 0
|
addBi stashOps "stash_operators" 0
|
||||||
|
|
|
@ -6,6 +6,7 @@ import Control.Monad.Trans.State.Lazy (StateT)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import IR (Id(..), StrTable)
|
import IR (Id(..), StrTable)
|
||||||
import Operators (Ops)
|
import Operators (Ops)
|
||||||
|
import Parser (PAST)
|
||||||
import System.Console.Haskeline (InputT)
|
import System.Console.Haskeline (InputT)
|
||||||
|
|
||||||
data Datum
|
data Datum
|
||||||
|
@ -62,6 +63,7 @@ data Interp =
|
||||||
, ops :: Ops -- currently defined operators
|
, ops :: Ops -- currently defined operators
|
||||||
, opstash :: [Ops] -- saved operators
|
, opstash :: [Ops] -- saved operators
|
||||||
, strtable :: StrTable -- string table
|
, strtable :: StrTable -- string table
|
||||||
|
, cmdq :: [(Bool, PAST)] -- isQuery, lexemes
|
||||||
}
|
}
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
|
|
140
app/Frontend.hs
140
app/Frontend.hs
|
@ -2,19 +2,24 @@ module Frontend where
|
||||||
|
|
||||||
import Builtins
|
import Builtins
|
||||||
import Code (Interp(..))
|
import Code (Interp(..))
|
||||||
import qualified Compiler as C
|
import Control.Monad (when)
|
||||||
import Control.Monad.IO.Class (liftIO)
|
import Control.Monad.IO.Class (liftIO)
|
||||||
import Control.Monad.Trans.Class (lift)
|
import Control.Monad.Trans.Class (lift)
|
||||||
import Control.Monad.Trans.Except (except, runExceptT)
|
import Control.Monad.Trans.Except (except, runExceptT)
|
||||||
import Control.Monad.Trans.State.Lazy (evalStateT, gets)
|
import Control.Monad.Trans.State.Lazy (evalStateT, gets, modify)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Data.Traversable (for)
|
import Env (PrlgEnv)
|
||||||
import Env (PrlgEnv, findAtom, findStruct, withStrTable)
|
|
||||||
import qualified IR
|
import qualified IR
|
||||||
import qualified Interpreter as I
|
import qualified Interpreter as I
|
||||||
import qualified Parser as P
|
import Load
|
||||||
|
( compile
|
||||||
|
, intern
|
||||||
|
, loadExpansion
|
||||||
|
, processInput
|
||||||
|
, queryExpansion
|
||||||
|
, shunt
|
||||||
|
)
|
||||||
import System.Console.Haskeline
|
import System.Console.Haskeline
|
||||||
import qualified Text.Megaparsec as MP
|
|
||||||
import qualified Text.Pretty.Simple as Ppr
|
import qualified Text.Pretty.Simple as Ppr
|
||||||
|
|
||||||
ppr :: Show a => a -> PrlgEnv ()
|
ppr :: Show a => a -> PrlgEnv ()
|
||||||
|
@ -29,73 +34,19 @@ ppr x =
|
||||||
}
|
}
|
||||||
x
|
x
|
||||||
|
|
||||||
left f = either (Left . f) Right
|
|
||||||
|
|
||||||
tokenize = left MP.errorBundlePretty . MP.parse P.lexPrlg "<stdin>"
|
|
||||||
|
|
||||||
parse = left MP.errorBundlePretty . MP.parse P.parsePrlg "<stdin>"
|
|
||||||
|
|
||||||
shunt ops =
|
|
||||||
left (\err -> "operator resolution: " ++ err ++ "\n") . P.shuntPrlg ops
|
|
||||||
|
|
||||||
intern prlgs = do
|
|
||||||
prlgi <- withStrTable $ \st -> IR.internPrlg st prlgs
|
|
||||||
underscore <- findAtom "_"
|
|
||||||
list <- findAtom "[]"
|
|
||||||
withStrTable $ \st ->
|
|
||||||
( st
|
|
||||||
, C.squashVars $ C.variablizePrlg underscore st $ C.desugarPrlg list prlgi)
|
|
||||||
|
|
||||||
compile prlgv = do
|
|
||||||
comma <- findAtom ","
|
|
||||||
cut <- findAtom "!"
|
|
||||||
return $ C.seqGoals (C.compileGoals comma cut prlgv)
|
|
||||||
|
|
||||||
-- the signature of this is too ugly to include here
|
-- the signature of this is too ugly to include here
|
||||||
handleError m = do
|
handleError m = do
|
||||||
res <- runExceptT m
|
res <- runExceptT m
|
||||||
case res of
|
case res of
|
||||||
Left err -> lift $ outputStr err
|
Left err -> do
|
||||||
|
lift $ outputStrLn err
|
||||||
|
modify $ \s -> s {cmdq = []}
|
||||||
_ -> pure ()
|
_ -> pure ()
|
||||||
|
|
||||||
processInput precompileHook good bad input =
|
processCmd precompileHook ast' = do
|
||||||
(True <$) . handleError $ do
|
ast <- shunt ast'
|
||||||
asts <- except $ tokenize input >>= parse
|
code <- lift $ intern ast >>= precompileHook >>= compile
|
||||||
ops <- lift $ gets ops
|
lift (I.prove code) >>= except
|
||||||
for asts $ \ast' -> do
|
|
||||||
ast <- except $ shunt ops ast'
|
|
||||||
code <- lift $ intern ast >>= precompileHook >>= compile
|
|
||||||
res <- lift (I.prove code) >>= except . left (++ "\n")
|
|
||||||
lift . lift . outputStrLn $
|
|
||||||
if res
|
|
||||||
then good
|
|
||||||
else bad
|
|
||||||
|
|
||||||
expansion noexpand expander output x = do
|
|
||||||
es <- findStruct expander 2
|
|
||||||
o <- findAtom output
|
|
||||||
comma <- findAtom ","
|
|
||||||
expand <- gets (M.member es . defs)
|
|
||||||
pure $
|
|
||||||
if expand
|
|
||||||
then IR.CallI
|
|
||||||
comma
|
|
||||||
[ IR.CallI (IR.str es) [x, IR.VarI (-1) 0]
|
|
||||||
, IR.CallI o [IR.VarI (-1) 0]
|
|
||||||
]
|
|
||||||
else noexpand o x
|
|
||||||
|
|
||||||
query =
|
|
||||||
processInput
|
|
||||||
(expansion (\_ -> id) "query_expansion" "call")
|
|
||||||
"yes."
|
|
||||||
"no proof."
|
|
||||||
|
|
||||||
assert =
|
|
||||||
processInput
|
|
||||||
(expansion (\o x -> IR.CallI o [x]) "load_expansion" "assert")
|
|
||||||
"ok."
|
|
||||||
"rejected."
|
|
||||||
|
|
||||||
interpreterStart :: PrlgEnv ()
|
interpreterStart :: PrlgEnv ()
|
||||||
interpreterStart = do
|
interpreterStart = do
|
||||||
|
@ -104,24 +55,38 @@ interpreterStart = do
|
||||||
|
|
||||||
interpreterLoop :: Bool -> PrlgEnv ()
|
interpreterLoop :: Bool -> PrlgEnv ()
|
||||||
interpreterLoop queryMode = do
|
interpreterLoop queryMode = do
|
||||||
minput <-
|
q <- gets cmdq
|
||||||
lift $
|
case q of
|
||||||
getInputLine
|
[] -> do
|
||||||
(if queryMode
|
minput <-
|
||||||
then "prlg? "
|
lift $
|
||||||
else "prlg |- ")
|
getInputLine
|
||||||
case minput of
|
(if queryMode
|
||||||
Nothing -> return ()
|
then "prlg? "
|
||||||
Just "." -> interpreterLoop (not queryMode)
|
else "prlg |- ")
|
||||||
Just input -> do
|
case minput of
|
||||||
continue <-
|
Nothing -> return ()
|
||||||
(if queryMode
|
Just "." -> interpreterLoop (not queryMode)
|
||||||
then query
|
Just input -> do
|
||||||
else assert)
|
handleError $ processInput "<user input>" queryMode input
|
||||||
input
|
interpreterLoop queryMode
|
||||||
if continue
|
((mode, ast):asts) -> do
|
||||||
then interpreterLoop queryMode
|
modify $ \s -> s {cmdq = asts}
|
||||||
else return ()
|
handleError $ do
|
||||||
|
resOK <-
|
||||||
|
processCmd
|
||||||
|
(if mode
|
||||||
|
then queryExpansion
|
||||||
|
else loadExpansion)
|
||||||
|
ast
|
||||||
|
finished <- lift $ gets (null . cmdq)
|
||||||
|
when finished . lift . lift . outputStrLn $
|
||||||
|
case (resOK, queryMode) of
|
||||||
|
(True, True) -> "yes."
|
||||||
|
(False, True) -> "no proof."
|
||||||
|
(True, False) -> "ok."
|
||||||
|
(False, False) -> "rejected."
|
||||||
|
interpreterLoop queryMode
|
||||||
|
|
||||||
interpreter :: InputT IO ()
|
interpreter :: InputT IO ()
|
||||||
interpreter =
|
interpreter =
|
||||||
|
@ -129,9 +94,10 @@ interpreter =
|
||||||
interpreterStart
|
interpreterStart
|
||||||
(Interp
|
(Interp
|
||||||
{ defs = M.empty
|
{ defs = M.empty
|
||||||
|
, cur = error "no cur"
|
||||||
|
, cho = []
|
||||||
, ops = []
|
, ops = []
|
||||||
, opstash = []
|
, opstash = []
|
||||||
, strtable = IR.emptystrtable
|
, strtable = IR.emptystrtable
|
||||||
, cur = error "no cur"
|
, cmdq = []
|
||||||
, cho = []
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -317,4 +317,8 @@ proveStep = St.get >>= go
|
||||||
nchos
|
nchos
|
||||||
}
|
}
|
||||||
{- The End -}
|
{- The End -}
|
||||||
go _ = ifail "code broken: impossible instruction combo"
|
go i =
|
||||||
|
ifail $
|
||||||
|
"code broken: impossible instruction combo hed=" ++
|
||||||
|
show (hed . cur $ i) ++
|
||||||
|
" gol=" ++ show (gol . cur $ i) ++ " stk=" ++ show (stk . cur $ i)
|
||||||
|
|
|
@ -4,6 +4,8 @@ module Parser
|
||||||
( lexPrlg
|
( lexPrlg
|
||||||
, parsePrlg
|
, parsePrlg
|
||||||
, shuntPrlg
|
, shuntPrlg
|
||||||
|
, PAST
|
||||||
|
, Lexeme
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad (void)
|
import Control.Monad (void)
|
||||||
|
|
|
@ -25,7 +25,7 @@ executable prlg
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
|
|
||||||
-- Modules included in this executable, other than Main.
|
-- Modules included in this executable, other than Main.
|
||||||
other-modules: Interpreter, Compiler, Parser, Frontend, IR, Operators, Code, Builtins, Env
|
other-modules: Interpreter, Compiler, Parser, Frontend, IR, Operators, Code, Builtins, Env, Load
|
||||||
|
|
||||||
-- LANGUAGE extensions used by modules in this package.
|
-- LANGUAGE extensions used by modules in this package.
|
||||||
-- other-extensions:
|
-- other-extensions:
|
||||||
|
|
Loading…
Reference in a new issue