@@ -208,6 +208,64 @@ registerIntroduction nth e = apo builder (branchVar nth newVarGen, e) where
208208 (\ (Just t) vs -> context $ VarTagNode t (tail vs))
209209 ((ValTag tag): vals)
210210
211+ nth :: Int -> Int -> [a ] -> [a ]
212+ nth s n = go 1 . drop s where
213+ go 1 (x: xs) = x: go n xs
214+ go n (_: xs) = go (n- 1 ) xs
215+
216+ registerIntroductionI :: Int -> Exp -> Exp
217+ registerIntroductionI _ e = apo builder ([1 .. ], e) where
218+ builder :: ([Int ], Exp ) -> ExpF (Either Exp ([Int ], Exp ))
219+ builder (path, exp ) =
220+ case exp of
221+ SStore (VarTagNode name vals) -> varTagNode SStore name vals
222+ SStore (ConstTagNode tag vals) -> constTagNode SStore tag vals
223+ SStore (Lit lit) -> literal SStore lit
224+ SReturn (VarTagNode name vals) -> varTagNode SReturn name vals
225+ SReturn (ConstTagNode tag vals) -> constTagNode SReturn tag vals
226+ SUpdate uname (VarTagNode tname vals) -> varTagNode (SUpdate uname) tname vals
227+ SUpdate uname (ConstTagNode tag vals) -> constTagNode (SUpdate uname) tag vals
228+ SUpdate uname (Lit lit) -> literal (SUpdate uname) lit
229+ SApp name vals -> appExp (if any isLit vals then SBlock else id ) name vals
230+
231+ Program defs -> let n = length defs
232+ in ProgramF $ zipWith (\ i d -> Right (nth i n path', d)) [1 .. ] defs
233+ EBind sexp lpat exp -> EBindF (Right (nth 0 2 path', sexp)) lpat (Right (nth 1 2 path', exp ))
234+ ECase val alts -> let n = length alts
235+ in ECaseF val $ zipWith (\ i a -> Right (nth i n path', a)) [0 .. ] alts
236+
237+ e -> fmap (\ e' -> Right (path', e')) $ project e -- (Right . (,) (tail path)) $ project e
238+
239+ where
240+ path' = tail path
241+ evars = map (\ i -> concat [" v." , show (head path), " ." , show i]) [1 .. ]
242+
243+ changeSimpleVals :: [Name ] -> [SimpleVal ] -> ([SimpleVal ], [(Name , Val )])
244+ changeSimpleVals newVars svals = second catMaybes . unzip $ zipWith changeVal svals newVars
245+ where
246+ changeVal (Lit lit) v = (Var v, Just (v, Lit lit))
247+ changeVal (Var v) _ = (Var v, Nothing )
248+ changeVal (ValTag g) v = (Var v, Just (v, ValTag g)) -- constTagNode only
249+ changeVal bad _ = error $ unwords [" registerIntroduction changeSimpleVals: invalid simple literal:" , show bad]
250+
251+ literal context lit =
252+ fmap Left . project $ EBind (SReturn (Lit lit)) (Var (evars !! 0 )) (context (Var $ evars !! 0 ))
253+
254+ introduction block context vals =
255+ let (vals', newVars) = changeSimpleVals evars vals
256+ in fmap Left . project . block $ foldr
257+ (\ (name, lit) -> EBind (SReturn lit) (Var name))
258+ (context (fst <$> listToMaybe newVars) vals') -- Tag is always first and stand for constTagNode only
259+ newVars
260+
261+ appExp block name = introduction block (const $ SApp name)
262+ varTagNode context name = introduction id (const $ context . VarTagNode name)
263+ constTagNode context tag vals =
264+ introduction SBlock
265+ (\ (Just t) vs -> context $ VarTagNode t (tail vs))
266+ ((ValTag tag): vals)
267+
268+
211269
212270-- Work In Progress
213271type VariablePath = [String ]
0 commit comments