Move parallel assignment handling into a pass

This commit is contained in:
Adam Sampson 2007-04-20 13:16:29 +00:00
parent a8bffbcac0
commit e8d61dcac7
3 changed files with 27 additions and 22 deletions

View File

@ -854,29 +854,14 @@ genProcess p = case p of
--{{{ assignment
genAssign :: [A.Variable] -> A.ExpressionList -> CGen ()
genAssign vs el
genAssign [v] el
= case el of
A.FunctionCallList m n es -> missing "function call"
A.ExpressionList m es -> case vs of
[v] ->
do genVariable v
tell [" = "]
genExpression (head es)
tell [";\n"]
vs ->
do tell ["{\n"]
ns <- mapM (\_ -> makeNonce "assign_tmp") vs
mapM (\(v, n, e) -> do st <- get
t <- checkJust $ typeOfVariable st v
genType t
tell [" ", n, " = "]
genExpression e
tell [";\n"])
(zip3 vs ns es)
mapM (\(v, n) -> do genVariable v
tell [" = ", n, ";\n"])
(zip vs ns)
tell ["}\n"]
A.ExpressionList m es ->
do genVariable v
tell [" = "]
genExpression (head es)
tell [";\n"]
--}}}
--{{{ input
genInput :: A.Variable -> A.InputMode -> CGen ()

View File

@ -15,6 +15,7 @@ import Pass
simplifyProcs :: A.Process -> PassM A.Process
simplifyProcs p
= parsToProcs p
>>= removeParAssign
-- | Wrap the subprocesses of PARs in no-arg PROCs.
parsToProcs :: Data t => t -> PassM t
@ -37,3 +38,21 @@ parsToProcs = doGeneric `extM` doProcess
return $ A.ParRep m pm rep' call
doProcess p = doGeneric p
-- | Turn parallel assignment into multiple single assignments.
removeParAssign :: Data t => t -> PassM t
removeParAssign = doGeneric `extM` doProcess
where
doGeneric :: Data t => t -> PassM t
doGeneric = gmapM removeParAssign
doProcess :: A.Process -> PassM A.Process
doProcess (A.Assign m vs@(_:_:_) (A.ExpressionList _ es))
= do ps <- get
let ts = [fromJust $ typeOfVariable ps v | v <- vs]
specs <- sequence [makeNonceVariable "assign_temp" m t A.VariableName A.Original | t <- ts]
let temps = [A.Variable m n | A.Specification _ n _ <- specs]
let first = [A.Assign m [v] (A.ExpressionList m [e]) | (v, e) <- zip temps es]
let second = [A.Assign m [v] (A.ExpressionList m [A.ExprVariable m v']) | (v, v') <- zip vs temps]
return $ foldl (\p s -> A.ProcSpec m s p) (A.Seq m $ first ++ second) specs
doProcess p = doGeneric p

View File

@ -2,10 +2,11 @@ To-do list for FCO
------------------
Have a "compiler options" field in ParseState, which can contain things like:
- whether -v is on (which avoids needing to pass "progress" around -- and means
we can have a pass composition operator)
- optional tracing in passes
- whether to compile out overflow/bounds checks
Parallel assignment should be handled by a simplification pass, not by GenerateC.
(Then things get proper names and we can write a genAssignment function that
handles different types.)
- and then array assignment can be made to work properly.