@@ -280,6 +280,81 @@ elabClause info fc (PWith fname lhs_in withs wval_in withblock)
280280 PApp fc (PRef fc' wname) (map (pexp . (PRef fc')) ns ++ [pexp w])
281281 updateLHS n wname mvars ns tm w = fail $ "Not implemented " ++ show tm
282282
283+elabClass :: ElabInfo -> SyntaxInfo ->
284+ FC -> Name -> [(Name, PTerm)] -> [PDecl] -> Idris ()
285+elabClass info syn fc tn ps ds
286+ = do let cn = UN ["instance" ++ show tn] -- MN 0 ("instance" ++ show tn)
287+ let tty = pibind ps PSet
288+ let constraint = PApp fc (PRef fc tn)
289+ (map (pexp . PRef fc) (map fst ps))
290+ -- build data declaration
291+ ims <- mapM tdecl ds
292+ let (methods, imethods) = unzip ims
293+ let cty = impbind ps $ pibind methods constraint
294+ let cons = [(cn, cty, fc)]
295+ let ddecl = PData syn fc (PDatadecl tn tty cons)
296+ elabDecl info ddecl
297+ -- for each method, build a top level function
298+ fns <- mapM (tfun cn constraint (map fst imethods)) imethods
299+ mapM_ (elabDecl info) (concat fns)
300+ i <- get
301+ put (i { idris_classes = addDef tn (map fst methods) (idris_classes i) })
302+ where
303+ pibind [] x = x
304+ pibind ((n, ty): ns) x = PPi expl n ty (pibind ns x)
305+ impbind [] x = x
306+ impbind ((n, ty): ns) x = PPi impl n ty (impbind ns x)
307+
308+ tdecl (PTy syn _ n t) = do t' <- implicit syn n t
309+ return ( (n, (toExp (map fst ps) Exp t')),
310+ (n, (toExp (map fst ps) Imp t')) )
311+ tdecl (PClauses _ _ _) = fail "No default definitions allowed yet"
312+ tdecl _ = fail "Not allowed in a class declaration"
313+
314+ tfun cn c all (m, ty)
315+ = do let ty' = insertConstraint c ty
316+ let mnames = take (length all) $ map (\x -> MN x "meth") [0..]
317+ let capp = PApp fc (PRef fc cn) (map (pexp . PRef fc) mnames)
318+ let margs = getMArgs ty
319+ let anames = map (\x -> MN x "arg") [0..]
320+ let lhs = PApp fc (PRef fc m) (pconst capp : lhsArgs margs anames)
321+ let rhs = PApp fc (getMeth mnames all m) (rhsArgs margs anames)
322+ iLOG (showImp True ty)
323+ iLOG (show (m, ty', capp, margs))
324+ iLOG (showImp True lhs ++ " = " ++ showImp True rhs)
325+ return [PTy syn fc m ty',
326+ PClauses fc m [PClause m lhs [] rhs []]]
327+
328+ getMArgs (PPi (Imp _ _) n ty sc) = False : getMArgs sc
329+ getMArgs (PPi (Exp _ _) n ty sc) = True : getMArgs sc
330+ getMArgs _ = []
331+
332+ getMeth (m:ms) (a:as) x | x == a = PRef fc m
333+ | otherwise = getMeth ms as x
334+
335+ lhsArgs (True : xs) (n : ns) = pexp (PRef fc n) : lhsArgs xs ns
336+ lhsArgs (False : xs) ns = lhsArgs xs ns
337+ lhsArgs [] _ = []
338+
339+ rhsArgs (True : xs) (n : ns) = pexp (PRef fc n) : rhsArgs xs ns
340+ rhsArgs (False : xs) ns = pexp Placeholder : rhsArgs xs ns
341+ rhsArgs [] _ = []
342+
343+ insertConstraint c (PPi p@(Imp _ _) n ty sc)
344+ = PPi p n ty (insertConstraint c sc)
345+ insertConstraint c sc = PPi constraint (MN 0 "c") c sc
346+
347+ -- make arguments explicit and don't bind class parameters
348+ toExp ns e (PPi (Imp l s) n ty sc)
349+ | n `elem` ns = toExp ns e sc
350+ | otherwise = PPi (e l s) n ty (toExp ns e sc)
351+ toExp ns e (PPi p n ty sc) = PPi p n ty (toExp ns e sc)
352+ toExp ns e sc = sc
353+
354+elabInstance :: ElabInfo -> SyntaxInfo ->
355+ FC -> Name -> PTerm -> [PDecl] -> Idris ()
356+elabInstance info syn fc n t ds = fail "Not implemented"
357+
283358pbinds (Bind n (PVar t) sc) = do attack; patbind n
284359 pbinds sc
285360pbinds tm = return ()
@@ -325,6 +400,12 @@ elabDecl' info (PParams f ns ps) = mapM_ (elabDecl' pinfo) ps
325400 newb = addAlist dsParams (inblock info) in
326401 info { params = newps,
327402 inblock = newb }
403+elabDecl' info (PClass s f n ps ds) = do iLOG $ "Elaborating class " ++ show n
404+ elabClass info s f n ps ds
405+elabDecl' info (PInstance s f n t ds) = do iLOG $ "Elaborating instance " ++ show n
406+ elabInstance info s f n t ds
407+
408+
328409-- elabDecl' info (PImport i) = loadModule i
329410
330411