(* JungTaek Kim Copyright(c) 2000-2004 KAIST/SNU Research On Program Analysis System (National Creative Research Initiative Center 1998-2003) http://ropas.snu.ac.kr/n All rights reserved. This file is distributed under the terms of an Open Source License. *) (* 'a can have any information needed. For example, parser give it the syntax location information. *) module Ast_generator (Idinfo : sig type varidinfo type tyidinfo type conidinfo type stridinfo type sigidinfo type fctidinfo type labelinfo type tyvarinfo val print_varidinfo : varidinfo -> unit val print_tyidinfo : tyidinfo -> unit val print_conidinfo : conidinfo -> unit val print_stridinfo : stridinfo -> unit val print_sigidinfo : sigidinfo -> unit val print_fctidinfo : fctidinfo -> unit val print_labelinfo : labelinfo -> unit val print_tyvarinfo : tyvarinfo -> unit end) (Syninfo : sig type info val print : info -> unit end) = struct open Idinfo open Syninfo type varid = varidinfo * info type tyid = tyidinfo * info type conid = conidinfo * info type strid = stridinfo * info type sigid = sigidinfo * info type fctid = fctidinfo * info type label = labelinfo * info (* EQ represents eqtype tyvars and NEQ represents others *) type tyvar = tyvarinfo * info type varlongid = strid list * varid * info type tylongid = strid list * tyid * info type conlongid = strid list * conid * info type strlongid = strid list * strid * info type ty = VarTy of tyvar * info | ConstTy of ty list * tylongid * info | RecordTy of labty list * info | TupleTy of ty list * info | FunTy of ty * ty * info and labty = label * ty * info (* - Alphanumeric identifiers and 'op' symbols are represented as VarPat *) type pat = WildPat of info | UnitPat of info | IntPat of int * info | StringPat of string * info | CharPat of char * info | VarPat of varid * info | ConPat of conlongid * info | AppPat of conlongid * pat * info | RecordPat of labpat list * info | SubRecordPat of labpat list * info | RefPat of pat * info | ConstraintPat of pat * ty * info | AsPat of varid * ty option * pat * info | TuplePat of pat list * info | ListPat of pat list * info | ArrayPat of pat list * info | OrPat of pat list * info and labpat = label * pat * info (* - Alphanumeric identifiers and 'op' symbols are represented as VarExp *) type exp = UnitExp of info | IntExp of int * info | RealExp of string * info | StringExp of string * info | CharExp of char * info | VarExp of varlongid * info | ConExp of conlongid * info | AppExp of exp * exp * info | RecordExp of labexp list * info | RecordFieldExp of exp * label * info | ArrayFieldExp of exp * exp * info | UpdateArrayExp of exp * exp * exp * info | SubstRecordExp of exp * label * exp * info | TupleExp of exp list * info | ListExp of exp list * info | ArrayExp of exp list * info | LetExp of dec * exp * info | HandleExp of exp * rule list * info | RaiseExp of exp * info | FnExp of fnrule list * info | AssignExp of exp * exp * info | RefExp of exp * info | DeRefExp of exp * info | SeqExp of exp list * info | CaseExp of exp * rule list * info | IfExp of exp * exp * exp * info | WhileExp of exp * exp * info | ForExp of varid * exp * exp * exp * exp * info | ConstraintExp of exp * ty * info and labexp = label * exp * info and fnrule = pat list * exp * info and rule = pat * exp * info and dec = ValDec of tyvar list * valbind list * info | RecValDec of tyvar list * valbind list * info | FunDec of tyvar list * funbind list * info | TypeDec of typebind list * info | ExceptionDec of exnbind list * info | LocalDec of dec * dec * info | OpenDec of strlongid list * info | SeqDec of dec list * info and valbind = pat * exp * info and funbind = body list * info and body = varid * pat list * exp * info and typebind = TypeBind of tyvar list * tyid * ty * info | DataBind of tyvar list * tyid * con list * info and con = conid * ty option * info and exnbind = con and strdec = SimpleDec of dec * info | StrDec of strbind list * info | SeqStrDec of strdec list * info and strbind = strid * (sigexp option) * strexp * info and fctarg = strid * sigexp * info and fctdec = fctid * fctarg list * sigexp option * strexp * info and sigdec = sigbind list * info and sigbind = sigid * sigexp * info and strexp = VarStr of strlongid * info | StrStr of strdec * info | SigStr of strexp * sigexp * info | FctAppStr of fctid * strexp list * info and sigexp = VarSig of sigid * info | SigSig of spec * info | ConstraintSig of sigexp * where * info and spec = ValSpec of valdesc list * info | TypeSpec of typedesc list * info | ExnSpec of exndesc list * info | IncludeSpec of sigexp * info | StrSpec of strdesc list * info | SeqSpec of spec list * info and valdesc = varid * ty * info and typedesc = TypeDesc of tyvar list * tyid * info | TypeBindDesc of tyvar list * tyid * ty * info | DataDesc of tyvar list * tyid * con list * info and exndesc = con and strdesc = strid * sigexp * info and where = longtypebind list * info and longtypebind = tyvar list * tylongid * ty * info and topdec = Sig of sigdec * info | Fct of fctdec * info | Str of strdec * info | SeqTopDec of topdec list * info (***** poisson *****) and toplevel = TopDef of topdec | TopExp of exp list * info | TopDir of string * dirarg and dirarg = ArgNone | ArgString of string | ArgLident of varlongid | ArgInt of int (*******************) (* open Format let enable_syn_info_print = ref false let print_loc l = if !enable_syn_info_print then Syninfo.print l else () let print_list f del l = match l with [] -> (); | hd::tl -> begin let print_rest t = del(); f t in f hd; List.iter print_rest tl end let print_tyvar (s,loc) = printf "'"; print_tyvarinfo s; print_loc loc let print_tyvars l = match l with [] -> () | [ty] -> print_tyvar ty; printf " " | l -> printf "("; print_list print_tyvar (fun () -> printf ", ") l; printf ") " let print_varid (v,loc) = print_varidinfo v; print_loc loc let print_tyid (v,loc) = print_tyidinfo v; print_loc loc let print_conid (v,loc) = print_conidinfo v; print_loc loc let print_strid (v,loc) = print_stridinfo v; print_loc loc let print_sigid (v,loc) = print_sigidinfo v; print_loc loc let print_fctid (v,loc) = print_fctidinfo v; print_loc loc let print_label (v,loc) = print_labelinfo v; print_loc loc let print_varlongid (l,v,loc) = (match l with [] -> print_varid v | l -> print_list print_strid (fun () -> printf ".") l; printf "."; print_varid v); print_loc loc let print_tylongid (l,v,loc) = (match l with [] -> print_tyid v | l -> print_list print_strid (fun () -> printf ".") l; printf "."; print_tyid v); print_loc loc let print_conlongid (l,v,loc) = (match l with [] -> print_conid v | l -> print_list print_strid (fun () -> printf ".") l; printf "."; print_conid v); print_loc loc let print_strlongid (l,v,loc) = (match l with [] -> print_strid v | l -> print_list print_strid (fun () -> printf ".") l; printf "."; print_strid v); print_loc loc let rec print_ty t = match t with VarTy (tyv,loc) -> print_tyvar tyv; print_loc loc | ConstTy ([], lid,loc) -> print_tylongid lid; print_loc loc | ConstTy ([hd], lid,loc) -> print_ty hd; printf " "; print_tylongid lid; print_loc loc | ConstTy (l, lid,loc) -> printf "("; print_list print_ty (fun () -> printf ", ") l; printf ") "; print_tylongid lid; print_loc loc | RecordTy ([],loc) -> prerr_string "ty error\n"; print_loc loc | RecordTy (l,loc) -> begin let print_tyrow (l,t,loc) = print_label l; print_string " : "; print_ty t; print_loc loc in printf "["; print_list print_tyrow (fun () -> printf ", ") l; printf "]"; print_loc loc end | TupleTy ([],loc) -> prerr_string "ty error\n"; print_loc loc | TupleTy (l,loc) -> printf "("; print_list print_ty (fun () -> printf " * ") l; printf ")"; print_loc loc | FunTy (t1, t2,loc) -> printf "("; print_ty t1; print_string " -> "; print_ty t2; printf ")"; print_loc loc let print_con (id, tyop,loc) = print_conid id; (match tyop with None -> () | Some(ty) -> printf " of "; print_ty ty); print_loc loc let rec print_patrow (l, p,loc) = print_label l; printf " = "; print_pat p; print_loc loc and print_pat p = match p with WildPat(loc) -> printf "_"; print_loc loc | UnitPat(loc) -> printf "()"; print_loc loc | IntPat (i,loc) -> print_int i; print_loc loc | StringPat (s,loc) -> printf "\""; print_string (String.escaped s); printf "\""; print_loc loc | CharPat (c,loc) -> printf "'"; print_string (Char.escaped c); printf "'"; print_loc loc | RecordPat (l,loc) -> printf "{"; print_list print_patrow (fun () -> printf ", ") l; printf "}"; print_loc loc | SubRecordPat (l,loc) -> printf "{"; print_list print_patrow (fun () -> printf ", ") l; printf ", ..."; printf "}"; print_loc loc | RefPat (p,loc) -> printf "(ref "; print_pat p; printf ")" ; print_loc loc | VarPat (l,loc) -> print_varid l; print_loc loc | ConPat (l,loc) -> print_conlongid l; print_loc loc | AppPat (l, p,loc) -> printf "("; print_conlongid l; printf " "; print_pat p; printf ")"; print_loc loc | ConstraintPat (p, t,loc) -> printf "("; print_pat p; printf " : "; print_ty t; printf ")"; print_loc loc | AsPat (id, top, p,loc) -> printf "("; print_varid id; begin match top with None -> () | Some (t) -> printf " : "; print_ty t end; printf " as "; print_pat p; printf ")"; print_loc loc | TuplePat (l,loc) -> printf "("; print_list print_pat (fun () -> printf ", ") l; printf ")"; print_loc loc | ListPat ([],loc) -> printf "[]"; print_loc loc | ListPat (l,loc) -> printf "["; print_list print_pat (fun () -> printf ", ") l; printf "]"; print_loc loc | ArrayPat (l,loc) -> printf "[|"; print_list print_pat (fun () -> printf ", ") l; printf "|]"; print_loc loc | OrPat (l,loc) -> print_list print_pat (fun () -> printf " | ") l; print_loc loc let rec print_exprow (l, e,loc) = print_label l; printf " = "; print_exp e; print_loc loc and print_rule (p,e,loc) = print_pat p; printf " => "; print_exp e; print_loc loc and print_fnrule (l,e,loc) = print_list print_pat (fun () -> printf " ") l; printf " => "; print_exp e; print_loc loc and print_exp p = match p with UnitExp (loc) -> printf "()"; print_loc loc | IntExp (i,loc) -> print_int i; print_loc loc | RealExp (f,loc) -> print_string f; print_loc loc | StringExp (s,loc) -> printf "\""; print_string (String.escaped s); printf "\""; print_loc loc | CharExp (c,loc) -> printf "'"; print_string (Char.escaped c); printf "'"; print_loc loc | VarExp (l,loc) -> print_varlongid l; print_loc loc | ConExp (l,loc) -> print_conlongid l; print_loc loc | AppExp (e, a,loc) -> printf "("; print_exp e; printf " "; print_exp a; printf ")"; print_loc loc | RecordExp (l,loc) -> printf "@[<1>{"; print_list print_exprow (fun () -> printf ",@ ") l; printf "@]}"; print_loc loc | RecordFieldExp (e, l,loc) -> printf "("; print_exp e; printf "."; print_label l; printf ")"; print_loc loc | ArrayFieldExp (e, e',loc) -> printf "("; print_exp e; printf ".["; print_exp e'; printf "])"; print_loc loc | UpdateArrayExp (e, e', e'',loc) -> printf "("; print_exp e; printf ".["; print_exp e'; printf "]"; printf " <- "; print_exp e''; printf ")"; print_loc loc | SubstRecordExp (e, l, e',loc) -> printf "("; print_exp e; printf "{"; print_exp e'; printf "<-"; print_label l; printf "})"; print_loc loc | TupleExp (l,loc) -> printf "@[<1>("; print_list print_exp (fun () -> printf ",@ ") l; printf "@])"; print_loc loc | ListExp ([],loc) -> printf "[]"; print_loc loc | ListExp (l,loc) -> printf "@[<1>["; print_list print_exp (fun () -> printf ",@ ") l; printf "@]]"; print_loc loc | ArrayExp (l,loc) -> printf "@[<1>[|"; print_list print_exp (fun () -> printf ",@ ") l; printf "@]|]"; print_loc loc | LetExp (d, e,loc) -> printf "@[@[<2>let@\n"; print_dec d; printf "@]@\n@[<2>in"; print_exp e; printf "@]@\nend@]"; print_loc loc | HandleExp (e, l,loc) -> printf "("; print_exp e; printf " @[<2>handle "; print_list print_rule (fun () -> printf "@\n| ") l; printf "@])"; print_loc loc | RaiseExp (e,loc) -> printf "@[<3>(raise@ "; print_exp e; printf "@])"; print_loc loc | FnExp (l,loc) -> printf "(@[<2> fn "; print_list print_fnrule (fun () -> printf "@\n| ") l; printf "@])"; print_loc loc | AssignExp (e, e',loc) -> printf "@[<3>("; print_exp e; printf " :=@ "; print_exp e'; printf "@])"; print_loc loc | RefExp (e,loc) -> printf "@[<3>(ref@ "; print_exp e; printf "@])"; print_loc loc | DeRefExp (e,loc) -> printf "(! "; print_exp e; printf ")"; print_loc loc | SeqExp (l,loc) -> printf "@[<1>("; print_list print_exp (fun () -> printf ";@ ") l; printf "@])"; print_loc loc | CaseExp (e, l,loc) -> printf "(@[<2>case "; print_exp e; printf " of "; print_list print_rule (fun () -> printf "@\n| ") l; printf "@])"; print_loc loc | IfExp (e, e', e'',loc) -> printf "(@[if "; print_exp e; printf "@\nthen "; print_exp e'; printf "@\nelse "; print_exp e''; printf "@])" ; print_loc loc | WhileExp (e, e',loc) -> printf "@[while "; print_exp e; printf "@\ndo @["; print_exp e'; printf "@]@\nend@]" ; print_loc loc | ForExp (id, e, e', e'', e''',loc) -> printf "@[for "; print_varid id; printf " = "; print_exp e; printf "; "; print_exp e'; printf "; "; print_exp e''; printf "@\ndo @["; print_exp e'''; printf "@]@\nend@]"; print_loc loc | ConstraintExp (e, t,loc) -> printf "@[<1>("; print_exp e; printf " : "; print_ty t; printf "@])"; print_loc loc and print_valbind (p, e,loc) = printf "@[<3>"; print_pat p; printf " =@ "; print_exp e; printf "@]"; print_loc loc and print_funbind (l,loc) = begin let print_body (id,pl,e,loc) = print_varid id; printf " "; print_list print_pat (fun () -> printf " ") pl; printf " = "; print_exp e; print_loc loc in printf "@[<2>"; print_list print_body (fun () -> printf "@]@ @[<2>| ") l; printf "@]" end; print_loc loc and print_typebind p = match p with TypeBind (tyvs, id, ty,loc) -> print_tyvars tyvs; print_tyid id; printf " = "; print_ty ty; print_loc loc | DataBind (tyvs, id, cl,loc) -> print_tyvars tyvs; print_tyid id; printf " = "; printf "@["; print_list print_con (fun () -> printf " |@ ") cl; printf "@]"; print_loc loc and print_exnbind (c) = print_con c and print_dec p = match p with ValDec (b, tyvs, l,loc) -> printf "val "; print_tyvars tyvs; print_list print_valbind (fun () -> printf "@\nand ") l; print_loc loc | FunDec (l,loc) -> printf "@[<2>fun "; print_list print_funbind (fun () -> printf "@]@\n@[<2>and ") l; printf "@]"; print_loc loc | TypeDec (l,loc) -> printf "type "; print_list print_typebind (fun () -> printf "@\nand ") l; print_loc loc | AbstypeDec (l, d,loc) -> printf "@[<2>abstype@\n"; print_list print_typebind (fun () -> printf "@\nand ") l; printf "@]@\n@[<2>with@\n"; print_dec d; printf "@]@\nend"; print_loc loc | ExceptionDec (l,loc) -> printf "@[<2>exception "; print_list print_exnbind (fun () -> printf "@ and ") l; printf "@]"; print_loc loc | LocalDec (d, d',loc) -> printf "@[<2>local@\n"; print_dec d; printf "@]@\n@[<2>in"; print_dec d'; printf "@]@\nend"; print_loc loc | OpenDec (l,loc) -> printf "open "; print_list print_strlongid (fun () -> printf " ") l; print_loc loc | SeqDec (l,loc) -> print_list print_dec (fun () -> printf ";@ ") l; print_loc loc let print_longtypebind (tyvs, l, ty,loc) = print_tyvars tyvs; printf " "; print_tylongid l; printf " = "; print_ty ty; print_loc loc let print_where (l,loc) = printf "@[<2> where type "; print_list print_longtypebind (fun () -> printf "@, and ") l; printf "@]"; print_loc loc let print_valdesc (id, t,loc) = print_varid id; printf " = "; print_ty t; print_loc loc let print_typedesc p = match p with TypeDesc (tyvs, id,loc) -> print_tyvars tyvs; printf " "; print_tyid id; print_loc loc | TypeBindDesc (tyvs, id, ty,loc) -> print_tyvars tyvs; print_tyid id; printf " = "; print_ty ty; print_loc loc | DataDesc (tyvs, id, cl, loc) -> print_tyvars tyvs; printf " "; print_tyid id; printf " = "; printf "@["; print_list print_con (fun () -> printf " |@ ") cl; printf "@]"; print_loc loc let print_exndesc (c) = print_con c let rec print_strdesc (id, se,loc) = print_strid id; printf " : "; print_sigexp se; print_loc loc and print_spec p = match p with ValSpec (l,loc) -> printf "@[<2>val "; print_list print_valdesc (fun () -> printf "@]@\n@[<2>and ") l; printf "@]"; print_loc loc | TypeSpec (l,loc) -> printf "type "; print_list print_typedesc (fun () -> printf "@\nand ") l; print_loc loc | ExnSpec (l,loc) -> printf "@[<2>exception "; print_list print_exndesc (fun () -> printf "@ and ") l; printf "@]"; print_loc loc | IncludeSpec (s,loc) -> printf "@[<2>include "; print_sigexp s; printf "@]"; print_loc loc | StrSpec (l,loc) -> printf "@[<2>structure "; print_list print_strdesc (fun () -> printf "@\nand ") l; printf "@]"; print_loc loc | SeqSpec (l,loc) -> print_list print_spec (fun () -> printf "@\n") l; print_loc loc and print_sigexp p = match p with VarSig (s,loc) -> print_sigid s; print_loc loc | SigSig (s,loc) -> printf "@\n@[<2>sig @\n"; print_spec s; printf "@]@\nend"; print_loc loc | ConstraintSig (se, wh,loc) -> print_sigexp se; printf "@\n@ "; print_where wh; print_loc loc let print_sigexpop p = match p with None -> () | Some(s) -> printf " : "; print_sigexp s let print_sigbind (id, s, loc) = print_sigid id ; printf " = "; print_sigexp s; print_loc loc let print_sigdec (l,loc) = printf "@[<2>signature "; print_list print_sigbind (fun () -> printf "@]@\n@[<2>and ") l; printf "@]"; print_loc loc let rec print_strexp p = match p with VarStr (l,loc) -> print_strlongid l; print_loc loc | StrStr (d,loc) -> printf "@\n@[<2>struct@\n"; print_strdec d; printf "@]@\nend"; print_loc loc | SigStr (ste, sie,loc) -> print_strexp ste; printf " : "; print_sigexp sie; print_loc loc | FctAppStr (id, sl,loc) -> print_fctid id; printf " ("; print_list print_strexp (fun () -> printf ",@ ") sl; printf ")"; print_loc loc and print_strbind (id, sgop, se,loc) = print_strid id; print_sigexpop sgop; printf " = "; print_strexp se; print_loc loc and print_strdec p = match p with SimpleDec (d,loc) -> print_dec d; print_loc loc | StrDec (l,loc) -> printf "@[<2>structure "; print_list print_strbind (fun () -> printf "@]@\n@[<2>and ") l; printf "@]"; print_loc loc | SeqStrDec (l,loc) -> print_list print_strdec (fun () -> printf ";@\n") l; print_loc loc let print_fctarg (id, se, loc) = print_strid id; printf " : "; print_sigexp se; print_loc loc let print_whereop p = match p with None -> () | Some(w) -> printf " "; print_where w let print_fctdec p = match p with (id, al, sgop, se, loc) -> printf "@[<2>functor "; print_fctid id; printf " (@["; print_list print_fctarg (fun () -> printf ",@ ") al; printf "@])"; print_sigexpop sgop; printf " =@ "; print_strexp se; printf "@]"; print_loc loc let rec print_topdec p = match p with Sig (d,loc) -> print_sigdec d; print_loc loc | Fct (d,loc) -> print_fctdec d; print_loc loc | Str (d,loc) -> print_strdec d; print_loc loc | SeqTopDec (dl,loc) -> begin let print_one d = print_topdec d; printf ";@\n" in printf "@[";List.iter print_one dl;printf "@]" end; print_loc loc (* poisson *) let rec print_dirarg d = match d with ArgNone -> () | ArgString (s) -> print_string (" "^s) | ArgLident (v) -> print_varlongid v | ArgInt (i) -> print_int i let rec print_toplevel p = match p with TopDef (d) -> print_topdec d | TopExp (el,loc) -> List.iter print_exp el; print_loc loc | TopDir (s,d) -> print_string s; print_dirarg d (***********) *) end module Ast = Ast_generator(Info.StringInfo)(Info.LocationInfo) (* Modification history. 2000/03/27 By Judaigi - Remove DataDec and merge it in TypeDec. - Remove DataSpec and merge it in TypeSpec. - Remove pec and merge it in TypeSpec. 2000/02/24 By Judaigi - Remove eqtypeness from 'tyvar' def. - Remove 'sharing' option from 'FctDec'. - Add 'TypeBindSpec' to 'spec' def. - Remove 'ContraintSpec' from 'spec' def. - Remove 'sharing' type. - Remove 'tylongideq' type. *) (* Modification history. 2000/03/27 By Judaigi - Remove print_databind and print_datadesc functions. - Change according to changes in ast. *)