Skip to content
Snippets Groups Projects
  • Erwan Jahier's avatar
    16344043
    Fix a bug where, when defining a package exporting an abstract type · 16344043
    Erwan Jahier authored
    t, and a node returning such a t, the compiler was actually returning
    the type definition of t (instead of the abstract type).
    
    In  order  to fix  that,  it  was necessary  to  add  in argument  of
    Lazycompiler.solve_x_idref  a  flag  (named provide_flag)  indicating
    whether the  item being  compiled appears in  the provide, or  in the
    body part of the package.
    
    This fix  triggered another bug that  we also fix: indeed,  it is not
    correct to return  a compile error when the  provided parameters of a
    node is not equal to  its implementation. Indeed, such parameters can
    be abstract type that are defined in that package.
    
    The test "should_work/packEnvTest/packages.lus" is now ok.
    16344043
    History
    Fix a bug where, when defining a package exporting an abstract type
    Erwan Jahier authored
    t, and a node returning such a t, the compiler was actually returning
    the type definition of t (instead of the abstract type).
    
    In  order  to fix  that,  it  was necessary  to  add  in argument  of
    Lazycompiler.solve_x_idref  a  flag  (named provide_flag)  indicating
    whether the  item being  compiled appears in  the provide, or  in the
    body part of the package.
    
    This fix  triggered another bug that  we also fix: indeed,  it is not
    correct to return  a compile error when the  provided parameters of a
    node is not equal to  its implementation. Indeed, such parameters can
    be abstract type that are defined in that package.
    
    The test "should_work/packEnvTest/packages.lus" is now ok.
symbolTab.ml 4.43 KiB
(** Time-stamp: <modified the 15/05/2008 (at 16:26) by Erwan Jahier> *)

(*
Sous-module pour SyntaxTab 
*)
open Lxm
open SyntaxTree
open SyntaxTreeCore
open Errors

type 'a elt =
  | Local of 'a
  | Imported of Ident.long * static_param srcflagged list

type t = {
  st_consts: (Ident.t , (const_info srcflagged) elt) Hashtbl.t ;
  st_types : (Ident.t , (type_info  srcflagged) elt) Hashtbl.t ;
  st_nodes : (Ident.t , (node_info  srcflagged) elt) Hashtbl.t ;
} 

(* Création/initialisation d'une symbol_tab *)
let create () = 
  let consts_tbl = Hashtbl.create 50
  and types_tbl  = Hashtbl.create 50
  and nodes_tbl  = Hashtbl.create 50
  in
    {
      st_consts = consts_tbl;
      st_types  = types_tbl;
      st_nodes  = nodes_tbl;
    }

let find_type (this: t) (id: Ident.t) lxm =
  try Hashtbl.find (this.st_types) id
  with Not_found -> 
    raise (Compile_error(lxm, "unknown type (" ^ (Ident.to_string id)^")"))

  
let find_const (this: t) (id: Ident.t) lxm = 
  try Hashtbl.find (this.st_consts) id
  with Not_found -> 
    raise (Compile_error(lxm, "unknown constant (" ^ (Ident.to_string id) ^")"))


let find_node (this: t) (id: Ident.t) lxm =
  try Hashtbl.find (this.st_nodes) id
  with Not_found -> 
    if Lxm.line lxm = 0 && Lxm.cend lxm = 0 then
      (* A hack to print a nicer error msg when the node asked in the 
	 command-line is not found in the input files*)
      raise (Global_error("Can not find node " ^ (Ident.to_string id)^
			    " in " ^ (Lxm.file lxm)))
    else
      raise (Compile_error(lxm, "unknown node (" ^ (Ident.to_string id)^")"))


(* Manip de SymbolTab.t *)
let add_import_const (this: t) (id: Ident.t) (aid: Ident.long) =
  Hashtbl.replace (this.st_consts) id (Imported (aid, []))

let add_import_type (this: t) (id: Ident.t) (aid: Ident.long) =
  Hashtbl.replace (this.st_types) id (Imported (aid, []))

let add_import_node (this: t) (id: Ident.t) (aid: Ident.long) 
    (params:static_param srcflagged list) =
  Hashtbl.replace (this.st_nodes) id (Imported (aid, params))

let add_const (this: t) (n: Ident.t) (cix: const_info  srcflagged) =
  Hashtbl.replace this.st_consts n (Local cix)
let add_type (this: t) (n: Ident.t) (tix: type_info srcflagged) = (
  Hashtbl.replace this.st_types n (Local tix) ;
  (* cas particulier des types enums *)
  match tix.it with
      EnumType (_, ecl) -> (
	let tname = Lxm.str tix.src in
	let treat_enum_const ec = (
	  let te = Named_type_exp { Ident.id_pack = None; Ident.id_id = tname} in
	  let tex = Lxm.flagit te tix.src in
	  let ci = EnumConst (ec.it, tex) in
	    add_const this ec.it (Lxm.flagit ci (ec.src))
	) in
	  List.iter treat_enum_const ecl
      )
    | _ -> ()
)

let add_node (this: t) (n: Ident.t) (oix: node_info  srcflagged) =
  Hashtbl.add this.st_nodes n (Local oix)
 

let iter_types this f = ( Hashtbl.iter f this.st_types)
let iter_consts this f = ( Hashtbl.iter f this.st_consts)
let iter_nodes this f = ( Hashtbl.iter f this.st_nodes)

(* useful for debug *)
let (dump : t -> unit) =
  fun x ->
    let const_info_dump = function 
      | Imported(l,_) -> print_string (Ident.long_to_string l)
      | Local(x) -> (match x.it with
		       | ExternalConst (id,texp) -> print_string "extern"
		       | EnumConst (id,texp) -> print_string "enum"
		       | DefinedConst (id,texp,vexp) -> 
			   SyntaxTreeDump.dump_val_exp Format.std_formatter vexp;
			   Format.print_flush ()
		    )
    in
    let type_info_dump =  function 
      | Imported(l,params) -> print_string (Ident.long_to_string l)
      | Local ti -> 
	  match ti.it with
	    | ExternalType id -> print_string ("extern type ")
	    | AliasedType(id,texp)  -> 
		print_string "an alias on ";
		SyntaxTreeDump.dump_type_exp Format.std_formatter texp;
		Format.print_flush ()
	    | EnumType (id,_)  -> print_string ("an enum " ^ (Ident.to_string id))
	    | StructType   si  -> print_string ("a structure " )
	    | ArrayType(id,_,_)  -> print_string ("an array " ^ (Ident.to_string id))
    in
    let node_info_dump =  function 
      | Imported(l,params) -> print_string ((Ident.long_to_string l) ^ " (extern)")
      | Local ni -> print_string ((Ident.to_string ni.it.name) ^ " (local)")
    in
    let htbl_dump label i2s tbl =
      print_string label;
      Hashtbl.iter 
	(fun id info -> 
	   print_string ("\n  - " ^ Ident.to_string id ^" -> ");
	   i2s info)
	tbl
    in
      htbl_dump "\nconstants: " const_info_dump x.st_consts;
      htbl_dump "\ntypes: " type_info_dump x.st_types;
      htbl_dump "\nnodes: " node_info_dump x.st_nodes