diff --git a/fco2/GenerateC.hs b/fco2/GenerateC.hs index 677ec29..db22b4a 100644 --- a/fco2/GenerateC.hs +++ b/fco2/GenerateC.hs @@ -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 () diff --git a/fco2/SimplifyProcs.hs b/fco2/SimplifyProcs.hs index 4d1d012..82c549d 100644 --- a/fco2/SimplifyProcs.hs +++ b/fco2/SimplifyProcs.hs @@ -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 + diff --git a/fco2/TODO b/fco2/TODO index 433ad46..f2cc8f7 100644 --- a/fco2/TODO +++ b/fco2/TODO @@ -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.