Mercurial > urweb
view src/elab_util.sml @ 8:a455a9f85cc3
Parsing basic expressions
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sat, 26 Jan 2008 17:10:26 -0500 |
parents | 38bf996e1c2e |
children | 14b533dbe6cc |
line wrap: on
line source
(* Copyright (c) 2008, Adam Chlipala * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - The names of contributors may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *) structure ElabUtil :> ELAB_UTIL = struct open Elab structure S = Search structure Kind = struct fun mapfold f = let fun mfk k acc = S.bindP (mfk' k acc, f) and mfk' (kAll as (k, loc)) = case k of KType => S.return2 kAll | KArrow (k1, k2) => S.bind2 (mfk k1, fn k1' => S.map2 (mfk k2, fn k2' => (KArrow (k1', k2'), loc))) | KName => S.return2 kAll | KRecord k => S.map2 (mfk k, fn k' => (KRecord k', loc)) | KError => S.return2 kAll | KUnif (_, ref (SOME k)) => mfk' k | KUnif _ => S.return2 kAll in mfk end fun exists f k = case mapfold (fn k => fn () => if f k then S.Return () else S.Continue (k, ())) k () of S.Return _ => true | S.Continue _ => false end structure Con = struct fun mapfold {kind = fk, con = fc} = let val mfk = Kind.mapfold fk fun mfc c acc = S.bindP (mfc' c acc, fc) and mfc' (cAll as (c, loc)) = case c of TFun (c1, c2) => S.bind2 (mfc c1, fn c1' => S.map2 (mfc c2, fn c2' => (TFun (c1', c2'), loc))) | TCFun (e, x, k, c) => S.bind2 (mfk k, fn k' => S.map2 (mfc c, fn c' => (TCFun (e, x, k', c'), loc))) | TRecord c => S.map2 (mfc c, fn c' => (TRecord c', loc)) | CRel _ => S.return2 cAll | CNamed _ => S.return2 cAll | CApp (c1, c2) => S.bind2 (mfc c1, fn c1' => S.map2 (mfc c2, fn c2' => (CApp (c1', c2'), loc))) | CAbs (x, k, c) => S.bind2 (mfk k, fn k' => S.map2 (mfc c, fn c' => (CAbs (x, k', c'), loc))) | CName _ => S.return2 cAll | CRecord (k, xcs) => S.bind2 (mfk k, fn k' => S.map2 (ListUtil.mapfold (fn (x, c) => S.bind2 (mfc x, fn x' => S.map2 (mfc c, fn c' => (x', c')))) xcs, fn xcs' => (CRecord (k', xcs'), loc))) | CConcat (c1, c2) => S.bind2 (mfc c1, fn c1' => S.map2 (mfc c2, fn c2' => (CConcat (c1', c2'), loc))) | CError => S.return2 cAll | CUnif (_, _, ref (SOME c)) => mfc' c | CUnif _ => S.return2 cAll in mfc end fun exists {kind, con} k = case mapfold {kind = fn k => fn () => if kind k then S.Return () else S.Continue (k, ()), con = fn c => fn () => if con c then S.Return () else S.Continue (c, ())} k () of S.Return _ => true | S.Continue _ => false end structure E = ElabEnv fun declBinds env (d, _) = case d of DCon (x, n, k, _) => E.pushCNamedAs env x n k end