get lensy and classy
This commit is contained in:
parent
3eb6125609
commit
81df52f656
141
app/Builtins.hs
141
app/Builtins.hs
|
@ -2,24 +2,22 @@ module Builtins where
|
||||||
|
|
||||||
import Code
|
import Code
|
||||||
( Builtin(..)
|
( Builtin(..)
|
||||||
, Cho(..)
|
|
||||||
, Code
|
, Code
|
||||||
, Datum(..)
|
, Datum(..)
|
||||||
, Dereferenced(..)
|
, Dereferenced(..)
|
||||||
, Instr(..)
|
, Instr(..)
|
||||||
, Interp(..)
|
|
||||||
, InterpFn
|
, InterpFn
|
||||||
, InterpFn
|
, InterpFn
|
||||||
, derefHeap
|
, derefHeap
|
||||||
, heapStruct
|
, heapStruct
|
||||||
, newHeapVars
|
, newHeapVars
|
||||||
)
|
)
|
||||||
|
import CodeLens
|
||||||
import qualified Compiler as Co
|
import qualified Compiler as Co
|
||||||
import Control.Exception (IOException, catch)
|
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.Except (runExceptT)
|
||||||
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)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
@ -27,6 +25,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 Lens.Family2.State
|
||||||
import Load (processInput)
|
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)
|
||||||
|
@ -51,17 +50,17 @@ showTerm itos heap = runIdentity . heapStruct atom struct hrec heap
|
||||||
|
|
||||||
printLocals :: InterpFn
|
printLocals :: InterpFn
|
||||||
printLocals = do
|
printLocals = do
|
||||||
scope <- gets (gvar . cur)
|
scope <- use (cur . gvar)
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
IR.StrTable _ _ itos <- gets strtable
|
IR.StrTable _ _ itos <- use strtable
|
||||||
flip traverse (M.assocs scope) $ \(local, ref) ->
|
flip traverse (M.assocs scope) $ \(local, ref) ->
|
||||||
lift . outputStrLn $
|
lift . outputStrLn $ "_Local" ++ show local ++ " = " ++
|
||||||
"_Local" ++ show local ++ " = " ++ showTerm itos heap ref
|
showTerm itos heap ref
|
||||||
continue
|
continue
|
||||||
|
|
||||||
promptRetry :: InterpFn
|
promptRetry :: InterpFn
|
||||||
promptRetry = do
|
promptRetry = do
|
||||||
last <- gets (null . cho)
|
last <- cho `uses` null
|
||||||
if last
|
if last
|
||||||
then continue
|
then continue
|
||||||
else promptRetry'
|
else promptRetry'
|
||||||
|
@ -75,7 +74,7 @@ promptRetry' = do
|
||||||
|
|
||||||
withArgs :: [Int] -> ([Int] -> InterpFn) -> InterpFn
|
withArgs :: [Int] -> ([Int] -> InterpFn) -> InterpFn
|
||||||
withArgs as f = do
|
withArgs as f = do
|
||||||
scope <- gets (hvar . cur)
|
scope <- use (cur . hvar)
|
||||||
if all (`M.member` scope) as
|
if all (`M.member` scope) as
|
||||||
then f $ map (scope M.!) as
|
then f $ map (scope M.!) as
|
||||||
else prlgError "arguments not bound"
|
else prlgError "arguments not bound"
|
||||||
|
@ -83,8 +82,8 @@ withArgs as f = do
|
||||||
write' :: InterpFn -> InterpFn
|
write' :: InterpFn -> InterpFn
|
||||||
write' c =
|
write' c =
|
||||||
withArgs [0] $ \[arg] -> do
|
withArgs [0] $ \[arg] -> do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
IR.StrTable _ _ itos <- gets strtable
|
IR.StrTable _ _ itos <- use strtable
|
||||||
lift . outputStr $ showTerm itos heap arg
|
lift . outputStr $ showTerm itos heap arg
|
||||||
c --this now allows error fallthrough but we might like EitherT
|
c --this now allows error fallthrough but we might like EitherT
|
||||||
|
|
||||||
|
@ -101,19 +100,19 @@ writeln = write' nl
|
||||||
assertFact :: (Code -> IR.Id -> PrlgEnv ()) -> InterpFn
|
assertFact :: (Code -> IR.Id -> PrlgEnv ()) -> InterpFn
|
||||||
assertFact addClause =
|
assertFact addClause =
|
||||||
withArgs [0] $ \[arg] -> do
|
withArgs [0] $ \[arg] -> do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
case Co.compileGoal . Co.squashVars <$>
|
case Co.compileGoal . Co.squashVars <$>
|
||||||
Co.heapStructPrlgInt Nothing heap arg of
|
Co.heapStructPrlgInt Nothing heap arg of
|
||||||
Just (U (Struct s):head) -> do
|
Just (U (Struct s):head) -> do
|
||||||
addClause (head ++ [NoGoal]) s
|
addClause (head ++ [Done]) s
|
||||||
continue
|
continue
|
||||||
_ -> prlgError "assert fact failure"
|
_ -> prlgError "assert fact failure"
|
||||||
|
|
||||||
assertRule :: (Code -> IR.Id -> PrlgEnv ()) -> InterpFn
|
assertRule :: (Code -> IR.Id -> PrlgEnv ()) -> InterpFn
|
||||||
assertRule addClause =
|
assertRule addClause =
|
||||||
withArgs [0, 1] $ \args -> do
|
withArgs [0, 1] $ \args -> do
|
||||||
scope <- gets (hvar . cur)
|
scope <- use (cur . hvar)
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
comma <- findAtom ","
|
comma <- findAtom ","
|
||||||
cut <- findAtom "!"
|
cut <- findAtom "!"
|
||||||
case Co.squashVars . IR.CallI 0 <$>
|
case Co.squashVars . IR.CallI 0 <$>
|
||||||
|
@ -128,7 +127,7 @@ assertRule addClause =
|
||||||
retractall :: InterpFn
|
retractall :: InterpFn
|
||||||
retractall =
|
retractall =
|
||||||
withArgs [0] $ \[arg] -> do
|
withArgs [0] $ \[arg] -> do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
case derefHeap heap arg of
|
case derefHeap heap arg of
|
||||||
BoundRef _ (Atom a) ->
|
BoundRef _ (Atom a) ->
|
||||||
dropProcedure (IR.Id {IR.arity = 0, IR.str = a}) >> continue
|
dropProcedure (IR.Id {IR.arity = 0, IR.str = a}) >> continue
|
||||||
|
@ -138,21 +137,15 @@ retractall =
|
||||||
exec' :: (Code -> Code) -> InterpFn
|
exec' :: (Code -> Code) -> InterpFn
|
||||||
exec' fgol =
|
exec' fgol =
|
||||||
withArgs [0] $ \[arg] -> do
|
withArgs [0] $ \[arg] -> do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
case Co.squashVars <$> Co.heapStructPrlgInt Nothing heap arg of
|
case Co.squashVars <$> Co.heapStructPrlgInt Nothing heap arg of
|
||||||
Just gs -> do
|
Just gs -> do
|
||||||
cur <- gets cur
|
|
||||||
comma <- findAtom ","
|
comma <- findAtom ","
|
||||||
cut <- findAtom "!"
|
cut <- findAtom "!"
|
||||||
modify $ \s ->
|
zoom cur $ do
|
||||||
s
|
hvar .= M.empty
|
||||||
{ cur =
|
hed .= Co.seqGoals (Co.compileGoals comma cut gs)
|
||||||
cur
|
gol %= fgol
|
||||||
{ hvar = M.empty
|
|
||||||
, hed = Co.seqGoals (Co.compileGoals comma cut gs)
|
|
||||||
, gol = fgol (gol cur)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
_ -> prlgError "bad goal"
|
_ -> prlgError "bad goal"
|
||||||
|
|
||||||
|
@ -160,13 +153,13 @@ call :: InterpFn
|
||||||
call = exec' id
|
call = exec' id
|
||||||
|
|
||||||
exec :: InterpFn
|
exec :: InterpFn
|
||||||
exec = exec' (const [LastCall])
|
exec = exec' (const [Done])
|
||||||
|
|
||||||
{- struct assembly/disassembly -}
|
{- struct assembly/disassembly -}
|
||||||
struct :: InterpFn
|
struct :: InterpFn
|
||||||
struct = do
|
struct = do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
scope <- gets (hvar . cur)
|
scope <- use (cur . hvar)
|
||||||
case derefHeap heap <$> scope M.!? 0 of
|
case derefHeap heap <$> scope M.!? 0 of
|
||||||
Just (BoundRef addr (Struct IR.Id {IR.arity = arity, IR.str = str})) ->
|
Just (BoundRef addr (Struct IR.Id {IR.arity = arity, IR.str = str})) ->
|
||||||
structUnify arity str
|
structUnify arity str
|
||||||
|
@ -192,8 +185,8 @@ heapListLength listAtom heap ref = go 0 ref ref (id, fromJust . step)
|
||||||
|
|
||||||
structAssemble :: InterpFn
|
structAssemble :: InterpFn
|
||||||
structAssemble = do
|
structAssemble = do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
scope <- gets (hvar . cur)
|
scope <- use (cur . hvar)
|
||||||
case derefHeap heap <$> scope M.!? 1 of
|
case derefHeap heap <$> scope M.!? 1 of
|
||||||
Just (BoundRef addr (Atom str)) -> do
|
Just (BoundRef addr (Atom str)) -> do
|
||||||
listAtom <- findAtom "[]"
|
listAtom <- findAtom "[]"
|
||||||
|
@ -203,9 +196,8 @@ structAssemble = do
|
||||||
_ -> prlgError "struct id unknown"
|
_ -> prlgError "struct id unknown"
|
||||||
|
|
||||||
structUnify arity str = do
|
structUnify arity str = do
|
||||||
cur <- gets cur
|
h <- use (cur . heap)
|
||||||
let h = heap cur
|
scope <- use (cur . hvar)
|
||||||
scope = hvar cur
|
|
||||||
listAtom <- findAtom "[]"
|
listAtom <- findAtom "[]"
|
||||||
let hcode = map U $ maybe VoidRef HeapRef . (scope M.!?) <$> [0 .. 2]
|
let hcode = map U $ maybe VoidRef HeapRef . (scope M.!?) <$> [0 .. 2]
|
||||||
(h', pvars) = newHeapVars arity h
|
(h', pvars) = newHeapVars arity h
|
||||||
|
@ -217,15 +209,17 @@ structUnify arity str = do
|
||||||
pvars ++
|
pvars ++
|
||||||
[Atom listAtom]
|
[Atom listAtom]
|
||||||
gcode = map U $ structData ++ [Atom str] ++ paramsData
|
gcode = map U $ structData ++ [Atom str] ++ paramsData
|
||||||
modify $ \s ->
|
zoom cur $ do
|
||||||
s {cur = cur {heap = h', gol = gcode ++ gol cur, hed = hcode ++ hed cur}}
|
heap .= h'
|
||||||
|
gol %= (gcode ++)
|
||||||
|
hed %= (hcode ++)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
{- terms -}
|
{- terms -}
|
||||||
var :: InterpFn
|
var :: InterpFn
|
||||||
var = do
|
var = do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
scope <- gets (hvar . cur)
|
scope <- use (cur . hvar)
|
||||||
case derefHeap heap <$> scope M.!? 0 of
|
case derefHeap heap <$> scope M.!? 0 of
|
||||||
Nothing -> continue
|
Nothing -> continue
|
||||||
Just (FreeRef _) -> continue
|
Just (FreeRef _) -> continue
|
||||||
|
@ -233,8 +227,8 @@ var = do
|
||||||
|
|
||||||
sameTerm :: InterpFn
|
sameTerm :: InterpFn
|
||||||
sameTerm = do
|
sameTerm = do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
scope <- gets (hvar . cur)
|
scope <- use (cur . hvar)
|
||||||
case map (fmap (derefHeap heap) . (scope M.!?)) [0, 1] of
|
case map (fmap (derefHeap heap) . (scope M.!?)) [0, 1] of
|
||||||
[Just a, Just b]
|
[Just a, Just b]
|
||||||
| a == b -> continue
|
| a == b -> continue
|
||||||
|
@ -243,8 +237,8 @@ sameTerm = do
|
||||||
currentPredicate :: InterpFn
|
currentPredicate :: InterpFn
|
||||||
currentPredicate =
|
currentPredicate =
|
||||||
withArgs [0] $ \[arg] -> do
|
withArgs [0] $ \[arg] -> do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
ds <- gets defs
|
ds <- use defs
|
||||||
case derefHeap heap arg of
|
case derefHeap heap arg of
|
||||||
BoundRef _ (Struct s) ->
|
BoundRef _ (Struct s) ->
|
||||||
if s `M.member` ds
|
if s `M.member` ds
|
||||||
|
@ -256,76 +250,73 @@ currentPredicate =
|
||||||
op :: InterpFn
|
op :: InterpFn
|
||||||
op =
|
op =
|
||||||
withArgs [0, 1, 2] $ \args -> do
|
withArgs [0, 1, 2] $ \args -> do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
IR.StrTable _ _ itos <- gets strtable
|
IR.StrTable _ _ itos <- use strtable
|
||||||
case map (derefHeap heap) args of
|
case map (derefHeap heap) args of
|
||||||
[BoundRef _ (Number prio), BoundRef _ (Atom fixityAtom), BoundRef _ (Atom opatom)]
|
[BoundRef _ (Number prio), BoundRef _ (Atom fixityAtom), BoundRef _ (Atom opatom)]
|
||||||
| Just op <-
|
| Just op <-
|
||||||
(,) <$> itos M.!? opatom <*>
|
(,) <$> itos M.!? opatom <*>
|
||||||
(O.Op prio <$> ((itos M.!? fixityAtom) >>= O.fixity)) -> do
|
(O.Op prio <$> ((itos M.!? fixityAtom) >>= O.fixity)) -> do
|
||||||
modify $ \s -> s {ops = op : ops s}
|
ops %= (op :)
|
||||||
continue
|
continue
|
||||||
_ -> prlgError "bad op spec"
|
_ -> prlgError "bad op spec"
|
||||||
|
|
||||||
deop :: InterpFn
|
deop :: InterpFn
|
||||||
deop =
|
deop =
|
||||||
withArgs [0] $ \[arg] -> do
|
withArgs [0] $ \[arg] -> do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
IR.StrTable _ _ itos <- gets strtable
|
IR.StrTable _ _ itos <- use strtable
|
||||||
case derefHeap heap arg of
|
case derefHeap heap arg of
|
||||||
BoundRef _ (Atom opatom)
|
BoundRef _ (Atom opatom)
|
||||||
| Just op <- itos M.!? opatom -> do
|
| Just op <- itos M.!? opatom -> do
|
||||||
modify $ \s -> s {ops = filter ((/= op) . fst) (ops s)}
|
ops %= filter ((/= op) . fst)
|
||||||
continue
|
continue
|
||||||
_ -> prlgError "bad op spec"
|
_ -> prlgError "bad op spec"
|
||||||
|
|
||||||
stashOps :: InterpFn
|
stashOps :: InterpFn
|
||||||
stashOps = do
|
stashOps = do
|
||||||
currentOps <- gets ops
|
currentOps <- use ops
|
||||||
modify $ \s -> s {opstash = currentOps : opstash s}
|
opstash %= (currentOps :)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
popOps :: InterpFn
|
popOps :: InterpFn
|
||||||
popOps = do
|
popOps = do
|
||||||
currentOps <- gets opstash
|
currentOps <- use opstash
|
||||||
case currentOps of
|
case currentOps of
|
||||||
[] -> prlgError "no ops stashed"
|
[] -> prlgError "no ops stashed"
|
||||||
(ops':opss) -> do
|
(ops':opss) -> do
|
||||||
modify $ \s -> s {ops = ops', opstash = opss}
|
ops .= ops'
|
||||||
|
opstash .= opss
|
||||||
continue
|
continue
|
||||||
|
|
||||||
{- expansion environment -}
|
{- expansion environment -}
|
||||||
stashExpansions :: InterpFn
|
stashExpansions :: InterpFn
|
||||||
stashExpansions = do
|
stashExpansions = do
|
||||||
ds <- gets defs
|
ds <- use defs
|
||||||
les <- findStruct "load_expansion" 2
|
les <- findStruct "load_expansion" 2
|
||||||
qes <- findStruct "query_expansion" 2
|
qes <- findStruct "query_expansion" 2
|
||||||
let [le, qe] = map (ds M.!?) [les, qes]
|
let [le, qe] = map (ds M.!?) [les, qes]
|
||||||
modify $ \s -> s {macrostash = (le, qe) : macrostash s}
|
macrostash %= ((le, qe) :)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
popExpansions :: InterpFn
|
popExpansions :: InterpFn
|
||||||
popExpansions = do
|
popExpansions = do
|
||||||
currentMacros <- gets macrostash
|
currentMacros <- use macrostash
|
||||||
les <- findStruct "load_expansion" 2
|
les <- findStruct "load_expansion" 2
|
||||||
qes <- findStruct "query_expansion" 2
|
qes <- findStruct "query_expansion" 2
|
||||||
case currentMacros of
|
case currentMacros of
|
||||||
[] -> prlgError "no expansions stashed"
|
[] -> prlgError "no expansions stashed"
|
||||||
((le, qe):stash') -> do
|
((le, qe):stash') -> do
|
||||||
modify $ \s ->
|
defs %= M.alter (const le) les . M.alter (const qe) qes
|
||||||
s
|
macrostash .= stash'
|
||||||
{ defs = M.alter (const le) les $ M.alter (const qe) qes $ defs s
|
|
||||||
, macrostash = stash'
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
{- adding the builtins -}
|
{- adding the builtins -}
|
||||||
addOp :: (String, O.Op) -> PrlgEnv ()
|
addOp :: (String, O.Op) -> PrlgEnv ()
|
||||||
addOp op = modify $ \s -> s {ops = op : ops s}
|
addOp op = ops %= (op :)
|
||||||
|
|
||||||
modDef :: ([Code] -> Maybe [Code]) -> IR.Id -> PrlgEnv ()
|
modDef :: ([Code] -> Maybe [Code]) -> IR.Id -> PrlgEnv ()
|
||||||
modDef fn struct =
|
modDef fn struct = defs %= M.alter (maybe (fn []) fn) struct
|
||||||
modify $ \s -> s {defs = M.alter (maybe (fn []) fn) struct $ defs s}
|
|
||||||
|
|
||||||
addClauseA :: Code -> IR.Id -> PrlgEnv ()
|
addClauseA :: Code -> IR.Id -> PrlgEnv ()
|
||||||
addClauseA code = modDef $ Just . (code :)
|
addClauseA code = modDef $ Just . (code :)
|
||||||
|
@ -350,8 +341,8 @@ addBi b n a =
|
||||||
load :: Bool -> InterpFn
|
load :: Bool -> InterpFn
|
||||||
load queryMode =
|
load queryMode =
|
||||||
withArgs [0] $ \[arg] -> do
|
withArgs [0] $ \[arg] -> do
|
||||||
heap <- gets (heap . cur)
|
heap <- use (cur . heap)
|
||||||
IR.StrTable _ _ itos <- gets strtable --TODO the argument here should preferably be a string, right?
|
IR.StrTable _ _ itos <- use strtable --TODO the argument here should preferably be a string, right?
|
||||||
case derefHeap heap arg of
|
case derefHeap heap arg of
|
||||||
BoundRef _ (Atom a) -> do
|
BoundRef _ (Atom a) -> do
|
||||||
let fn = itos M.! a
|
let fn = itos M.! a
|
||||||
|
@ -373,7 +364,7 @@ addPrelude = do
|
||||||
addBi (pure Nothing) "true" 0
|
addBi (pure Nothing) "true" 0
|
||||||
addBi backtrack "fail" 0
|
addBi backtrack "fail" 0
|
||||||
addOp $ O.xfx "=" 700
|
addOp $ O.xfx "=" 700
|
||||||
addProc [[U (LocalRef 0), U (LocalRef 0), NoGoal]] "=" 2
|
addProc [[U (LocalRef 0), U (LocalRef 0), Done]] "=" 2
|
||||||
{- clauses -}
|
{- clauses -}
|
||||||
addOp $ O.xfy "," 1000
|
addOp $ O.xfy "," 1000
|
||||||
addOp $ O.xfx ":-" 1200
|
addOp $ O.xfx ":-" 1200
|
||||||
|
@ -417,19 +408,17 @@ addPrelude = do
|
||||||
addProc
|
addProc
|
||||||
[ [ U (LocalRef 0)
|
[ [ U (LocalRef 0)
|
||||||
, U (LocalRef 1)
|
, U (LocalRef 1)
|
||||||
, Goal -- current_predicate(expand_something(_,_)),
|
, U (Struct cp) -- current_predicate(expand_something(_,_)),
|
||||||
, U (Struct cp)
|
|
||||||
, U (Struct s)
|
, U (Struct s)
|
||||||
, U VoidRef
|
, U VoidRef
|
||||||
, U VoidRef
|
, U VoidRef
|
||||||
, Call -- no cut!
|
, U (Struct s) -- expand_something(Arg1, Arg2).
|
||||||
, Goal -- expand_something(Arg1, Arg2).
|
|
||||||
, U (Struct s)
|
|
||||||
, U (LocalRef 0)
|
, U (LocalRef 0)
|
||||||
, U (LocalRef 1)
|
, U (LocalRef 1)
|
||||||
, LastCall
|
, Cut -- TODO check that the cut works here; this was the whole reason why we migrated off vienna
|
||||||
|
, Done
|
||||||
]
|
]
|
||||||
, [U (LocalRef 0), U (LocalRef 0), NoGoal]
|
, [U (LocalRef 0), U (LocalRef 0), Done]
|
||||||
]
|
]
|
||||||
("expand_" ++ q)
|
("expand_" ++ q)
|
||||||
2
|
2
|
||||||
|
@ -444,4 +433,4 @@ addPrelude = do
|
||||||
addBi writeln "writeln" 1
|
addBi writeln "writeln" 1
|
||||||
addBi nl "nl" 0
|
addBi nl "nl" 0
|
||||||
{- debug -}
|
{- debug -}
|
||||||
addBi (get >>= liftIO . print >> pure Nothing) "interpreter_trace" 0
|
addBi (use id >>= liftIO . print >> pure Nothing) "interpreter_trace" 0
|
||||||
|
|
74
app/Code.hs
74
app/Code.hs
|
@ -19,13 +19,11 @@ data Datum
|
||||||
deriving (Show, Eq, Ord)
|
deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
data Instr
|
data Instr
|
||||||
= U Datum -- something unifiable
|
= U Datum -- unify/resolve something
|
||||||
| NoGoal -- trivial goal (directly after head)
|
| Invoke Builtin -- give control to a builtin (invoked from head)
|
||||||
| Invoke Builtin -- also directly after head
|
| Done -- all done, can return
|
||||||
| Goal -- a new goal (set head)
|
| Cut -- remove choicepoints of the current goal
|
||||||
| Call -- all seems okay, call the head's hoal
|
| Choices [[Code]] -- split off several possibilities (push choicepoints)
|
||||||
| LastCall -- tail call the head's goal
|
|
||||||
| Cut -- remove all alternative clauses of the current goal
|
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
type Code = [Instr]
|
type Code = [Instr]
|
||||||
|
@ -45,30 +43,32 @@ emptyScope = M.empty
|
||||||
|
|
||||||
data Cho =
|
data Cho =
|
||||||
Cho
|
Cho
|
||||||
{ hed :: Code -- head pointer
|
{ _hed :: Code -- head pointer
|
||||||
, hvar :: Scope -- variables unified in head (so far)
|
, _hvar :: Scope -- variables unified in head (so far)
|
||||||
, gol :: Code -- goal pointer
|
, _gol :: Code -- goal pointer
|
||||||
, gvar :: Scope -- variables unified in the goal
|
, _gvar :: Scope -- variables unified in the goal
|
||||||
, heap :: Heap -- a snapshot of the heap (there's no trail; we rely on CoW copies in other choicepoints)
|
, _unis :: Int -- items left to unify
|
||||||
, stk :: [(Code, Scope, [Cho])] -- remaining goals together with their vars and cuts
|
, _retcut :: Bool -- cut after this goal succeeds
|
||||||
, cut :: [Cho] -- snapshot of choicepoints before entering
|
, _heap :: Heap -- a snapshot of the heap (there's no trail; we rely on CoW copies in other choicepoints)
|
||||||
|
, _stk :: [(Code, Scope, [Cho], Bool)] -- remaining goals together with their vars, cuts, and ret-cut flag
|
||||||
|
, _cut :: [Cho] -- snapshot of choicepoints before entering
|
||||||
}
|
}
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
data Interp =
|
data Interp =
|
||||||
Interp
|
Interp
|
||||||
{ defs :: Defs -- global definitions for lookup
|
{ _defs :: Defs -- global definitions for lookup
|
||||||
, cur :: Cho -- the choice that is being evaluated right now
|
, _cur :: Cho -- the choice that is being evaluated right now
|
||||||
, cho :: [Cho] -- remaining choice points
|
, _cho :: [Cho] -- remaining choice points
|
||||||
, ops :: Ops -- currently defined operators
|
, _ops :: Ops -- currently defined operators
|
||||||
, opstash :: [Ops] -- saved operators
|
, _opstash :: [Ops] -- saved operators
|
||||||
, macrostash :: [(Maybe [Code], Maybe [Code])] -- saved expansion defs (load, query)
|
, _macrostash :: [(Maybe [Code], Maybe [Code])] -- saved expansion defs (load, query)
|
||||||
, strtable :: StrTable -- string table
|
, _strtable :: StrTable -- string table
|
||||||
, cmdq :: [(Bool, PAST)] -- isQuery, lexemes
|
, _cmdq :: [(Bool, PAST)] -- isQuery, lexemes
|
||||||
}
|
}
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
type PrlgEnv a = StateT Interp (InputT IO) a
|
type PrlgEnv = StateT Interp (InputT IO)
|
||||||
|
|
||||||
type InterpFn = PrlgEnv (Maybe (Either String Bool))
|
type InterpFn = PrlgEnv (Maybe (Either String Bool))
|
||||||
|
|
||||||
|
@ -114,34 +114,6 @@ withNewHeapStruct addr s@(Struct Id {arity = arity}) heap cont =
|
||||||
m'' = M.insert addr (HeapRef $ head addrs) . M.insert (head addrs) s $ m'
|
m'' = M.insert addr (HeapRef $ head addrs) . M.insert (head addrs) s $ m'
|
||||||
in cont (map HeapRef $ tail addrs) (Heap nxt' m'')
|
in cont (map HeapRef $ tail addrs) (Heap nxt' m'')
|
||||||
|
|
||||||
-- TODO are we actually going to use this?
|
|
||||||
codeStruct ::
|
|
||||||
Monad m
|
|
||||||
=> (Datum -> m a)
|
|
||||||
-> (Datum -> [a] -> m a)
|
|
||||||
-> (Datum -> m (Either Int a))
|
|
||||||
-> (Datum -> Int -> m a)
|
|
||||||
-> m a
|
|
||||||
-> Heap
|
|
||||||
-> Code
|
|
||||||
-> m (Code, a)
|
|
||||||
codeStruct atom struct local rec end heap = go
|
|
||||||
where
|
|
||||||
go [] = ([], ) <$> end
|
|
||||||
go (U lr@(LocalRef _):cs) = do
|
|
||||||
x <- local lr
|
|
||||||
case x of
|
|
||||||
Left ref -> (cs, ) <$> heapStruct atom struct rec heap ref
|
|
||||||
Right a -> pure (cs, a)
|
|
||||||
go (U s@(Struct (IR.Id _ arity)):cs) = eat arity cs >>= traverse (struct s)
|
|
||||||
go (U x:cs) = (cs, ) <$> atom x
|
|
||||||
go cs = (cs, ) <$> end
|
|
||||||
eat n cs
|
|
||||||
| n <= 0 = pure (cs, [])
|
|
||||||
| otherwise = do
|
|
||||||
(rest, a) <- go cs
|
|
||||||
fmap (a :) <$> eat (n - 1) rest
|
|
||||||
|
|
||||||
heapStruct ::
|
heapStruct ::
|
||||||
Monad m
|
Monad m
|
||||||
=> (Datum -> m a)
|
=> (Datum -> m a)
|
||||||
|
|
10
app/CodeLens.hs
Normal file
10
app/CodeLens.hs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
|
||||||
|
module CodeLens where
|
||||||
|
|
||||||
|
import Code
|
||||||
|
import Lens.Family2.TH
|
||||||
|
|
||||||
|
$(makeLenses ''Cho)
|
||||||
|
|
||||||
|
$(makeLenses ''Interp)
|
|
@ -74,12 +74,7 @@ compileArg (VarI x _) = [U (LocalRef x)]
|
||||||
compileArg (VoidI) = [U VoidRef]
|
compileArg (VoidI) = [U VoidRef]
|
||||||
|
|
||||||
seqGoals :: [Code] -> Code
|
seqGoals :: [Code] -> Code
|
||||||
seqGoals [] = [NoGoal]
|
seqGoals = (++ [Done]) . concat
|
||||||
seqGoals [[Cut]] = [Cut, NoGoal]
|
|
||||||
seqGoals [x] = [Goal] ++ x ++ [LastCall]
|
|
||||||
seqGoals [x, [Cut]] = [Goal] ++ x ++ [LastCall, Cut]
|
|
||||||
seqGoals ([Cut]:xs) = [Cut] ++ seqGoals xs
|
|
||||||
seqGoals (x:xs) = [Goal] ++ x ++ [Call] ++ seqGoals xs
|
|
||||||
|
|
||||||
heapStructPrlgInt :: Monad m => m PrlgInt -> Heap -> Int -> m PrlgInt
|
heapStructPrlgInt :: Monad m => m PrlgInt -> Heap -> Int -> m PrlgInt
|
||||||
heapStructPrlgInt heaperr heap ref = heapStruct atom struct hrec heap ref
|
heapStructPrlgInt heaperr heap ref = heapStruct atom struct hrec heap ref
|
||||||
|
|
10
app/Env.hs
10
app/Env.hs
|
@ -1,14 +1,14 @@
|
||||||
module Env where
|
module Env where
|
||||||
|
|
||||||
import Code (Interp(..), InterpFn, PrlgEnv)
|
import Code (InterpFn, PrlgEnv)
|
||||||
import Control.Monad.Trans.State.Lazy (gets, modify)
|
import CodeLens
|
||||||
import qualified IR
|
import qualified IR
|
||||||
|
import Lens.Family2.State
|
||||||
|
|
||||||
withStrTable :: (IR.StrTable -> (IR.StrTable, a)) -> Env.PrlgEnv a
|
withStrTable :: (IR.StrTable -> (IR.StrTable, a)) -> Env.PrlgEnv a
|
||||||
withStrTable f = do
|
withStrTable f = do
|
||||||
st <- gets strtable
|
(st', x) <- strtable `uses` f
|
||||||
let (st', x) = f st
|
strtable .= st'
|
||||||
modify (\s -> s {strtable = st'})
|
|
||||||
return x
|
return x
|
||||||
|
|
||||||
findStruct :: String -> Int -> Env.PrlgEnv IR.Id
|
findStruct :: String -> Int -> Env.PrlgEnv IR.Id
|
||||||
|
|
|
@ -2,15 +2,16 @@ module Frontend where
|
||||||
|
|
||||||
import Builtins
|
import Builtins
|
||||||
import Code (Interp(..))
|
import Code (Interp(..))
|
||||||
|
import CodeLens
|
||||||
import Control.Monad (when)
|
import Control.Monad (when)
|
||||||
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, modify)
|
import Control.Monad.Trans.State.Lazy (evalStateT)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Env (PrlgEnv)
|
import Env (PrlgEnv)
|
||||||
import qualified IR
|
import qualified IR
|
||||||
import qualified Interpreter as I
|
import qualified Interpreter as I
|
||||||
|
import Lens.Family2.State
|
||||||
import Load
|
import Load
|
||||||
( compile
|
( compile
|
||||||
, intern
|
, intern
|
||||||
|
@ -20,19 +21,6 @@ import Load
|
||||||
, shunt
|
, shunt
|
||||||
)
|
)
|
||||||
import System.Console.Haskeline
|
import System.Console.Haskeline
|
||||||
import qualified Text.Pretty.Simple as Ppr
|
|
||||||
|
|
||||||
ppr :: Show a => a -> PrlgEnv ()
|
|
||||||
ppr x =
|
|
||||||
liftIO $
|
|
||||||
Ppr.pPrintOpt
|
|
||||||
Ppr.CheckColorTty
|
|
||||||
Ppr.defaultOutputOptionsDarkBg
|
|
||||||
{ Ppr.outputOptionsCompactParens = True
|
|
||||||
, Ppr.outputOptionsIndentAmount = 2
|
|
||||||
, Ppr.outputOptionsPageWidth = 80
|
|
||||||
}
|
|
||||||
x
|
|
||||||
|
|
||||||
-- 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
|
||||||
|
@ -40,8 +28,8 @@ handleError m = do
|
||||||
case res of
|
case res of
|
||||||
Left err -> do
|
Left err -> do
|
||||||
lift $ outputStrLn err
|
lift $ outputStrLn err
|
||||||
modify $ \s -> s {cmdq = []}
|
cmdq .= []
|
||||||
_ -> pure ()
|
_ -> (pure () :: PrlgEnv ()) --prevents ambiguity
|
||||||
|
|
||||||
processCmd precompileHook ast' = do
|
processCmd precompileHook ast' = do
|
||||||
ast <- shunt ast'
|
ast <- shunt ast'
|
||||||
|
@ -55,7 +43,7 @@ interpreterStart = do
|
||||||
|
|
||||||
interpreterLoop :: Bool -> PrlgEnv ()
|
interpreterLoop :: Bool -> PrlgEnv ()
|
||||||
interpreterLoop queryMode = do
|
interpreterLoop queryMode = do
|
||||||
q <- gets cmdq
|
q <- use cmdq
|
||||||
case q of
|
case q of
|
||||||
[] -> do
|
[] -> do
|
||||||
minput <-
|
minput <-
|
||||||
|
@ -71,7 +59,7 @@ interpreterLoop queryMode = do
|
||||||
handleError $ processInput "<user input>" queryMode input
|
handleError $ processInput "<user input>" queryMode input
|
||||||
interpreterLoop queryMode
|
interpreterLoop queryMode
|
||||||
((mode, ast):asts) -> do
|
((mode, ast):asts) -> do
|
||||||
modify $ \s -> s {cmdq = asts}
|
cmdq .= asts
|
||||||
handleError $ do
|
handleError $ do
|
||||||
resOK <-
|
resOK <-
|
||||||
processCmd
|
processCmd
|
||||||
|
@ -79,7 +67,7 @@ interpreterLoop queryMode = do
|
||||||
then queryExpansion
|
then queryExpansion
|
||||||
else loadExpansion)
|
else loadExpansion)
|
||||||
ast
|
ast
|
||||||
finished <- lift $ gets (null . cmdq)
|
finished <- lift $ cmdq `uses` null
|
||||||
when finished . lift . lift . outputStrLn $
|
when finished . lift . lift . outputStrLn $
|
||||||
case (resOK, queryMode) of
|
case (resOK, queryMode) of
|
||||||
(True, True) -> "yes."
|
(True, True) -> "yes."
|
||||||
|
@ -93,12 +81,12 @@ interpreter =
|
||||||
evalStateT
|
evalStateT
|
||||||
interpreterStart
|
interpreterStart
|
||||||
(Interp
|
(Interp
|
||||||
{ defs = M.empty
|
{ _defs = M.empty
|
||||||
, cur = error "no cur"
|
, _cur = error "no cur"
|
||||||
, cho = []
|
, _cho = []
|
||||||
, ops = []
|
, _ops = []
|
||||||
, opstash = []
|
, _opstash = []
|
||||||
, macrostash = []
|
, _macrostash = []
|
||||||
, strtable = IR.emptystrtable
|
, _strtable = IR.emptystrtable
|
||||||
, cmdq = []
|
, _cmdq = []
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{- VAM 2P, done the lazy way -}
|
{- pražský přehledný stroj -}
|
||||||
module Interpreter where
|
module Interpreter where
|
||||||
|
|
||||||
import Code
|
import Code
|
||||||
|
@ -8,7 +8,6 @@ import Code
|
||||||
, Datum(..)
|
, Datum(..)
|
||||||
, Dereferenced(..)
|
, Dereferenced(..)
|
||||||
, Instr(..)
|
, Instr(..)
|
||||||
, Interp(..)
|
|
||||||
, InterpFn
|
, InterpFn
|
||||||
, derefHeap
|
, derefHeap
|
||||||
, emptyHeap
|
, emptyHeap
|
||||||
|
@ -17,29 +16,27 @@ import Code
|
||||||
, withNewHeapStruct
|
, withNewHeapStruct
|
||||||
, writeHeap
|
, writeHeap
|
||||||
)
|
)
|
||||||
import qualified Control.Monad.Trans.State.Lazy as St
|
import CodeLens
|
||||||
import Env (PrlgEnv)
|
|
||||||
|
|
||||||
--import Data.Function
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
import Env (PrlgEnv)
|
||||||
import IR (Id(..), StrTable(..))
|
import IR (Id(..), StrTable(..))
|
||||||
|
import Lens.Family2.State
|
||||||
|
|
||||||
prove :: Code -> PrlgEnv (Either String Bool)
|
prove :: Code -> PrlgEnv (Either String Bool)
|
||||||
prove g = do
|
prove g = do
|
||||||
St.modify $ \i ->
|
cur .=
|
||||||
i
|
Cho
|
||||||
{ cur =
|
{ _hed = g
|
||||||
Cho
|
, _hvar = emptyScope
|
||||||
{ hed = g
|
, _gol = [Done]
|
||||||
, hvar = emptyScope
|
, _gvar = emptyScope
|
||||||
, gol = [LastCall]
|
, _unis = 0
|
||||||
, gvar = emptyScope
|
, _retcut = True
|
||||||
, heap = emptyHeap
|
, _heap = emptyHeap
|
||||||
, stk = []
|
, _stk = []
|
||||||
, cut = []
|
, _cut = []
|
||||||
}
|
|
||||||
, cho = []
|
|
||||||
}
|
}
|
||||||
|
cho .= []
|
||||||
loop
|
loop
|
||||||
where
|
where
|
||||||
loop = do
|
loop = do
|
||||||
|
@ -48,20 +45,75 @@ prove g = do
|
||||||
Nothing -> loop -- not finished yet
|
Nothing -> loop -- not finished yet
|
||||||
Just x -> return x
|
Just x -> return x
|
||||||
|
|
||||||
{- Simple "fail" backtracking -}
|
{- toplevel decision -}
|
||||||
|
proveStep :: InterpFn
|
||||||
|
proveStep = do
|
||||||
|
u <- use (cur . unis)
|
||||||
|
h <- use (cur . hed)
|
||||||
|
case (u, h) of
|
||||||
|
(0, []) -> goalStep
|
||||||
|
(0, _) -> headStep h
|
||||||
|
(_, _)
|
||||||
|
| u > 0 -> unifyStep h
|
||||||
|
_ -> err "invalid state"
|
||||||
|
|
||||||
|
err :: String -> InterpFn
|
||||||
|
err = return . Just . Left
|
||||||
|
|
||||||
|
{- toplevel choices -}
|
||||||
|
goalStep :: InterpFn
|
||||||
|
goalStep = do
|
||||||
|
g <- use (cur . gol)
|
||||||
|
case g of
|
||||||
|
U (Struct _):gs -> undefined -- TODO these things NEED lens-family.
|
||||||
|
[Done] -> undefined
|
||||||
|
[Cut, Done] -> undefined
|
||||||
|
Cut:gs -> undefined
|
||||||
|
[Choices cs, Done] -> undefined
|
||||||
|
[Choices cs, Cut, Done] -> undefined
|
||||||
|
Choices cs:gs -> undefined
|
||||||
|
_ -> err "invalid goal code"
|
||||||
|
|
||||||
|
headStep :: [Instr] -> InterpFn
|
||||||
|
headStep h = do
|
||||||
|
g <- use (cur . gol)
|
||||||
|
case (h, g) of
|
||||||
|
([Done], _) -> undefined
|
||||||
|
([Cut, Done], _) -> undefined
|
||||||
|
(_, [Done]) -> undefined
|
||||||
|
(_, [Cut, Done]) -> undefined
|
||||||
|
(_, _) -> undefined
|
||||||
|
|
||||||
|
unifyStep h = do
|
||||||
|
g <- use (cur . gol)
|
||||||
|
case (h, g) of
|
||||||
|
(U hd:_, U gd:_) -> undefined hd gd
|
||||||
|
(_, _) -> err "invalid unification code"
|
||||||
|
|
||||||
|
{- helpers -}
|
||||||
backtrack :: InterpFn
|
backtrack :: InterpFn
|
||||||
backtrack = do
|
backtrack = do
|
||||||
chos <- St.gets cho
|
chos <- use cho
|
||||||
case chos
|
case chos of
|
||||||
{- if available, restore the easiest choicepoint -}
|
(c:cs)
|
||||||
of
|
{- if available, restore the easiest choicepoint -}
|
||||||
(c:cs) -> do
|
-> do
|
||||||
St.modify $ \i -> i {cur = c, cho = cs}
|
cur .= c
|
||||||
|
cho .= cs
|
||||||
pure Nothing
|
pure Nothing
|
||||||
{- if there's no other choice, answer no -}
|
{- if there's no other choice, answer no -}
|
||||||
_ -> pure . Just $ Right False
|
_ -> pure . Just $ Right False
|
||||||
|
|
||||||
proveStep :: InterpFn
|
retCut :: InterpFn
|
||||||
|
retCut = undefined
|
||||||
|
|
||||||
|
cutHead :: InterpFn
|
||||||
|
cutHead = undefined
|
||||||
|
|
||||||
|
cutGoal :: InterpFn
|
||||||
|
cutGoal = undefined
|
||||||
|
{- original, TODO remove -}
|
||||||
|
{-proveStep :: InterpFn
|
||||||
proveStep = St.get >>= go
|
proveStep = St.get >>= go
|
||||||
where
|
where
|
||||||
finish = pure . Just
|
finish = pure . Just
|
||||||
|
@ -325,3 +377,4 @@ proveStep = St.get >>= go
|
||||||
"code broken: impossible instruction combo hed=" ++
|
"code broken: impossible instruction combo hed=" ++
|
||||||
show (hed . cur $ i) ++
|
show (hed . cur $ i) ++
|
||||||
" gol=" ++ show (gol . cur $ i) ++ " stk=" ++ show (stk . cur $ i)
|
" gol=" ++ show (gol . cur $ i) ++ " stk=" ++ show (stk . cur $ i)
|
||||||
|
-}
|
||||||
|
|
17
app/Load.hs
17
app/Load.hs
|
@ -1,13 +1,14 @@
|
||||||
module Load where
|
module Load where
|
||||||
|
|
||||||
import Code (Code, Interp(..))
|
import Code (Code, PrlgEnv)
|
||||||
|
import CodeLens
|
||||||
import qualified Compiler as C
|
import qualified Compiler as C
|
||||||
import Control.Monad.Trans.Class (lift)
|
import Control.Monad.Trans.Class (lift)
|
||||||
import Control.Monad.Trans.Except (except)
|
import Control.Monad.Trans.Except (ExceptT, except)
|
||||||
import Control.Monad.Trans.State.Lazy (gets, modify)
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Env (PrlgEnv, findAtom, findStruct, withStrTable)
|
import Env (findAtom, findStruct, withStrTable)
|
||||||
import qualified IR
|
import qualified IR
|
||||||
|
import Lens.Family2.State
|
||||||
import qualified Parser as P
|
import qualified Parser as P
|
||||||
import qualified Text.Megaparsec as MP
|
import qualified Text.Megaparsec as MP
|
||||||
|
|
||||||
|
@ -20,8 +21,9 @@ tokenize fn = left MP.errorBundlePretty . MP.parse P.lexPrlg fn
|
||||||
parse :: String -> [P.Lexeme] -> Either String [P.PAST]
|
parse :: String -> [P.Lexeme] -> Either String [P.PAST]
|
||||||
parse fn = left MP.errorBundlePretty . MP.parse P.parsePrlg fn
|
parse fn = left MP.errorBundlePretty . MP.parse P.parsePrlg fn
|
||||||
|
|
||||||
|
shunt :: P.PAST -> ExceptT String PrlgEnv IR.PrlgStr
|
||||||
shunt past = do
|
shunt past = do
|
||||||
ops <- lift $ gets ops
|
ops <- lift $ use ops
|
||||||
except . left (\err -> "operator resolution: " ++ err ++ "\n") $
|
except . left (\err -> "operator resolution: " ++ err ++ "\n") $
|
||||||
P.shuntPrlg ops past
|
P.shuntPrlg ops past
|
||||||
|
|
||||||
|
@ -50,7 +52,7 @@ expansion noexpand expander output x = do
|
||||||
es <- findStruct expander 2
|
es <- findStruct expander 2
|
||||||
o <- findAtom output
|
o <- findAtom output
|
||||||
comma <- findAtom ","
|
comma <- findAtom ","
|
||||||
expand <- gets (M.member es . defs)
|
expand <- defs `uses` M.member es
|
||||||
pure $
|
pure $
|
||||||
if expand
|
if expand
|
||||||
then IR.CallI
|
then IR.CallI
|
||||||
|
@ -64,6 +66,7 @@ queryExpansion = expansion (\_ -> id) "expand_query" "call"
|
||||||
|
|
||||||
loadExpansion = expansion (\o x -> IR.CallI o [x]) "expand_load" "assert"
|
loadExpansion = expansion (\o x -> IR.CallI o [x]) "expand_load" "assert"
|
||||||
|
|
||||||
|
processInput :: String -> Bool -> String -> ExceptT String PrlgEnv ()
|
||||||
processInput fn queryMode input = do
|
processInput fn queryMode input = do
|
||||||
asts <- except $ tokenize fn input >>= parse fn
|
asts <- except $ tokenize fn input >>= parse fn
|
||||||
lift . modify $ \s -> s {cmdq = [(queryMode, ast) | ast <- asts]}
|
lift $ cmdq .= [(queryMode, ast) | ast <- asts]
|
||||||
|
|
|
@ -25,11 +25,11 @@ 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, Load
|
other-modules: Interpreter, Compiler, Parser, Frontend, IR, Operators, Code, Builtins, Env, Load, CodeLens
|
||||||
|
|
||||||
-- LANGUAGE extensions used by modules in this package.
|
-- LANGUAGE extensions used by modules in this package.
|
||||||
-- other-extensions:
|
-- other-extensions:
|
||||||
build-depends: base >=4.14, containers, megaparsec, haskeline, pretty-simple, split, transformers
|
build-depends: base >=4.14, containers, megaparsec, haskeline, split, transformers, lens-family, lens-family-th
|
||||||
hs-source-dirs: app
|
hs-source-dirs: app
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
ghc-options: -Wunused-imports
|
ghc-options: -Wunused-imports
|
||||||
|
|
Loading…
Reference in a new issue