summaryrefslogtreecommitdiffstats
path: root/otherlibs/labltk/compiler/tables.ml
diff options
context:
space:
mode:
Diffstat (limited to 'otherlibs/labltk/compiler/tables.ml')
-rw-r--r--otherlibs/labltk/compiler/tables.ml414
1 files changed, 0 insertions, 414 deletions
diff --git a/otherlibs/labltk/compiler/tables.ml b/otherlibs/labltk/compiler/tables.ml
deleted file mode 100644
index 4a606014d..000000000
--- a/otherlibs/labltk/compiler/tables.ml
+++ /dev/null
@@ -1,414 +0,0 @@
-(* $Id$ *)
-
-(* Internal compiler errors *)
-
-exception Compiler_Error of string
-let fatal_error s = raise (Compiler_Error s)
-
-
-(* Types of the description language *)
-type mltype =
- Unit
- | Int
- | Float
- | Bool
- | Char
- | String
- | List of mltype
- | Product of mltype list
- | Record of (string * mltype) list
- | UserDefined of string
- | Subtype of string * string
- | Function of mltype (* arg type only *)
- | As of mltype * string
-
-type template =
- StringArg of string
- | TypeArg of string * mltype
- | ListArg of template list
- | OptionalArgs of string * template list * template list
-
-(* Sorts of components *)
-type component_type =
- Constructor
- | Command
- | External
-
-(* Full definition of a component *)
-type fullcomponent = {
- component : component_type;
- ml_name : string; (* may be no longer useful *)
- var_name : string;
- template : template;
- result : mltype;
- safe : bool
- }
-
-let sort_components =
- Sort.list order:(fun c1 c2 -> c1.ml_name < c2.ml_name)
-
-
-(* components are given either in full or abbreviated *)
-type component =
- Full of fullcomponent
- | Abbrev of string
-
-(* A type definition *)
-(*
- requires_widget_context: the converter of the type MUST be passed
- an additional argument of type Widget.
-*)
-
-type parser_arity =
- OneToken
-| MultipleToken
-
-type type_def = {
- parser_arity : parser_arity;
- mutable constructors : fullcomponent list;
- mutable subtypes : (string * fullcomponent list) list;
- mutable requires_widget_context : bool;
- mutable variant : bool
-}
-
-type module_type =
- Widget
- | Family
-
-type module_def = {
- module_type : module_type;
- commands : fullcomponent list;
- externals : fullcomponent list
-}
-
-(******************** The tables ********************)
-
-(* the table of all explicitly defined types *)
-let types_table = (Hashtbl.create 37 : (string, type_def) Hashtbl.t)
-(* "builtin" types *)
-let types_external = ref ([] : (string * parser_arity) list)
-(* dependancy order *)
-let types_order = (Tsort.create () : string Tsort.porder)
-(* Types of atomic values returned by Tk functions *)
-let types_returned = ref ([] : string list)
-(* Function table *)
-let function_table = ref ([] : fullcomponent list)
-(* Widget/Module table *)
-let module_table = (Hashtbl.create 37 : (string, module_def) Hashtbl.t)
-
-
-(* variant name *)
-let rec getvarname ml_name temp =
- let offhypben s =
- let s = String.copy s in
- if (try String.sub s pos:0 len:1 with _ -> "") = "-" then
- String.sub s pos:1 len:(String.length s - 1)
- else s
- and makecapital s =
- begin
- try
- let cd = s.[0] in
- if cd >= 'a' && cd <= 'z' then
- s.[0] <- Char.chr (Char.code cd + (Char.code 'A' - Char.code 'a'))
- with
- _ -> ()
- end;
- s
- in
- let head = makecapital (offhypben begin
- match temp with
- StringArg s -> s
- | TypeArg (s,t) -> s
- | ListArg (h::_) -> getvarname ml_name h
- | OptionalArgs (s,_,_) -> s
- | ListArg [] -> ""
- end)
- in
- let varname = if head = "" then ml_name
- else if head.[0] >= 'A' && head.[0] <= 'Z' then head
- else ml_name
- in varname
-
-(***** Some utilities on the various tables *****)
-(* Enter a new empty type *)
-let new_type typname arity =
- Tsort.add_element types_order typname;
- let typdef = {parser_arity = arity;
- constructors = [];
- subtypes = [];
- requires_widget_context = false;
- variant = false} in
- Hashtbl.add types_table key:typname data:typdef;
- typdef
-
-
-(* Assume that types not yet defined are not subtyped *)
-(* Widget is builtin and implicitly subtyped *)
-let is_subtyped s =
- s = "widget" or
- try
- let typdef = Hashtbl.find types_table key:s in
- typdef.subtypes <> []
- with
- Not_found -> false
-
-let requires_widget_context s =
- try
- (Hashtbl.find types_table key:s).requires_widget_context
- with
- Not_found -> false
-
-let declared_type_parser_arity s =
- try
- (Hashtbl.find types_table key:s).parser_arity
- with
- Not_found ->
- try List.assoc key:s !types_external
- with
- Not_found ->
- prerr_string "Type "; prerr_string s;
- prerr_string " is undeclared external or undefined\n";
- prerr_string ("Assuming cTKtoCAML"^s^" : string -> "^s^"\n");
- OneToken
-
-let rec type_parser_arity = function
- Unit -> OneToken
- | Int -> OneToken
- | Float -> OneToken
- | Bool -> OneToken
- | Char -> OneToken
- | String -> OneToken
- | List _ -> MultipleToken
- | Product _ -> MultipleToken
- | Record _ -> MultipleToken
- | UserDefined s -> declared_type_parser_arity s
- | Subtype (s,_) -> declared_type_parser_arity s
- | Function _ -> OneToken
- | As (ty, _) -> type_parser_arity ty
-
-let enter_external_type s v =
- types_external := (s,v)::!types_external
-
-(*** Stuff for topological Sort.list of types ***)
-(* Make sure all types used in commands and functions are in *)
-(* the table *)
-let rec enter_argtype = function
- Unit | Int | Float | Bool | Char | String -> ()
- | List ty -> enter_argtype ty
- | Product tyl -> List.iter fun:enter_argtype tyl
- | Record tyl -> List.iter tyl fun:(fun (l,t) -> enter_argtype t)
- | UserDefined s -> Tsort.add_element types_order s
- | Subtype (s,_) -> Tsort.add_element types_order s
- | Function ty -> enter_argtype ty
- | As (ty, _) -> enter_argtype ty
-
-let rec enter_template_types = function
- StringArg _ -> ()
- | TypeArg (l,t) -> enter_argtype t
- | ListArg l -> List.iter fun:enter_template_types l
- | OptionalArgs (_,tl,_) -> List.iter fun:enter_template_types tl
-
-(* Find type dependancies on s *)
-let rec add_dependancies s =
- function
- List ty -> add_dependancies s ty
- | Product tyl -> List.iter fun:(add_dependancies s) tyl
- | Subtype(s',_) -> if s <> s' then Tsort.add_relation types_order (s', s)
- | UserDefined s' -> if s <> s' then Tsort.add_relation types_order (s', s)
- | Function ty -> add_dependancies s ty
- | As (ty, _) -> add_dependancies s ty
- | _ -> ()
-
-let rec add_template_dependancies s = function
- StringArg _ -> ()
- | TypeArg (l,t) -> add_dependancies s t
- | ListArg l -> List.iter fun:(add_template_dependancies s) l
- | OptionalArgs (_,tl,_) -> List.iter fun:(add_template_dependancies s) tl
-
-(* Assumes functions are not nested in products, which is reasonable due to syntax*)
-let rec has_callback = function
- StringArg _ -> false
- | TypeArg (l,Function _ ) -> true
- | TypeArg _ -> false
- | ListArg l -> List.exists pred:has_callback l
- | OptionalArgs (_,tl,_) -> List.exists pred:has_callback tl
-
-(*** Returned types ***)
-let really_add ty =
- if List.mem elt:ty !types_returned then ()
- else types_returned := ty :: !types_returned
-
-let rec add_return_type = function
- Unit -> ()
- | Int -> ()
- | Float -> ()
- | Bool -> ()
- | Char -> ()
- | String -> ()
- | List ty -> add_return_type ty
- | Product tyl -> List.iter fun:add_return_type tyl
- | Record tyl -> List.iter tyl fun:(fun (l,t) -> add_return_type t)
- | UserDefined s -> really_add s
- | Subtype (s,_) -> really_add s
- | Function _ -> fatal_error "unexpected return type (function)" (* whoah *)
- | As (ty, _) -> add_return_type ty
-
-(*** Update tables for a component ***)
-let enter_component_types {template = t; result = r} =
- add_return_type r;
- enter_argtype r;
- enter_template_types t
-
-
-(******************** Types and subtypes ********************)
-exception Duplicate_Definition of string * string
-exception Invalid_implicit_constructor of string
-
-(* Checking duplicate definition of constructor in subtypes *)
-let rec check_duplicate_constr allowed c =
- function
- [] -> false (* not defined *)
- | c'::rest ->
- if c.ml_name = c'.ml_name then (* defined *)
- if allowed then
- if c.template = c'.template then true (* same arg *)
- else raise (Duplicate_Definition ("constructor",c.ml_name))
- else raise (Duplicate_Definition ("constructor", c.ml_name))
- else check_duplicate_constr allowed c rest
-
-(* Retrieve constructor *)
-let rec find_constructor cname = function
- [] -> raise (Invalid_implicit_constructor cname)
- | c::l -> if c.ml_name = cname then c
- else find_constructor cname l
-
-(* Enter a type, must not be previously defined *)
-let enter_type typname ?:variant{=false} arity constructors =
- try
- Hashtbl.find types_table key:typname;
- raise (Duplicate_Definition ("type", typname))
- with Not_found ->
- let typdef = new_type typname arity in
- if variant then typdef.variant <- true;
- List.iter constructors fun:
- begin fun c ->
- if not (check_duplicate_constr false c typdef.constructors)
- then begin
- typdef.constructors <- c :: typdef.constructors;
- add_template_dependancies typname c.template
- end;
- (* Callbacks require widget context *)
- typdef.requires_widget_context <-
- typdef.requires_widget_context or
- has_callback c.template
- end
-
-(* Enter a subtype *)
-let enter_subtype typ arity subtyp constructors =
- (* Retrieve the type if already defined, else add a new one *)
- let typdef =
- try Hashtbl.find types_table key:typ
- with Not_found -> new_type typ arity
- in
- if List.mem_assoc key:subtyp typdef.subtypes
- then raise (Duplicate_Definition ("subtype", typ ^" "^subtyp))
- else begin
- let real_constructors =
- List.map constructors fun:
- begin function
- Full c ->
- if not (check_duplicate_constr true c typdef.constructors)
- then begin
- add_template_dependancies typ c.template;
- typdef.constructors <- c :: typdef.constructors
- end;
- typdef.requires_widget_context <-
- typdef.requires_widget_context or
- has_callback c.template;
- c
- | Abbrev name -> find_constructor name typdef.constructors
- end
- in
- (* TODO: duplicate def in subtype are not checked *)
- typdef.subtypes <-
- (subtyp , Sort.list real_constructors
- order:(fun c1 c2 -> c1.var_name <= c2.var_name)) ::
- typdef.subtypes
- end
-
-(******************** Widgets ********************)
-(* used by the parser; when enter_widget is called,
- all components are assumed to be in Full form *)
-let retrieve_option optname =
- let optiontyp =
- try Hashtbl.find types_table key:"options"
- with
- Not_found -> raise (Invalid_implicit_constructor optname)
- in find_constructor optname optiontyp.constructors
-
-(* Sort components by type *)
-let rec add_sort acc:l obj =
- match l with
- [] -> [obj.component ,[obj]]
- | (s',l)::rest ->
- if obj.component = s' then
- (s',obj::l)::rest
- else
- (s',l)::(add_sort acc:rest obj)
-
-let separate_components = List.fold_left fun:add_sort acc:[]
-
-let enter_widget name components =
- try
- Hashtbl.find module_table key:name;
- raise (Duplicate_Definition ("widget/module", name))
- with Not_found ->
- let sorted_components = separate_components components in
- List.iter sorted_components fun:
- begin function
- Constructor, l ->
- enter_subtype "options" MultipleToken
- name (List.map fun:(fun c -> Full c) l)
- | Command, l ->
- List.iter fun:enter_component_types l
- | External, _ -> ()
- end;
- let commands =
- try List.assoc key:Command sorted_components
- with Not_found -> []
- and externals =
- try List.assoc key:External sorted_components
- with Not_found -> []
- in
- Hashtbl.add module_table key:name
- data:{module_type = Widget; commands = commands; externals = externals}
-
-(******************** Functions ********************)
-let enter_function comp =
- enter_component_types comp;
- function_table := comp :: !function_table
-
-
-(******************** Modules ********************)
-let enter_module name components =
- try
- Hashtbl.find module_table key:name;
- raise (Duplicate_Definition ("widget/module", name))
- with Not_found ->
- let sorted_components = separate_components components in
- List.iter sorted_components fun:
- begin function
- Constructor, l -> fatal_error "unexpected Constructor"
- | Command, l -> List.iter fun:enter_component_types l
- | External, _ -> ()
- end;
- let commands =
- try List.assoc key:Command sorted_components
- with Not_found -> []
- and externals =
- try List.assoc key:External sorted_components
- with Not_found -> []
- in
- Hashtbl.add module_table key:name
- data:{module_type = Family; commands = commands; externals = externals}
-