Added support for giving ranges an explicit type in Rain

This commit is contained in:
Neil Brown 2008-03-21 21:10:47 +00:00
parent 0511c852da
commit 025eebf61d
3 changed files with 33 additions and 3 deletions

View File

@ -269,6 +269,7 @@ data ExprHelper =
| DirVar A.Direction String
| Lit A.Expression
| EHTrue
| Range A.Type ExprHelper ExprHelper
buildExprPattern :: ExprHelper -> Pattern
buildExprPattern = (stopCaringPattern emptyMeta) . mkPattern . buildExpr
@ -281,6 +282,8 @@ buildExpr (Var n) = A.ExprVariable emptyMeta $ variable n
buildExpr (DirVar dir n) = A.ExprVariable emptyMeta $ (A.DirectedVariable emptyMeta dir $ variable n)
buildExpr (Lit e) = e
buildExpr EHTrue = A.True emptyMeta
buildExpr (Range t begin end) = A.ExprConstr emptyMeta $ A.RangeConstr emptyMeta t
(buildExpr begin) (buildExpr end)
-- | A simple definition of a variable
simpleDef :: String -> A.SpecType -> A.NameDef

View File

@ -34,7 +34,7 @@ import qualified LexRain as L
import Metadata
import ParseUtils
import Pass
import Utils
type RainState = CompState
type RainParser = GenParser L.Token RainState
@ -233,9 +233,25 @@ literal = do {lr <- stringLiteral ; return $ A.Literal (findMeta lr) (A.List A.B
<|> listLiteral
<?> "literal"
maybeParse :: RainParser a -> RainParser (Maybe a)
maybeParse p = option Nothing (p >>* Just)
range :: RainParser A.Expression
range = try $ do {m <- sLeftQ ; begin <- literal; sDots ; end <- literal ;
sRightQ ; return $ A.ExprConstr m $ A.RangeConstr m (A.List A.Any) begin end}
range = try $ do m <- sLeftQ
optTy <- maybeParse $ try $ do t <- dataType
m <- sColon
return (t, m)
begin <- literal
sDots
end <- literal
sRightQ
case optTy of
Just (t, mc) -> return $ A.ExprConstr m $ A.RangeConstr m
(A.List t)
(A.Conversion mc A.DefaultConversion t begin)
(A.Conversion mc A.DefaultConversion t end)
Nothing -> return $ A.ExprConstr m $ A.RangeConstr m
(A.List A.Any) begin end
expression :: RainParser A.Expression
expression

View File

@ -46,6 +46,7 @@ import qualified LexRain as L
import Metadata (Meta,emptyMeta)
import qualified ParseRain as RP
import Pattern
import TagAST
import TestUtils
import TreeUtils
@ -196,6 +197,8 @@ testExprs =
passE (code,index,expr) = pass(code,RP.expression,assertPatternMatch ("testExprs " ++ show index) (buildExprPattern expr))
failE x = fail (x,RP.expression)
--TODO add support for shared ? and shared !, as well as any2any channels etc
testLiteral :: [ParseTest A.Expression]
testLiteral =
[
@ -277,9 +280,17 @@ testRange =
A.ExprConstr m $ A.RangeConstr m (A.List A.Any) (intLiteral 0) (intLiteral 10000))
,pass("[-3..-1]", RP.expression, assertPatternMatch "testRange 2" $ pat $
A.ExprConstr m $ A.RangeConstr m (A.List A.Any) (intLiteral $ -3) (intLiteral $ -1))
,pass("[sint16: 0..1]", RP.expression, rangePattern 4 (A.List A.Int16)
(buildExprPattern $ Cast A.Int16 (Lit $ intLiteral 0))
(buildExprPattern $ Cast A.Int16 (Lit $ intLiteral 1)))
--For now, at least, this should fail:
,fail("[0..x]", RP.expression)
]
where
rangePattern :: Int -> A.Type -> Pattern -> Pattern -> (A.Expression -> Assertion)
rangePattern n t start end = assertPatternMatch ("testRange " ++ show n) $
mExprConstr $ mRangeConstr t start end
--Helper function for ifs:
makeIf :: [(A.Expression,A.Process)] -> A.Process