forked from GitHub/gf-core
primitive pattern matching
This commit is contained in:
@@ -27,9 +27,10 @@ compDef d = case d of
|
|||||||
addOper f exp
|
addOper f exp
|
||||||
DPar p cs -> do
|
DPar p cs -> do
|
||||||
v <- sizeParType cs
|
v <- sizeParType cs
|
||||||
addTypedef p $ TVal $ toInteger $ fst v
|
let ty = TBas p
|
||||||
|
addParsize ty $ fst v
|
||||||
vals <- allParVals cs
|
vals <- allParVals cs
|
||||||
addPartype (TBas p) vals
|
addPartype ty vals
|
||||||
mapM_ (uncurry addParVal) (zip vals (map VPar [0..]))
|
mapM_ (uncurry addParVal) (zip vals (map VPar [0..]))
|
||||||
DOpty a ty -> do
|
DOpty a ty -> do
|
||||||
addTypedef a ty
|
addTypedef a ty
|
||||||
|
|||||||
@@ -11,13 +11,14 @@ data Env = Env {
|
|||||||
types :: M.Map Ident Type,
|
types :: M.Map Ident Type,
|
||||||
opers :: M.Map Ident Exp,
|
opers :: M.Map Ident Exp,
|
||||||
typedefs :: M.Map Ident Type,
|
typedefs :: M.Map Ident Type,
|
||||||
|
parsizes :: M.Map Type Int,
|
||||||
partypes :: M.Map Type [Exp],
|
partypes :: M.Map Type [Exp],
|
||||||
parvals :: M.Map Exp Val,
|
parvals :: M.Map Exp Val,
|
||||||
vars :: M.Map Ident Val
|
vars :: M.Map Ident Val
|
||||||
--- constrs :: M.Map Ident ([Int] -> Int)
|
--- constrs :: M.Map Ident ([Int] -> Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
emptyEnv = Env M.empty M.empty M.empty M.empty M.empty M.empty M.empty
|
emptyEnv = Env M.empty M.empty M.empty M.empty M.empty M.empty M.empty M.empty
|
||||||
|
|
||||||
lookEnv :: (Show i, Ord i) => (Env -> M.Map i a) -> i -> STM Env a
|
lookEnv :: (Show i, Ord i) => (Env -> M.Map i a) -> i -> STM Env a
|
||||||
lookEnv field c = do
|
lookEnv field c = do
|
||||||
@@ -36,6 +37,9 @@ addOper c v = updateSTM (\env -> (env{opers = M.insert c v (opers env)}))
|
|||||||
addTypedef :: Ident -> Type -> STM Env ()
|
addTypedef :: Ident -> Type -> STM Env ()
|
||||||
addTypedef c v = updateSTM (\env -> (env{typedefs = M.insert c v (typedefs env)}))
|
addTypedef c v = updateSTM (\env -> (env{typedefs = M.insert c v (typedefs env)}))
|
||||||
|
|
||||||
|
addParsize :: Type -> Int -> STM Env ()
|
||||||
|
addParsize c v = updateSTM (\env -> (env{parsizes = M.insert c v (parsizes env)}))
|
||||||
|
|
||||||
addPartype :: Type -> [Exp] -> STM Env ()
|
addPartype :: Type -> [Exp] -> STM Env ()
|
||||||
addPartype c v = updateSTM (\env -> (env{partypes = M.insert c v (partypes env)}))
|
addPartype c v = updateSTM (\env -> (env{partypes = M.insert c v (partypes env)}))
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import AbsSrc
|
|||||||
import AbsTgt
|
import AbsTgt
|
||||||
import SMacros
|
import SMacros
|
||||||
import TMacros
|
import TMacros
|
||||||
|
import Match
|
||||||
import ComposOp
|
|
||||||
import STM
|
|
||||||
import Env
|
import Env
|
||||||
|
|
||||||
|
import STM
|
||||||
|
|
||||||
|
|
||||||
eval :: Exp -> STM Env Val
|
eval :: Exp -> STM Env Val
|
||||||
eval e = case e of
|
eval e = case e of
|
||||||
EAbs x b -> do
|
EAbs x b -> do
|
||||||
@@ -38,11 +39,13 @@ eval e = case e of
|
|||||||
vs <- mapM eval [e | FExp _ e <- fs]
|
vs <- mapM eval [e | FExp _ e <- fs]
|
||||||
return $ VRec vs
|
return $ VRec vs
|
||||||
|
|
||||||
ETab cs -> do
|
ETab ty cs -> do
|
||||||
vs <- mapM eval [e | Cas _ e <- cs] ---- expand and pattern match
|
-- sz <- lookEnv parsizes ty
|
||||||
|
-- let ps = map (VPar . toInteger) [0..sz-1]
|
||||||
|
ps <- lookEnv partypes ty
|
||||||
|
vs <- mapM (\p -> match cs p >>= eval) ps
|
||||||
return $ VRec vs
|
return $ VRec vs
|
||||||
|
|
||||||
|
|
||||||
ESel t v -> do
|
ESel t v -> do
|
||||||
t' <- eval t
|
t' <- eval t
|
||||||
v' <- eval v
|
v' <- eval v
|
||||||
|
|||||||
21
devel/compiler/Match.hs
Normal file
21
devel/compiler/Match.hs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
module Match where
|
||||||
|
|
||||||
|
import AbsSrc
|
||||||
|
import AbsTgt
|
||||||
|
|
||||||
|
import Env
|
||||||
|
import STM
|
||||||
|
|
||||||
|
match :: [Case] -> Exp -> STM Env Exp
|
||||||
|
match cs v = checks $ map (tryMatch v) cs
|
||||||
|
|
||||||
|
---- return substitution
|
||||||
|
tryMatch :: Exp -> Case -> STM Env Exp
|
||||||
|
tryMatch e (Cas p v) = if fit (e, p) then return v else raise "no fit" where
|
||||||
|
fit (exp,patt) = case (exp,patt) of
|
||||||
|
(ECst c es, PCon d ps) ->
|
||||||
|
c == d &&
|
||||||
|
length es == length ps &&
|
||||||
|
all fit (zip es ps)
|
||||||
|
(_,PVar _) -> True ---- not is exp contains variables
|
||||||
|
|
||||||
@@ -12,16 +12,9 @@ sizeParType cs = do
|
|||||||
return (sum scs, length cs)
|
return (sum scs, length cs)
|
||||||
where
|
where
|
||||||
sizeC (Con c ts) = do
|
sizeC (Con c ts) = do
|
||||||
ats <- mapM lookParTypeSize ts
|
ats <- mapM (lookEnv parsizes) ts
|
||||||
return $ product ats
|
return $ product ats
|
||||||
|
|
||||||
lookParTypeSize :: Type -> STM Env Int
|
|
||||||
lookParTypeSize ty = case ty of
|
|
||||||
TBas c -> do
|
|
||||||
ty' <- lookEnv typedefs c
|
|
||||||
lookParTypeSize ty'
|
|
||||||
TVal i -> return $ fromInteger i
|
|
||||||
|
|
||||||
allParVals :: [Constr] -> STM Env [Exp]
|
allParVals :: [Constr] -> STM Env [Exp]
|
||||||
allParVals cs = do
|
allParVals cs = do
|
||||||
ess <- mapM alls cs
|
ess <- mapM alls cs
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ import qualified Data.Map as M
|
|||||||
|
|
||||||
prEnv :: Env -> IO ()
|
prEnv :: Env -> IO ()
|
||||||
prEnv env = do
|
prEnv env = do
|
||||||
putStrLn "--# values"
|
|
||||||
mapM_ putStrLn
|
|
||||||
[prs c ++ " = " ++ prt val | (c,val) <- M.toList $ values env]
|
|
||||||
putStrLn "--# types"
|
putStrLn "--# types"
|
||||||
mapM_ putStrLn
|
mapM_ putStrLn
|
||||||
[prs c ++ " : " ++ prs val | (c,val) <- M.toList $ types env]
|
[prs c ++ " : " ++ prs val | (c,val) <- M.toList $ types env]
|
||||||
@@ -27,6 +24,10 @@ prEnv env = do
|
|||||||
putStrLn "--# parvals"
|
putStrLn "--# parvals"
|
||||||
mapM_ putStrLn
|
mapM_ putStrLn
|
||||||
[prs c ++ " = " ++ prt val | (c,val) <- M.toList $ parvals env]
|
[prs c ++ " = " ++ prt val | (c,val) <- M.toList $ parvals env]
|
||||||
|
putStrLn "--# values"
|
||||||
|
mapM_ putStrLn
|
||||||
|
[prs c ++ " = " ++ prt val | (c,val) <- M.toList $ values env]
|
||||||
|
|
||||||
|
|
||||||
prs :: (S.Print a) => a -> String
|
prs :: (S.Print a) => a -> String
|
||||||
prs = S.printTree
|
prs = S.printTree
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ ERec. Exp2 ::= "{" [Assign] "}" ;
|
|||||||
EApp. Exp1 ::= Exp1 Exp2 ;
|
EApp. Exp1 ::= Exp1 Exp2 ;
|
||||||
ESel. Exp1 ::= Exp1 "!" Exp2 ;
|
ESel. Exp1 ::= Exp1 "!" Exp2 ;
|
||||||
EPro. Exp1 ::= Exp1 "." Exp2 ;
|
EPro. Exp1 ::= Exp1 "." Exp2 ;
|
||||||
ETab. Exp1 ::= "table" "{" [Case] "}" ;
|
ETab. Exp1 ::= "table" Type "{" [Case] "}" ;
|
||||||
ETbv. Exp1 ::= "table" "(" Type ")" "{" [Exp] "}" ;
|
|
||||||
ECat. Exp ::= Exp "++" Exp1 ;
|
ECat. Exp ::= Exp "++" Exp1 ;
|
||||||
EAbs. Exp ::= "\\" Ident "->" Exp ;
|
EAbs. Exp ::= "\\" Ident "->" Exp ;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ compVal args = comp where
|
|||||||
VRec vs -> VRec $ map comp vs
|
VRec vs -> VRec $ map comp vs
|
||||||
VPro r p -> case (comp r, comp p) of
|
VPro r p -> case (comp r, comp p) of
|
||||||
(VRec vs, VPar i) -> vs !! fromInteger i
|
(VRec vs, VPar i) -> vs !! fromInteger i
|
||||||
VArg i -> args !! fromInteger i
|
(r',p') -> VPro r' p' ---- not at runtime
|
||||||
|
VArg j
|
||||||
|
| i < length args -> args !! i ---- not needed at runtime
|
||||||
|
| otherwise -> val ---- not the right thing at compiletime either
|
||||||
|
where i = fromInteger j
|
||||||
VCat x y -> VCat (comp x) (comp y)
|
VCat x y -> VCat (comp x) (comp y)
|
||||||
_ -> val
|
_ -> val
|
||||||
|
|||||||
@@ -8,14 +8,13 @@ oper Agr = {g : Gen ; n : Num} ;
|
|||||||
oper CN = {s : Num -> Str ; g : Gen} ;
|
oper CN = {s : Num -> Str ; g : Gen} ;
|
||||||
oper NP = {s : Str ; a : Agr} ;
|
oper NP = {s : Str ; a : Agr} ;
|
||||||
|
|
||||||
oper artDef : Gen -> Str = \g -> table {
|
oper artDef : Gen -> Str = \g -> table Gen {
|
||||||
(Masc) => "le" ;
|
(Masc) => "le" ;
|
||||||
(Fem) => "la"
|
(Fem) => "la"
|
||||||
} ! $g ;
|
} ! $g ;
|
||||||
|
|
||||||
|
|
||||||
lin Voiture : CN = {
|
lin Voiture : CN = {
|
||||||
s = table {
|
s = table Num {
|
||||||
(Sg) => "voiture" ;
|
(Sg) => "voiture" ;
|
||||||
(Pl) => "voitures"
|
(Pl) => "voitures"
|
||||||
} ;
|
} ;
|
||||||
@@ -24,13 +23,20 @@ lin Voiture : CN = {
|
|||||||
|
|
||||||
|
|
||||||
lin Bus : CN = {
|
lin Bus : CN = {
|
||||||
s = table {$x => "bus"} ;
|
s = table Num {$x => "bus"} ;
|
||||||
g = (Masc@)
|
g = (Masc@)
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
{-
|
lin Indef : CN -> NP = \cn -> {
|
||||||
|
s = table Gen {
|
||||||
|
(Masc) => "un" ;
|
||||||
|
$x => "une"
|
||||||
|
} ! $cn.g ++ $cn.s ! (Sg@) ;
|
||||||
|
a = {g = $cn.g ; n = (Sg@)}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
lin Def : CN -> NP = \cn -> {
|
lin Def : CN -> NP = \cn -> {
|
||||||
s = &artDef $cn.g ++ $cn.s ! (Sg@) ;
|
s = &artDef $cn.g ++ $cn.s ! (Sg@) ;
|
||||||
a = {g = $cn.g ; n = (Sg@)}
|
a = {g = $cn.g ; n = (Sg@)}
|
||||||
} ;
|
} ;
|
||||||
-}
|
|
||||||
Reference in New Issue
Block a user