@@ -97,7 +97,7 @@ elabVal info tm
9797 tclift $ recheck ctxt [] vtm
9898
9999elabClause :: ElabInfo -> FC -> PClause -> Idris (Term, Term)
100−elabClause info fc (PClause fname lhs rhs whereblock)
100+elabClause info fc (PClause fname lhs withs rhs whereblock)
101101 = do ctxt <- getContext
102102 -- Build the LHS as an "Infer", and pull out its type and
103103 -- pattern bindings
@@ -116,28 +116,19 @@ elabClause info fc (PClause fname lhs rhs whereblock)
116116 -- Now build the RHS, using the type of the LHS as the goal.
117117 logLvl 2 (showImp True rhs)
118118 ctxt <- getContext -- new context with where block added
119− ((rhs', defer), _) <- tclift $ elaborate ctxt (MN 0 "patRHS") clhsty
120− (do pbinds lhs_tm
121− (_, d) <- erun fc (build winfo False rhs)
122− psolve lhs_tm
123− tt <- get_term
124− return (tt, d))
119+ ((rhs', defer), _) <-
120+ tclift $ elaborate ctxt (MN 0 "patRHS") clhsty
121+ (do pbinds lhs_tm
122+ (_, d) <- erun fc (build winfo False rhs)
123+ psolve lhs_tm
124+ tt <- get_term
125+ return (tt, d))
125126 logLvl 2 $ "---> " ++ show rhs'
126127 when (not (null defer)) $ iLOG $ "DEFERRED " ++ show defer
127128 addDeferred defer
128129 (crhs, crhsty) <- tclift $ recheck ctxt [] rhs'
129130 return (clhs, crhs)
130131 where
131− pbinds (Bind n (PVar t) sc) = do attack; patbind n
132− pbinds sc
133− pbinds tm = return ()
134−
135− psolve (Bind n (PVar t) sc) = do solve; psolve sc
136− psolve tm = return ()
137−
138− pvars ist (Bind n (PVar t) sc) = (n, delab ist t) : pvars ist sc
139− pvars ist _ = []
140−
141132 pinfo ns ps i
142133 = let ds = concatMap declared ps
143134 newps = params info ++ ns
@@ -151,6 +142,103 @@ elabClause info fc (PClause fname lhs rhs whereblock)
151142 _ -> MN i (show n)) . l
152143 }
153144
145+elabClause info fc (PWith fname lhs withs wval withblock)
146+ = do ctxt <- getContext
147+ -- Build the LHS as an "Infer", and pull out its type and
148+ -- pattern bindings
149+ ((lhs', dlhs), _) <- tclift $ elaborate ctxt (MN 0 "patLHS") infP
150+ (erun fc (build info True (infTerm lhs)))
151+ let lhs_tm = getInferTerm lhs'
152+ let lhs_ty = getInferType lhs'
153+ let ret_ty = getRetTy lhs_ty
154+ logLvl 3 (show lhs_tm)
155+ (clhs, clhsty) <- tclift $ recheck ctxt [] lhs_tm
156+ logLvl 5 ("Checked " ++ show clhs)
157+ logLvl 5 ("Checking " ++ show wval)
158+ let bargs = getPBtys lhs_tm
159+ -- Elaborate wval in this context
160+ ((wval', defer), _) <-
161+ tclift $ elaborate ctxt (MN 0 "withRHS")
162+ (bindTyArgs PVTy bargs infP)
163+ (do pbinds lhs_tm
164+ -- TODO: may want where here - see winfo abpve
165+ (_', d) <- erun fc (build info False (infTerm wval))
166+ psolve lhs_tm
167+ tt <- get_term
168+ return (tt, d))
169+ addDeferred defer
170+ (cwval, cwvalty) <- tclift $ recheck ctxt [] (getInferTerm wval')
171+ logLvl 3 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
172+ windex <- getName
173+ -- build a type declaration for the new function:
174+ -- (ps : Xs) -> (withval : cwvalty) -> ret_ty
175+ let wtype = bindTyArgs Pi (bargs ++ [(MN 0 "warg", getRetTy cwvalty)]) ret_ty
176+ logLvl 3 ("New function type " ++ show wtype)
177+ let wname = MN windex (show fname)
178+ addDeferred [(wname, wtype)]
179+
180+ -- in the subdecls, lhs becomes:
181+ -- fname pats | wpat [rest]
182+ -- ==> fname' ps wpat [rest]
183+ wb <- mapM (mkAuxC wname (map fst bargs)) withblock
184+ logLvl 5 ("with block " ++ show wb)
185+ mapM_ (elabDecl info) wb
186+
187+ -- rhs becomes: fname' ps wval
188+ let rhs = PApp fc (PRef fc wname) (map (PExp . (PRef fc) . fst) bargs ++
189+ [PExp wval])
190+ logLvl 3 ("New RHS " ++ show rhs)
191+ ctxt <- getContext -- New context with block added
192+ ((rhs', defer), _) <-
193+ tclift $ elaborate ctxt (MN 0 "wpatRHS") clhsty
194+ (do pbinds lhs_tm
195+ (_, d) <- erun fc (build info False rhs)
196+ psolve lhs_tm
197+ tt <- get_term
198+ return (tt, d))
199+ addDeferred defer
200+ (crhs, crhsty) <- tclift $ recheck ctxt [] rhs'
201+ return (clhs, crhs)
202+ where
203+ mkAuxC wname ns (PClauses fc n cs)
204+ | n == fname = do cs' <- mapM (mkAux wname ns) cs
205+ return $ PClauses fc wname cs'
206+ | otherwise = fail $ "with clause uses wrong function name " ++ show n
207+ mkAuxC wname ns d = return $ d
208+
209+ mkAux wname ns (PClause n tm (w:ws) rhs wheres)
210+ = do lhs <- updateLHS n wname ns tm w
211+ return $ PClause wname lhs ws rhs wheres
212+ mkAux wname ns (PWith n tm (w:ws) wval wheres)
213+ = do lhs <- updateLHS n wname ns tm w
214+ return $ PWith wname lhs ws wval wheres
215+
216+ updateLHS n wname ns (PApp fc (PRef fc' n') args) w
217+ = return $ PApp fc (PRef fc' wname)
218+ (map (PExp . (PRef fc')) ns ++ [PExp w])
219+ updateLHS n wname ns tm w = fail $ "Not implemented " ++ show tm
220+
221+pbinds (Bind n (PVar t) sc) = do attack; patbind n
222+ pbinds sc
223+pbinds tm = return ()
224+
225+pbty (Bind n (PVar t) sc) tm = Bind n (PVTy t) (pbty sc tm)
226+pbty _ tm = tm
227+
228+getPBtys (Bind n (PVar t) sc) = (n, t) : getPBtys sc
229+getPBtys _ = []
230+
231+getRetTy (Bind n (PVar _) sc) = getRetTy sc
232+getRetTy (Bind n (PVTy _) sc) = getRetTy sc
233+getRetTy (Bind n (Pi _) sc) = getRetTy sc
234+getRetTy sc = sc
235+
236+psolve (Bind n (PVar t) sc) = do solve; psolve sc
237+psolve tm = return ()
238+
239+pvars ist (Bind n (PVar t) sc) = (n, delab ist t) : pvars ist sc
240+pvars ist _ = []
241+
154242-- TODO: Also build a 'binary' version of each declaration for fast reloading
155243
156244elabDecl :: ElabInfo -> PDecl -> Idris ()
@@ -215,8 +303,8 @@ elab info pattern tm = do elab' tm
215303 elab' (PPair fc l r) = try (elab' (PApp fc (PRef fc pairTy)
216304 [PExp l,PExp r]))
217305 (elab' (PApp fc (PRef fc pairCon)
218− [PImp (MN 0 "a") Placeholder,
219− PImp (MN 0 "a") Placeholder,
306+ [PImp (MN 0 "A") Placeholder,
307+ PImp (MN 0 "B") Placeholder,
220308 PExp l, PExp r]))
221309 elab' (PRef fc n) | pattern && not (inparamBlock n)
222310 = erun fc $