@@ -16,6 +16,7 @@ import qualified Text.ParserCombinators.Parsec.Token as PTok
1616import Data.List
1717import Control.Monad.State
1818import Debug.Trace
19+import Data.Maybe
1920
2021type TokenParser a = PTok.TokenParser a
2122
@@ -143,6 +144,29 @@ pDecl' syn
143144 = try pFixity
144145 <|> pFunDecl' syn
145146 <|> try (pData syn)
147+ <|> try (pSyntaxDecl syn)
148+
149+pSyntaxDecl :: SyntaxInfo -> IParser PDecl
150+pSyntaxDecl syn
151+ = do s <- pSyntaxRule syn
152+ i <- getState
153+ setState (i { syntax_rules = s : syntax_rules i })
154+ return (PSyntax s)
155+
156+pSyntaxRule :: SyntaxInfo -> IParser Syntax
157+pSyntaxRule syn
158+ = do reserved "syntax"
159+ syms <- many1 pSynSym
160+ lchar '='
161+ tm <- pExpr syn
162+ lchar ';'
163+ return (Rule syms tm)
164+
165+pSynSym :: IParser SSymbol
166+pSynSym = try (do lchar '['; n <- iName; lchar ']'
167+ return (Expr n))
168+ <|> do n <- iName
169+ return (Keyword n)
146170
147171pFunDecl' :: SyntaxInfo -> IParser PDecl
148172pFunDecl' syn = try (do n <- pfName; ty <- pTSig syn
@@ -200,12 +224,44 @@ pExpr syn = do i <- getState
200224
201225pExpr' :: SyntaxInfo -> IParser PTerm
202226pExpr' syn
203− = try (pApp syn)
227+ = try (do i <- getState
228+ pExtensions syn (syntax_rules i))
229+ <|> try (pApp syn)
204230 <|> pSimpleExpr syn
205231 <|> try (pLambda syn)
206232 <|> try (pPi syn)
207233 <|> try (pDoBlock syn)
208234
235+pExtensions :: SyntaxInfo -> [Syntax] -> IParser PTerm
236+pExtensions syn rules = choice (map (pExt syn) rules)
237+
238+pExt :: SyntaxInfo -> Syntax -> IParser PTerm
239+pExt syn (Rule ssym ptm)
240+ = do smap <- mapM pSymbol ssym
241+ return (update (mapMaybe id smap) ptm) -- updated with smap
242+ where
243+ pSymbol (Keyword n) = do reserved (show n); return Nothing
244+ pSymbol (Expr n) = do tm <- pSimpleExpr syn
245+ return $ Just (n, tm)
246+ dropn n [] = []
247+ dropn n ((x,t) : xs) | n == x = xs
248+ | otherwise = (x,t):dropn n xs
249+
250+ update ns (PRef n) = case lookup n ns of
251+ Just t -> t
252+ _ -> PRef n
253+ update ns (PLam n ty sc) = PLam n (update ns ty) (update (dropn n ns) sc)
254+ update ns (PPi p n ty sc) = PPi p n (update ns ty) (update (dropn n ns) sc)
255+ update ns (PLet n ty val sc) = PLet n (update ns ty) (update ns val)
256+ (update (dropn n ns) sc)
257+ update ns (PApp t args) = PApp (update ns t) (map (fmap (update ns)) args)
258+ update ns (PPair l r) = PPair (update ns l) (update ns r)
259+ update ns (PHidden t) = PHidden (update ns t)
260+ update ns (PDoBlock ds) = PDoBlock $ upd ns ds
261+ where upd ns (DoExp t : ds) = DoExp (update ns t) : upd ns ds
262+ upd ns (DoBind n t : ds) = DoBind n (update ns t) : upd (dropn n ns) ds
263+ upd ns (DoLet n t : ds) = DoLet n (update ns t) : upd (dropn n ns) ds
264+
209265pfName = try iName
210266 <|> do lchar '('; o <- operator; lchar ')'; return (UN [o])
211267