Multidimensional arrays and slices
This commit is contained in:
parent
5840659ade
commit
2ec22a5c24
|
@ -182,20 +182,6 @@ genConversion A.DefaultConversion t e
|
||||||
genConversion cm t e = missing $ "genConversion " ++ show cm
|
genConversion cm t e = missing $ "genConversion " ++ show cm
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
--{{{ subscripts
|
|
||||||
genSubscript :: A.Subscript -> CGen () -> CGen ()
|
|
||||||
genSubscript (A.Subscript m e) p
|
|
||||||
= do p
|
|
||||||
tell ["["]
|
|
||||||
genExpression e
|
|
||||||
tell ["]"]
|
|
||||||
genSubscript (A.SubscriptField m n) p
|
|
||||||
= do p
|
|
||||||
tell ["->"]
|
|
||||||
genName n
|
|
||||||
genSubscript s p = missing $ "genSubscript " ++ show s
|
|
||||||
--}}}
|
|
||||||
|
|
||||||
--{{{ literals
|
--{{{ literals
|
||||||
genLiteral :: A.Literal -> CGen ()
|
genLiteral :: A.Literal -> CGen ()
|
||||||
genLiteral (A.Literal m t lr) = genLiteralRepr lr
|
genLiteral (A.Literal m t lr) = genLiteralRepr lr
|
||||||
|
@ -235,13 +221,26 @@ The various types are generated like this:
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
INT x: int x; int x; int *x;
|
INT x: int x; int x; int *x;
|
||||||
x x x *x
|
x x x *x
|
||||||
|
|
||||||
[10]INT xs: int xs[10]; int *xs; int *xs;
|
[10]INT xs: int xs[10]; int *xs; int *xs;
|
||||||
xs xs xs xs
|
xs xs xs xs
|
||||||
xs[i] xs[i] xs[i] xs[i]
|
xs[i] xs[i] xs[i] xs[i]
|
||||||
|
|
||||||
|
[20][10]INT xss: int xss[20*10]; int *xss; int *xss;
|
||||||
|
xss xss xss xss
|
||||||
|
xss[i] &xss[i*10] &xss[i*10] &xss[i*10] (where 10 = xss_sizes[1])
|
||||||
|
xss[i][j] xss[i*10+j] xss[i*10+j] xss[i*10+j]
|
||||||
|
|
||||||
|
[6][4][2]INT xsss: int xsss[6*4*2]; int *xsss;
|
||||||
|
xsss xsss (as left)
|
||||||
|
xsss[i] &xsss[i*4*2]
|
||||||
|
xsss[i][j] &xsss[i*4*2+j*2]
|
||||||
|
xsss[i][j][k] xsss[i*4*2+j*2+k]
|
||||||
|
|
||||||
MYREC r: MYREC r; MYREC *r; MYREC *r;
|
MYREC r: MYREC r; MYREC *r; MYREC *r;
|
||||||
r &r r r
|
r &r r r
|
||||||
r[F] (&r)->F (r)->F (r)->F
|
r[F] (&r)->F (r)->F (r)->F
|
||||||
|
|
||||||
[10]MYREC rs: MYREC rs[10]; MYREC *rs; MYREC *rs;
|
[10]MYREC rs: MYREC rs[10]; MYREC *rs; MYREC *rs;
|
||||||
rs rs rs rs
|
rs rs rs rs
|
||||||
rs[i] &rs[i] &rs[i] &rs[i]
|
rs[i] &rs[i] &rs[i] &rs[i]
|
||||||
|
@ -250,14 +249,11 @@ MYREC r: MYREC r; MYREC *r; MYREC *r;
|
||||||
|
|
||||||
CHAN OF INT c: Channel c; Channel *c;
|
CHAN OF INT c: Channel c; Channel *c;
|
||||||
c &c c
|
c &c c
|
||||||
|
|
||||||
[10]CHAN OF INT cs: Channel **cs; Channel **cs;
|
[10]CHAN OF INT cs: Channel **cs; Channel **cs;
|
||||||
cs cs cs
|
cs cs cs
|
||||||
cs[i] cs[i] cs[i]
|
cs[i] cs[i] cs[i]
|
||||||
|
|
||||||
Should treat record fields as if they're Originals.
|
|
||||||
|
|
||||||
FIXME: Deal with multidimensional arrays, which are (slightly) more awkward again.
|
|
||||||
|
|
||||||
I suspect there's probably a nicer way of doing this, but as a translation of
|
I suspect there's probably a nicer way of doing this, but as a translation of
|
||||||
the above table this isn't too horrible...
|
the above table this isn't too horrible...
|
||||||
-}
|
-}
|
||||||
|
@ -280,8 +276,47 @@ genVariable v
|
||||||
inner v
|
inner v
|
||||||
when (prefix /= "") $ tell [")"]
|
when (prefix /= "") $ tell [")"]
|
||||||
where
|
where
|
||||||
|
inner :: A.Variable -> CGen ()
|
||||||
inner (A.Variable _ n) = genName n
|
inner (A.Variable _ n) = genName n
|
||||||
inner (A.SubscriptedVariable _ s v) = genSubscript s (genVariable v)
|
inner sv@(A.SubscriptedVariable _ (A.Subscript _ _) _)
|
||||||
|
= do let (es, v) = collectSubs sv
|
||||||
|
ps <- get
|
||||||
|
t <- checkJust $ typeOfVariable ps v
|
||||||
|
let numDims = case t of A.Array ds _ -> length ds
|
||||||
|
genVariable v
|
||||||
|
tell ["["]
|
||||||
|
sequence_ $ intersperse (tell [" + "]) $ genPlainSub v es [0..(numDims - 1)]
|
||||||
|
tell ["]"]
|
||||||
|
inner (A.SubscriptedVariable _ (A.SubscriptField m n) v)
|
||||||
|
= do genVariable v
|
||||||
|
tell ["->"]
|
||||||
|
genName n
|
||||||
|
inner (A.SubscriptedVariable m (A.SubscriptFromFor m' start _) v)
|
||||||
|
= inner (A.SubscriptedVariable m (A.Subscript m' start) v)
|
||||||
|
inner (A.SubscriptedVariable m (A.SubscriptFrom m' start) v)
|
||||||
|
= inner (A.SubscriptedVariable m (A.Subscript m' start) v)
|
||||||
|
inner (A.SubscriptedVariable m (A.SubscriptFor m' _) v)
|
||||||
|
= inner (A.SubscriptedVariable m (A.Subscript m' (makeConstant m' 0)) v)
|
||||||
|
|
||||||
|
-- | Collect all the plain subscripts on a variable, so we can combine them.
|
||||||
|
collectSubs :: A.Variable -> ([A.Expression], A.Variable)
|
||||||
|
collectSubs (A.SubscriptedVariable _ (A.Subscript _ e) v)
|
||||||
|
= (es' ++ [e], v')
|
||||||
|
where
|
||||||
|
(es', v') = collectSubs v
|
||||||
|
collectSubs v = ([], v)
|
||||||
|
|
||||||
|
-- | Generate the individual offsets that need adding together to find the
|
||||||
|
-- right place in the array.
|
||||||
|
-- FIXME This is obviously not the best way to factor this, but I figure a
|
||||||
|
-- smart C compiler should be able to work it out...
|
||||||
|
genPlainSub :: A.Variable -> [A.Expression] -> [Int] -> [CGen ()]
|
||||||
|
genPlainSub _ [] _ = []
|
||||||
|
genPlainSub v (e:es) (_:subs)
|
||||||
|
= gen : genPlainSub v es subs
|
||||||
|
where
|
||||||
|
gen = sequence_ $ intersperse (tell [" * "]) $ genExpression e : genChunks
|
||||||
|
genChunks = [genVariable v >> tell ["_sizes[", show i, "]"] | i <- subs]
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
--{{{ expressions
|
--{{{ expressions
|
||||||
|
@ -373,8 +408,7 @@ genInputItem c (A.InCounted m cv av)
|
||||||
tell ["ChanIn ("]
|
tell ["ChanIn ("]
|
||||||
genVariable c
|
genVariable c
|
||||||
tell [", "]
|
tell [", "]
|
||||||
let (rhs, rhsS) = abbrevVariable A.Abbrev t av
|
fst $ abbrevVariable A.Abbrev t av
|
||||||
rhs
|
|
||||||
tell [", "]
|
tell [", "]
|
||||||
let subT = fromJust $ subscriptType ps (A.Subscript m $ makeConstant m 0) t
|
let subT = fromJust $ subscriptType ps (A.Subscript m $ makeConstant m 0) t
|
||||||
genVariable cv
|
genVariable cv
|
||||||
|
@ -384,7 +418,7 @@ genInputItem c (A.InCounted m cv av)
|
||||||
genInputItem c (A.InVariable m v)
|
genInputItem c (A.InVariable m v)
|
||||||
= do ps <- get
|
= do ps <- get
|
||||||
t <- checkJust $ typeOfVariable ps v
|
t <- checkJust $ typeOfVariable ps v
|
||||||
let (rhs, rhsS) = abbrevVariable A.Abbrev t v
|
let rhs = fst $ abbrevVariable A.Abbrev t v
|
||||||
case t of
|
case t of
|
||||||
A.Int ->
|
A.Int ->
|
||||||
do tell ["ChanInInt ("]
|
do tell ["ChanInInt ("]
|
||||||
|
@ -411,8 +445,7 @@ genOutputItem c (A.OutCounted m ce ae)
|
||||||
do tell ["ChanOut ("]
|
do tell ["ChanOut ("]
|
||||||
genVariable c
|
genVariable c
|
||||||
tell [", "]
|
tell [", "]
|
||||||
let (rhs, rhsS) = abbrevVariable A.Abbrev t v
|
fst $ abbrevVariable A.Abbrev t v
|
||||||
rhs
|
|
||||||
tell [", "]
|
tell [", "]
|
||||||
let subT = fromJust $ subscriptType ps (A.Subscript m $ makeConstant m 0) t
|
let subT = fromJust $ subscriptType ps (A.Subscript m $ makeConstant m 0) t
|
||||||
genExpression ce
|
genExpression ce
|
||||||
|
@ -433,8 +466,7 @@ genOutputItem c (A.OutExpression m e)
|
||||||
do tell ["ChanOut ("]
|
do tell ["ChanOut ("]
|
||||||
genVariable c
|
genVariable c
|
||||||
tell [", "]
|
tell [", "]
|
||||||
let (rhs, rhsS) = abbrevVariable A.Abbrev t v
|
fst $ abbrevVariable A.Abbrev t v
|
||||||
rhs
|
|
||||||
tell [", "]
|
tell [", "]
|
||||||
genBytesInType t
|
genBytesInType t
|
||||||
tell [");\n"]
|
tell [");\n"]
|
||||||
|
@ -489,55 +521,82 @@ genReplicatorSize (A.For m n base count) = genExpression count
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
--{{{ abbreviations
|
--{{{ abbreviations
|
||||||
genSlice :: A.Variable -> A.Expression -> A.Expression -> (CGen (), Maybe (CGen ()))
|
-- FIXME: This code is horrible, and I can't easily convince myself that it's correct.
|
||||||
genSlice v start count
|
|
||||||
= ((do tell ["&"]
|
genSlice :: A.Variable -> A.Variable -> A.Expression -> A.Expression -> [A.Dimension] -> (CGen (), A.Name -> CGen ())
|
||||||
genVariable v
|
genSlice v (A.Variable _ on) start count ds
|
||||||
tell ["["]
|
= (tell ["&"] >> genVariable v,
|
||||||
genExpression start
|
genArraySize False
|
||||||
tell ["]"]),
|
(do genExpression count
|
||||||
(Just $ do tell ["{ "]
|
sequence_ [do tell [", "]
|
||||||
genExpression count
|
genName on
|
||||||
-- FIXME Add remaining dimensions
|
tell ["_sizes[", show i, "]"]
|
||||||
tell [" }"]))
|
| i <- [1..(length ds - 1)]]))
|
||||||
|
|
||||||
|
genArrayAbbrev :: A.Variable -> (CGen (), A.Name -> CGen ())
|
||||||
|
genArrayAbbrev v
|
||||||
|
= (genVariable v, genAASize v 0)
|
||||||
|
where
|
||||||
|
genAASize (A.SubscriptedVariable _ (A.Subscript _ _) v) arg
|
||||||
|
= genAASize v (arg + 1)
|
||||||
|
genAASize (A.Variable _ on) arg
|
||||||
|
= genArraySize True
|
||||||
|
(tell ["&"] >> genName on >> tell ["_sizes[", show arg, "]"])
|
||||||
|
|
||||||
|
genArraySize :: Bool -> CGen () -> A.Name -> CGen ()
|
||||||
|
genArraySize isPtr size n
|
||||||
|
= if isPtr
|
||||||
|
then do tell ["const int *"]
|
||||||
|
genName n
|
||||||
|
tell ["_sizes = "]
|
||||||
|
size
|
||||||
|
tell [";\n"]
|
||||||
|
else do tell ["const int "]
|
||||||
|
genName n
|
||||||
|
tell ["_sizes[] = { "]
|
||||||
|
size
|
||||||
|
tell [" };\n"]
|
||||||
|
|
||||||
|
noSize :: A.Name -> CGen ()
|
||||||
|
noSize n = return ()
|
||||||
|
|
||||||
-- | Generate the right-hand side of an abbreviation of a variable.
|
-- | Generate the right-hand side of an abbreviation of a variable.
|
||||||
abbrevVariable :: A.AbbrevMode -> A.Type -> A.Variable -> (CGen (), Maybe (CGen ()))
|
abbrevVariable :: A.AbbrevMode -> A.Type -> A.Variable -> (CGen (), A.Name -> CGen ())
|
||||||
abbrevVariable am _ (A.SubscriptedVariable _ (A.SubscriptFromFor _ start count) v)
|
abbrevVariable am (A.Array _ _) v@(A.SubscriptedVariable _ (A.Subscript _ _) _)
|
||||||
= genSlice v start count
|
= genArrayAbbrev v
|
||||||
abbrevVariable am _ (A.SubscriptedVariable m (A.SubscriptFrom _ start) v)
|
abbrevVariable am (A.Array ds _) v@(A.SubscriptedVariable _ (A.SubscriptFromFor _ start count) v')
|
||||||
= genSlice v start (A.Dyadic m A.Minus (A.SizeExpr m (A.ExprVariable m v)) start)
|
= genSlice v v' start count ds
|
||||||
abbrevVariable am _ (A.SubscriptedVariable m (A.SubscriptFor _ count) v)
|
abbrevVariable am (A.Array ds _) v@(A.SubscriptedVariable m (A.SubscriptFrom _ start) v')
|
||||||
= genSlice v (makeConstant m 0) count
|
= genSlice v v' start (A.Dyadic m A.Minus (A.SizeExpr m (A.ExprVariable m v')) start) ds
|
||||||
|
abbrevVariable am (A.Array ds _) v@(A.SubscriptedVariable m (A.SubscriptFor _ count) v')
|
||||||
|
= genSlice v v' (makeConstant m 0) count ds
|
||||||
abbrevVariable am (A.Array _ _) v
|
abbrevVariable am (A.Array _ _) v
|
||||||
= (genVariable v, Just $ do { genVariable v; tell ["_sizes"] })
|
= (genVariable v, genArraySize True (genVariable v >> tell ["_sizes"]))
|
||||||
abbrevVariable am (A.Chan _) v
|
abbrevVariable am (A.Chan _) v
|
||||||
= (genVariable v, Nothing)
|
= (genVariable v, noSize)
|
||||||
abbrevVariable am (A.UserDataType _) v
|
abbrevVariable am (A.UserDataType _) v
|
||||||
= (genVariable v, Nothing)
|
= (genVariable v, noSize)
|
||||||
abbrevVariable am t v
|
abbrevVariable am t v
|
||||||
= (do { when (am == A.Abbrev) $ tell ["&"]; genVariable v }, Nothing)
|
= (do { when (am == A.Abbrev) $ tell ["&"]; genVariable v }, noSize)
|
||||||
|
|
||||||
-- | Generate the right-hand side of an abbreviation of an expression.
|
-- | Generate the right-hand side of an abbreviation of an expression.
|
||||||
abbrevExpression :: A.AbbrevMode -> A.Type -> A.Expression -> (CGen (), Maybe (CGen ()))
|
abbrevExpression :: A.AbbrevMode -> A.Type -> A.Expression -> (CGen (), A.Name -> CGen ())
|
||||||
abbrevExpression am t@(A.Array _ _) e
|
abbrevExpression am t@(A.Array _ _) e
|
||||||
= case e of
|
= case e of
|
||||||
A.ExprVariable _ v -> abbrevVariable am t v
|
A.ExprVariable _ v -> abbrevVariable am t v
|
||||||
A.ExprLiteral _ l ->
|
A.ExprLiteral _ l ->
|
||||||
case l of
|
case l of
|
||||||
A.Literal _ litT r -> (genExpression e, Just $ genTypeSize litT)
|
A.Literal _ litT r -> (genExpression e, genTypeSize litT)
|
||||||
A.SubscriptedLiteral _ _ _ -> bad
|
A.SubscriptedLiteral _ _ _ -> bad
|
||||||
_ -> bad
|
_ -> bad
|
||||||
where
|
where
|
||||||
bad = (missing "array expression abbreviation", Just $ missing "AEA size")
|
bad = (missing "array expression abbreviation", noSize)
|
||||||
|
|
||||||
genTypeSize :: A.Type -> CGen ()
|
genTypeSize :: A.Type -> (A.Name -> CGen ())
|
||||||
genTypeSize (A.Array ds _)
|
genTypeSize (A.Array ds _)
|
||||||
= do tell ["{ "]
|
= genArraySize False $ sequence_ $ intersperse genComma [genExpression e | A.Dimension e <- ds]
|
||||||
sequence_ $ intersperse genComma [genExpression e | A.Dimension e <- ds]
|
|
||||||
tell [" }"]
|
|
||||||
abbrevExpression am _ e
|
abbrevExpression am _ e
|
||||||
= (genExpression e, Nothing)
|
= (genExpression e, noSize)
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
--{{{ specifications
|
--{{{ specifications
|
||||||
|
@ -555,14 +614,10 @@ declareType t = genType t
|
||||||
|
|
||||||
genDimensions :: [A.Dimension] -> CGen ()
|
genDimensions :: [A.Dimension] -> CGen ()
|
||||||
genDimensions ds
|
genDimensions ds
|
||||||
= sequence_ $ [case d of
|
= do tell ["["]
|
||||||
A.Dimension e ->
|
sequence $ intersperse (tell [" * "])
|
||||||
do tell ["["]
|
[case d of A.Dimension e -> genExpression e | d <- ds]
|
||||||
genExpression e
|
|
||||||
tell ["]"]
|
tell ["]"]
|
||||||
A.UnknownDimension ->
|
|
||||||
missing "unknown dimension in declaration"
|
|
||||||
| d <- ds]
|
|
||||||
|
|
||||||
genDeclaration :: A.Type -> A.Name -> CGen ()
|
genDeclaration :: A.Type -> A.Name -> CGen ()
|
||||||
genDeclaration A.Timer n = return ()
|
genDeclaration A.Timer n = return ()
|
||||||
|
@ -648,28 +703,14 @@ introduceSpec (n, A.Is m am t v)
|
||||||
tell [" = "]
|
tell [" = "]
|
||||||
rhs
|
rhs
|
||||||
tell [";\n"]
|
tell [";\n"]
|
||||||
case rhsSizes of
|
rhsSizes n
|
||||||
Just r ->
|
|
||||||
do tell ["const int *"]
|
|
||||||
genName n
|
|
||||||
tell ["_sizes = "]
|
|
||||||
r
|
|
||||||
tell [";\n"]
|
|
||||||
Nothing -> return ()
|
|
||||||
introduceSpec (n, A.IsExpr m am t e)
|
introduceSpec (n, A.IsExpr m am t e)
|
||||||
= do let (rhs, rhsSizes) = abbrevExpression am t e
|
= do let (rhs, rhsSizes) = abbrevExpression am t e
|
||||||
genDecl am t n
|
genDecl am t n
|
||||||
tell [" = "]
|
tell [" = "]
|
||||||
rhs
|
rhs
|
||||||
tell [";\n"]
|
tell [";\n"]
|
||||||
case rhsSizes of
|
rhsSizes n
|
||||||
Just r ->
|
|
||||||
do tell ["const int "]
|
|
||||||
genName n
|
|
||||||
tell ["_sizes[] = "]
|
|
||||||
r
|
|
||||||
tell [";\n"]
|
|
||||||
Nothing -> return ()
|
|
||||||
introduceSpec (n, A.IsChannelArray m t cs)
|
introduceSpec (n, A.IsChannelArray m t cs)
|
||||||
= do genDecl A.Abbrev t n
|
= do genDecl A.Abbrev t n
|
||||||
tell [" = {"]
|
tell [" = {"]
|
||||||
|
@ -733,21 +774,21 @@ genActual :: A.Actual -> CGen ()
|
||||||
genActual actual
|
genActual actual
|
||||||
= case actual of
|
= case actual of
|
||||||
A.ActualExpression t e ->
|
A.ActualExpression t e ->
|
||||||
do let (rhs, rhsSizes) = abbrevExpression A.ValAbbrev t e
|
case (t, e) of
|
||||||
rhs
|
(A.Array _ _, A.ExprVariable _ v) ->
|
||||||
case rhsSizes of
|
do genVariable v
|
||||||
Just r ->
|
tell [", "]
|
||||||
do tell [", "]
|
genVariable v
|
||||||
r
|
tell ["_sizes"]
|
||||||
Nothing -> return ()
|
_ -> genExpression e
|
||||||
A.ActualVariable am t v ->
|
A.ActualVariable am t v ->
|
||||||
do let (rhs, rhsSizes) = abbrevVariable am t v
|
case t of
|
||||||
rhs
|
A.Array _ _ ->
|
||||||
case rhsSizes of
|
do genVariable v
|
||||||
Just r ->
|
tell [", "]
|
||||||
do tell [", "]
|
genVariable v
|
||||||
r
|
tell ["_sizes"]
|
||||||
Nothing -> return ()
|
_ -> fst $ abbrevVariable am t v
|
||||||
|
|
||||||
numCArgs :: [A.Actual] -> Int
|
numCArgs :: [A.Actual] -> Int
|
||||||
numCArgs [] = 0
|
numCArgs [] = 0
|
||||||
|
@ -761,11 +802,11 @@ genFormals fs = prefixComma (map genFormal fs)
|
||||||
genFormal :: A.Formal -> CGen ()
|
genFormal :: A.Formal -> CGen ()
|
||||||
genFormal (A.Formal am t n)
|
genFormal (A.Formal am t n)
|
||||||
= case t of
|
= case t of
|
||||||
(A.Array _ t) ->
|
A.Array _ t' ->
|
||||||
do genDecl am t n
|
do genDecl am t n
|
||||||
tell ["[], const int "]
|
tell [", const int *"]
|
||||||
genName n
|
genName n
|
||||||
tell ["_sizes[]"]
|
tell ["_sizes"]
|
||||||
_ -> genDecl am t n
|
_ -> genDecl am t n
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
|
|
|
@ -84,12 +84,12 @@ makeNonceProc m p
|
||||||
= defineNonce m "wrapper_proc" (A.Proc m [] p) A.ProcName A.Abbrev
|
= defineNonce m "wrapper_proc" (A.Proc m [] p) A.ProcName A.Abbrev
|
||||||
|
|
||||||
-- | Generate and define a variable abbreviation.
|
-- | Generate and define a variable abbreviation.
|
||||||
makeNonceIs :: MonadState ParseState m => Meta -> A.Type -> A.AbbrevMode -> A.Variable -> m A.Specification
|
makeNonceIs :: MonadState ParseState m => String -> Meta -> A.Type -> A.AbbrevMode -> A.Variable -> m A.Specification
|
||||||
makeNonceIs m t am v
|
makeNonceIs s m t am v
|
||||||
= defineNonce m "var" (A.Is m am t v) A.VariableName am
|
= defineNonce m s (A.Is m am t v) A.VariableName am
|
||||||
|
|
||||||
-- | Generate and define an expression abbreviation.
|
-- | Generate and define an expression abbreviation.
|
||||||
makeNonceIsExpr :: MonadState ParseState m => Meta -> A.Type -> A.Expression -> m A.Specification
|
makeNonceIsExpr :: MonadState ParseState m => String -> Meta -> A.Type -> A.Expression -> m A.Specification
|
||||||
makeNonceIsExpr m t e
|
makeNonceIsExpr s m t e
|
||||||
= defineNonce m "expr" (A.IsExpr m A.ValAbbrev t e) A.VariableName A.ValAbbrev
|
= defineNonce m s (A.IsExpr m A.ValAbbrev t e) A.VariableName A.ValAbbrev
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ pullUp = doGeneric `extM` doProcess `extM` doExpression `extM` doActual
|
||||||
modify (\ps -> ps { psPulledItems = psPulledItems origPS })
|
modify (\ps -> ps { psPulledItems = psPulledItems origPS })
|
||||||
return p'
|
return p'
|
||||||
|
|
||||||
-- | Pull array expressions that aren't already variables.
|
-- | Pull array expressions that aren't already non-subscripted variables.
|
||||||
doExpression :: A.Expression -> PassM A.Expression
|
doExpression :: A.Expression -> PassM A.Expression
|
||||||
doExpression e
|
doExpression e
|
||||||
= do e' <- doGeneric e
|
= do e' <- doGeneric e
|
||||||
|
@ -44,7 +44,7 @@ pullUp = doGeneric `extM` doProcess `extM` doExpression `extM` doActual
|
||||||
case t of
|
case t of
|
||||||
A.Array _ _ ->
|
A.Array _ _ ->
|
||||||
case e of
|
case e of
|
||||||
A.ExprVariable _ _ -> return e'
|
A.ExprVariable _ (A.Variable _ _) -> return e'
|
||||||
_ -> pull t e'
|
_ -> pull t e'
|
||||||
_ -> return e'
|
_ -> return e'
|
||||||
where
|
where
|
||||||
|
@ -52,26 +52,31 @@ pullUp = doGeneric `extM` doProcess `extM` doExpression `extM` doActual
|
||||||
pull t e
|
pull t e
|
||||||
= do -- FIXME Should get Meta from somewhere...
|
= do -- FIXME Should get Meta from somewhere...
|
||||||
let m = []
|
let m = []
|
||||||
spec@(n, _) <- makeNonceIsExpr m t e
|
spec@(n, _) <- makeNonceIsExpr "array_expr" m t e
|
||||||
addPulled $ A.ProcSpec m spec
|
addPulled $ A.ProcSpec m spec
|
||||||
return $ A.ExprVariable m (A.Variable m n)
|
return $ A.ExprVariable m (A.Variable m n)
|
||||||
|
|
||||||
-- | Pull array actual slices.
|
-- FIXME: We really want to pull *any* array slice that isn't already
|
||||||
|
-- an abbreviation and turn it into one -- should be straightforward using
|
||||||
|
-- a rule that matches abbrevs.
|
||||||
|
|
||||||
|
-- | Pull any actual that's a subscript resulting in an array.
|
||||||
doActual :: A.Actual -> PassM A.Actual
|
doActual :: A.Actual -> PassM A.Actual
|
||||||
doActual a@(A.ActualVariable _ _ _)
|
doActual a@(A.ActualVariable _ _ _)
|
||||||
= do a' <- doGeneric a
|
= do a' <- doGeneric a
|
||||||
let (am, t, v) = case a' of A.ActualVariable am t v -> (am, t, v)
|
let (am, t, v) = case a' of A.ActualVariable am t v -> (am, t, v)
|
||||||
case v of
|
case v of
|
||||||
A.SubscriptedVariable m s _ ->
|
A.SubscriptedVariable m _ _ ->
|
||||||
if isSliceSubscript s
|
case t of
|
||||||
then do v' <- pull m am t v
|
A.Array _ _ ->
|
||||||
|
do v' <- pull m am t v
|
||||||
return $ A.ActualVariable am t v'
|
return $ A.ActualVariable am t v'
|
||||||
else return a'
|
_ -> return a'
|
||||||
_ -> return a'
|
_ -> return a'
|
||||||
where
|
where
|
||||||
pull :: Meta -> A.AbbrevMode -> A.Type -> A.Variable -> PassM A.Variable
|
pull :: Meta -> A.AbbrevMode -> A.Type -> A.Variable -> PassM A.Variable
|
||||||
pull m am t v
|
pull m am t v
|
||||||
= do spec@(n, _) <- makeNonceIs m t am v
|
= do spec@(n, _) <- makeNonceIs "subscript_actual" m t am v
|
||||||
addPulled $ A.ProcSpec m spec
|
addPulled $ A.ProcSpec m spec
|
||||||
return $ A.Variable m n
|
return $ A.Variable m n
|
||||||
doActual a = doGeneric a
|
doActual a = doGeneric a
|
||||||
|
|
|
@ -141,11 +141,6 @@ isChannelType (A.Array _ t) = isChannelType t
|
||||||
isChannelType (A.Chan _) = True
|
isChannelType (A.Chan _) = True
|
||||||
isChannelType _ = False
|
isChannelType _ = False
|
||||||
|
|
||||||
isSliceSubscript :: A.Subscript -> Bool
|
|
||||||
isSliceSubscript (A.Subscript _ _) = False
|
|
||||||
isSliceSubscript (A.SubscriptField _ _) = False
|
|
||||||
isSliceSubscript _ = True
|
|
||||||
|
|
||||||
stripArrayType :: A.Type -> A.Type
|
stripArrayType :: A.Type -> A.Type
|
||||||
stripArrayType (A.Array _ t) = stripArrayType t
|
stripArrayType (A.Array _ t) = stripArrayType t
|
||||||
stripArrayType t = t
|
stripArrayType t = t
|
||||||
|
|
Loading…
Reference in New Issue
Block a user