module Lookup where import Vtslib import Core_datatype {- (******************************************************************************) (* memoised lookup table of signatures. *) (******************************************************************************) -} {- (******************************************************************************) (* A lookup table is an list of association lists. *) (* Each element of an association list consists of *) (* string - The name of a symbol (or constructor) *) (* int * bool - The j index of a symbol, or *) (* int * int * int list - The j,k indexes for of a constructor *) (* (int * opr) option - The precedence and type of operator *) (* The boolean in the symbol part indicates wheather the symbol is *) (* accessabe by a rec expression. *) (* in *) (******************************************************************************) -} type Index = Sum (Int , Bool) ( Int , Int , [(Int , Int)] ) type Entry = [(String , Option (Index , (Int , String) ))] type Lookup_table = [Entry] {- local (******************************************************************************) (* Turn a name into a lookup table *) (******************************************************************************) fun get_nms jf (Name s) = [(s, (jf, NONE))] | get_nms jf (Operator (s,p,opr)) = [(s,(jf,SOME (p,opr)))] (******************************************************************************) (* Turn a list of names and a list of list of terms (taken from a *) (* datatype declaration) and turn them into a lookup table *) (******************************************************************************) and get_nmsL jf k [] [] = [] | get_nmsL jf k (nm :: nmL) (tmL :: tmLL) = get_nms (inr (jf,k,(length tmL, rec_pars 0 tmL))) nm @ get_nmsL jf (k+1) nmL tmLL | get_nmsL jf k _ _ = [] and rec_pars _ [] = [] | rec_pars i (tm :: tmL) = (if is_00_sm tm then [i] else []) @ rec_pars (i+1) tmL and is_00_sm (Sym (0,0,_,_)) = true | is_00_sm _ = false (******************************************************************************) (* Return the lookup table for a declaration *) (******************************************************************************) fun get_dec_nms rec_flag j (Symbol_dec (_,attL)) = (case get_att Name_Style attL of SOME (Symbol_Name nm) => (get_nms (inl (j,rec_flag)) nm, j) | _ => ([], j)) | get_dec_nms rec_flag j (Axiom_dec (_,attL)) = (case get_att Name_Style attL of SOME (Symbol_Name nm) => (get_nms (inl (j,rec_flag)) nm, j) | _ => ([], j)) | get_dec_nms rec_flag j (Def (_,_,attL)) = (case get_att Name_Style attL of SOME (Symbol_Name nm) => (get_nms (inl (j,rec_flag)) nm, j) | _ => ([], j)) | get_dec_nms rec_flag j (Data (_,tmLL,attL)) = (case get_att Name_Style attL of SOME (Datatype_Name (nm::nmL)) => (get_nms (inr (j,0,(0,[]))) nm @ get_nmsL j 1 nmL tmLL, j) | _ => ([], j)) | get_dec_nms rec_flag j (Decpair (dc1,dc2,_)) = let val (nms1,j1) = get_dec_nms rec_flag (j+1) dc1 val (nms2,j2) = get_dec_nms rec_flag (j1+1) dc2 in (nms1@nms2, j2) end (******************************************************************************) (* Return the lookup table for a pass1 decaration *) (******************************************************************************) fun get_pdec_nms rec_flag j (P1_Dec (nmL, _)) = get_p1_nmsL rec_flag j nmL | get_pdec_nms rec_flag j (P1_Def (P1_Lhs (_,nm,_),_)) = get_p1_nmsL rec_flag j [nm] | get_pdec_nms rec_flag j (P1_Define (nm,_,_)) = get_p1_nmsL rec_flag j [nm] | get_pdec_nms rec_flag j (P1_Data (P1_Lhs (_,nm,_), conL,_)) = (get_nms (inr (j,0,(0,[]))) nm @ get_con_nms j 1 conL, j) | get_pdec_nms rec_flag j (P1_Decp (dc1,dc2)) = let val (nms1,j1) = get_pdec_nms rec_flag (j+1) dc1 val (nms2,j2) = get_pdec_nms rec_flag (j1+1) dc2 in (nms1@nms2, j2) end | get_pdec_nms rec_flag j (P1_BDec dc) = get_p1bdc rec_flag j dc | get_pdec_nms rec_flag j (P1_Database_dec dc) = let val (dc1, _) = internal_Dec dc in get_dec_nms rec_flag j dc1 end (******************************************************************************) (* Return the lookup table for a pass1 binding declaration *) (******************************************************************************) and get_p1bdc rec_flag j (P1_Bdec (nmL, _)) = get_p1_nmsL rec_flag j nmL | get_p1bdc rec_flag j (P1_Bdecp (dc1,dc2)) = let val (nms1, j1) = get_p1bdc rec_flag (j+1) dc1 val (nms2, j2) = get_p1bdc rec_flag (j1+1) dc2 in (nms1@nms2, j2) end (******************************************************************************) (* Return the llokup table for a list of names, that representing *) (* sequence of paired declarations *) (******************************************************************************) and get_p1_nmsL rec_flag j [nm] = (get_nms (inl (j,rec_flag)) nm, j) | get_p1_nmsL rec_flag j (nm :: nmL) = let val nms1 = get_nms (inl (j+1,rec_flag)) nm val (nms2,j1) = get_p1_nmsL rec_flag (j+2) nmL in (nms1@nms2, j1) end | get_p1_nmsL rec_flag j [] = ([], j) (******************************************************************************) (* Return the lookup table for the constuctors of a pass1 datatype *) (* declaration *) (******************************************************************************) and get_con_nms j k [] = [] | get_con_nms j k (P1_Rhs (nm,tmL) :: nmL) = get_nms (inr (j,k,(length tmL,get_pvars 0 tmL))) nm @ get_con_nms j (k+1) nmL and get_pvars _ [] = [] | get_pvars i (tm :: tmL) = (if is_00_psm tm then [i] else []) @ get_pvars (i+1) tmL and is_00_psm (P1_Sym (0,0,_)) = true | is_00_psm _ = false in (* local *) (******************************************************************************) (* Take a signature and return its lookup table *) (******************************************************************************) fun create_lookup_table (sg : sgn) : lookup_table = case sg of Empty _ => [] | Extend (dc,sg,_) => extend_lookup_table true dc (create_lookup_table sg) | Combine (sg1,sg2,_,_,_) => let val tbl1 = create_lookup_table sg2 and tbl2 = create_lookup_table sg1 in [] :: tbl1 @ tbl2 end | Share (sg,_,_,_,_,_) => [] :: create_lookup_table sg (******************************************************************************) (* Extend a lookup table with a new declaration *) (******************************************************************************) and extend_lookup_table rec_flag dc tbl : lookup_table = let val (nms, _) = get_dec_nms rec_flag 0 dc in nms :: tbl end fun combine_lookup_table tbl1 tbl2 : lookup_table = tbl2 @ [[]] @ tbl1 fun share_lookup_table tbl (i : int) (j : int) : lookup_table = [] :: tbl fun create_tbl (sg : pass1_sgn) : lookup_table = case sg of P1_Empty => [] | P1_Signature (dc) => extend_tbl true dc [] | P1_Extend (dc,sg) => extend_tbl true dc (create_tbl sg) | P1_Combine (sg1,sg2) => let val tbl1 = create_tbl sg2 and tbl2 = create_tbl sg1 in [] :: tbl1 @ tbl2 end | P1_Sharing (sg,_) => [] :: create_tbl sg | P1_Database_sgn sg => create_lookup_table (internal_Sgn sg) | P1_Named_sgn (_,sg) => create_tbl sg | P1_plus_plus (sg1,sg2) => let val tbl1 = create_tbl sg2 and tbl2 = create_tbl sg1 in [] :: tbl1 @ tbl2 end and extend_tbl rec_flag pdc tbl : lookup_table = let val (nms,_) = get_pdec_nms rec_flag 0 pdc in nms :: tbl end (******************************************************************************) (* Lookup a string in the lookup table and return the pass1 symbol (or *) (* constructor) and its optional operator status *) (******************************************************************************) fun lookup_name (tbl : lookup_table) (str : string) = let fun lookup i [] = NONE | lookup i (entry :: tbl) = case assoc str entry of SOME (inl (j,true),opr_op) => SOME (P1_Sym (i,j,true), opr_op) | SOME (inr (j,k,_),opr_op) => SOME (P1_Const (i,j,k,true), opr_op) | _ => lookup (i+1) tbl in lookup 0 tbl end fun lookup_rec_name (tbl : lookup_table) (str : string) = let fun lookup i [] = NONE | lookup i (entry :: tbl) = case assoc str entry of SOME (inl (j, false),opr_op) => SOME (P1_Sym (i,j,true), opr_op) | _ => lookup (i+1) tbl in lookup 0 tbl end exception BadIndex fun lookup_sm_index (tbl : lookup_table) (i,j) = let val entry = tbl !! i fun is_sm (_,(inl (j',_),_)) = j = j' | is_sm _ = false in case filter is_sm entry of ((s,(inl (_,f),NONE)) :: _) => SOME (s, f, NONE) | ( (s,(inl (_,f),SOME (i, opr))) :: _) => SOME (s, f, SOME (i,opr)) | _ => NONE end fun lookup_cn_index (tbl : lookup_table) (i,j,k) = let val entry = tbl !! i fun is_sm (_,(inr (j',k',_),_)) = (j',k') = (j,k) | is_sm _ = false in case filter is_sm entry of ( (s,(inr (_,_,_),SOME (i, opr))) :: _) => SOME (s, SOME (i,opr)) | ((s,(inr (_,_,_),_)) :: _) => SOME (s, NONE) | _ => NONE end end (* of local *) fun rec_parameters (tbl : lookup_table) (i,j,k) = let val entry = tbl !! i fun is_sm (_,(inr (j',k',_),_)) = (j',k') = (j,k) | is_sm _ = false in case filter is_sm entry of ((_,(inr (_,_,iL),_)) :: _) => iL | _ => raise BadIndex end fun operators ([] : lookup_table) = [] | operators (ent :: tbl) = foldr (curry op@) (operators tbl) (map get_ops ent) and get_ops (id, (inr _, SOME (i, opr))) = [(id, Operator (id,i,opr))] | get_ops (id, (inr _, NONE)) = [(id, Name id)] | get_ops _ = [] end -}