From de984fca1a04d043801ce28257e0133faf2c03c3 Mon Sep 17 00:00:00 2001
From: Erwan Jahier <jahier@imag.fr>
Date: Mon, 26 May 2008 16:52:48 +0200
Subject: [PATCH] Add  error messages  when  one tries  to  alaias a 
 polymporphic or  a overloaded operator.

Moreover, do not try to check that int or real constant are ok. It is
the role of the host language.
---
 src/TODO               |  11 +++-
 src/evalType.ml        |  14 ++--
 src/lazyCompiler.ml    |  17 ++++-
 src/predefSemantics.ml | 142 ++++++++++++++++++++---------------------
 4 files changed, 101 insertions(+), 83 deletions(-)

diff --git a/src/TODO b/src/TODO
index 082dc741..684aa528 100644
--- a/src/TODO
+++ b/src/TODO
@@ -100,6 +100,14 @@ lazycompiler.ml:
   je les ai en interne...
 
 * splitter predefsemantics en predefTyping et PredefEval?
+   les  function   type_error  des  predefSemantics   devraient  ĂȘtre
+   definies ailleurs en ce cas.
+   
+
+* autoriser les  alias sur  "nor" et "#"  ? (ca complique  les choses
+  pour bien peu...).
+
+* essayer de faire qque chose pour les 2 verrues dans predefSemantics
 
 ***********************************************************************************
 ***********************************************************************************
@@ -109,9 +117,8 @@ lazycompiler.ml:
 
 *** facile
 
-* les function type_error des predefSemantics devraient ĂȘtre definies ailleurs
 
-* essayer de faire qque chose pour les 2 verrues dans predefSemantics
+   
 
 * iterateur sur  des operateur  predefinis : ca  ne peut  pas marcher
   tant que StaticParamNode (cd SyntaxTreeCore.static_param) stocke un
diff --git a/src/evalType.ml b/src/evalType.ml
index 9584172a..5a38e6e4 100644
--- a/src/evalType.ml
+++ b/src/evalType.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 26/05/2008 (at 10:55) by Erwan Jahier> *)
+(** Time-stamp: <modified the 26/05/2008 (at 15:48) by Erwan Jahier> *)
  
   
 open Predef
@@ -34,9 +34,9 @@ and (eval_by_pos_type :
       | CALL_eff node_exp_eff -> 
 	  let lto = snd (List.split node_exp_eff.it.outlist_eff) in
 	    List.map
-	      (function 
-		 | Atype t -> t 
-		 | (Any | Overload)  -> assert false (* cannot occur for user node *)
+	      (function
+		 | Atype t -> t
+		 | (Any | Overload) -> assert false (* cannot occur for user node *)
 	      )
 	      lto
       | IDENT_eff id  -> (
@@ -48,14 +48,14 @@ and (eval_by_pos_type :
 	  match args with
 	      [a0;a1;a2] -> (
 		match (f id_solver a0) with
-		  | [Bool_type_eff] -> 
+		  | [Bool_type_eff] ->
 		      let teff1 = f id_solver a1
 		      and teff2 = f id_solver a2 in
 			if teff1 = teff2 then teff1 else
 			  type_error [] "type mismatch in with statements"
 		  | x -> type_error x "bool"
 	      )
-	    | _ -> 
+	    | _ ->
 		raise (EvalType_error(sprintf "arity error: 3 expected instead of %d" 
 					 (List.length args)))
 	)
@@ -66,7 +66,7 @@ and (eval_by_pos_type :
 	    | [[Array_type_eff (teff0, size0)]; [Array_type_eff (teff1, size1)]] -> (
 		if teff0 = teff1 then 
 		  [Array_type_eff (teff0, size0+size1)]	
-		else 
+		else
 		  raise(EvalType_error(
 			  sprintf "type combination error, can't concat %s with %s"
 			    (CompiledDataDump.string_of_type_eff teff0)
diff --git a/src/lazyCompiler.ml b/src/lazyCompiler.ml
index 7e4d9c13..ab24f7a7 100644
--- a/src/lazyCompiler.ml
+++ b/src/lazyCompiler.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 26/05/2008 (at 14:58) by Erwan Jahier> *)
+(** Time-stamp: <modified the 26/05/2008 (at 16:42) by Erwan Jahier> *)
 
 
 open Lxm
@@ -658,6 +658,21 @@ and (node_check_do: t -> CompiledData.node_key -> Lxm.t -> SymbolTab.t ->
 	| Alias({it= alias;src=lxm}) -> (
 	    let aliased_node = 
 	      match alias with
+		| Predef((Predef.NOR_n|Predef.DIESE_n), sargs) -> 
+		    raise (Compile_error (lxm, "Can not alias 'nor' nor '#', sorry"))
+		| Predef(
+		    (Predef.NEQ_n | Predef.EQ_n | Predef.LT_n | Predef.LTE_n 
+		    | Predef.GT_n | Predef.GTE_n | Predef.IF_n), _sargs
+		  ) -> 
+		    raise (Compile_error (
+			     lxm, "can not alias polymorphic operators, sorry"))
+		| Predef(
+		    ( Predef.UMINUS_n | Predef.MINUS_n  |  Predef.PLUS_n 
+		    | Predef.TIMES_n |  Predef.SLASH_n), _sargs
+		  ) -> 
+		    raise (Compile_error (
+			     lxm, "can not alias overloaded operators, sorry"))
+
 		| Predef(predef_op, sargs) -> 
 		    let sargs_eff = 
 		      GetEff.translate_predef_static_args node_id_solver sargs lxm 
diff --git a/src/predefSemantics.ml b/src/predefSemantics.ml
index 5c90a2ec..b8a13ae6 100644
--- a/src/predefSemantics.ml
+++ b/src/predefSemantics.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 26/05/2008 (at 15:09) by Erwan Jahier> *)
+(** Time-stamp: <modified the 26/05/2008 (at 16:51) by Erwan Jahier> *)
 
 
 open Predef
@@ -13,7 +13,6 @@ type typer = type_eff evaluator
 type const_evaluator = const_eff evaluator
 type clocker = clock_eff evaluator
 
-let finish_me msg = print_string ("\n\tXXX predefSemantics.ml:"^msg^" ->  finish me!\n")
 
 (*********************************************************************************)
 exception EvalConst_error of string
@@ -72,10 +71,12 @@ let not_evaluable op l =
 	     (op2string op)))
 
 (*********************************************************************************)
-(** 
-    This unify function is quite specific. It can only unify 2 lists
+(** This unify function is quite specific. It can only unify 2 lists
     with at most one type variable (Any); we also suppose that the
     second list have no Any type.
+
+    Moreover, it deals with the concept of overloaded variable. Currently,
+    an overloaded variable is polymorphic var that can only be an int or a real.
   
     [unify] has 3 kinds of results:
     - the 2 lists are equal
@@ -89,35 +90,34 @@ type unify_result =
 
 let var_type2str = CompiledDataDump.string_of_var_type
 let type_eff2str = CompiledDataDump.string_of_type_eff
+
 let (unify : var_type list -> var_type list -> unify_result) =
-  fun l1 l2 -> 
-    let (is_overloadable : type_eff -> bool) = function
-      | Int_type_eff -> true
-      | Real_type_eff -> true
-      | _ -> false
-    in
-      List.fold_left2
-	(fun acc vt1 vt2 -> 
-	   match acc,vt1,vt2 with
-	     | Ko msg , _, _ -> acc
-	     | Equal, Any,      Atype t2 -> Unif t2
-	     | Equal, Overload, Atype t2 -> if is_overloadable t2 then Unif t2 else 
-		 Ko((type_eff2str t2) ^ " should have type int or real")
-
-	     | (Equal|Unif _), Atype t1, Atype t2 -> if t1 = t2 then acc else 
-		 Ko((type_eff2str t1) ^ " <> " ^ (type_eff2str t2))
-
-	     | Unif ts, Any, Atype t2 -> if ts = t2 then acc else
+  let (is_overloadable : type_eff -> bool) = function
+    | Int_type_eff -> true
+    | Real_type_eff -> true
+    | _ -> false
+  in
+    List.fold_left2
+      (fun acc vt1 vt2 -> 
+	 match acc,vt1,vt2 with
+	   | Ko msg , _, _ -> acc
+	   | Equal, Any,      Atype t2 -> Unif t2
+	   | Equal, Overload, Atype t2 -> if is_overloadable t2 then Unif t2 else 
+	       Ko((type_eff2str t2) ^ " should have type int or real")
+
+	   | (Equal|Unif _), Atype t1, Atype t2 -> if t1 = t2 then acc else 
+	       Ko((type_eff2str t1) ^ " <> " ^ (type_eff2str t2))
+
+	   | Unif ts, Any, Atype t2 -> if ts = t2 then acc else
+	       Ko((type_eff2str ts) ^ " <> " ^ (type_eff2str t2))
+	   | Unif ts, Overload, Atype t2 -> 
+	       if ts = t2 && is_overloadable t2 then acc else
 		 Ko((type_eff2str ts) ^ " <> " ^ (type_eff2str t2))
-	     | Unif ts, Overload, Atype t2 -> 
-		 if ts = t2 && is_overloadable t2 then acc else
-		   Ko((type_eff2str ts) ^ " <> " ^ (type_eff2str t2))
 
-	     | _,_, (Overload|Any) -> assert false (* cannot occur *)
-	)
-	Equal
-	l1 
-	l2
+	   | _,_, (Overload|Any) -> assert false (* cannot occur *)
+      )
+      Equal
+
 
 (*********************************************************************************)
 (* a few local alias to make the node profile below more readable. *)
@@ -133,42 +133,23 @@ let ii_profile  = [(id "i", i)], [(id "o", i)]               (* int -> int *)
 let iii_profile = [(id "i1", i);(id "i2", i)], [(id "o", i)] (* int*int -> int *)
 let rr_profile  = [(id "i", r)], [(id "o", r)]               (* real -> real *)
 let rrr_profile = [(id "i1", r);(id "i2", r)], [(id "o", r)] (* real*real -> real *)
-let b_profile   = [],[id "o", b]           (* unit -> bool *) 
 let ri_profile  = [id "i", i], [id "o", r] (* real -> int  *)
 let ir_profile  = [id "i", r], [id "o", i] (* int  -> real *)
 
-let bl_profile lxm = [],[] (* bool list *)
+(** Constant profiles  *)
+let b_profile = [],[id "o", b]
+let i_profile = [],[id "o", i]
+let r_profile = [],[id "o", r]
 
-(** polymorphic operators *)
+(** polymorphic operator profiles *)
 let aab_profile = [(id "i1",Any);(id "i2",Any)], [(id "o", b)] (* 'a -> 'a -> bool*)
 let baaa_profile = [(id "c", b);(id "b1",Any);(id "b2",Any)], [(id "o",Any)] 
   (* for if-then-else *)
 
-(** overloaded operators *)
-let oo_profile = [(id "i",Overload)], [(id "o",Overload)]
+(** overloaded operator profiless *)
+let oo_profile  = [(id "i",Overload)], [(id "o",Overload)]
 let ooo_profile = [(id "i1",Overload);(id "i2",Overload)], [(id "o",Overload)]
 
-(** Misc profiles  *)
-let si_profile = (* string -> int *)
-  fun ident ->
-    (* check the ident that be converted XXX is it the rigth place to do that ? *)
-    (try ignore(int_of_string (Ident.to_string ident))
-     with Failure  "int_of_string" -> 
-       raise (EvalType_error(
-	Printf.sprintf "\n*** fail to convert the string \"%s\" into an int" 
-	  (Ident.to_string ident))));
-    [],[id "o", i]
-
-let sr_profile = (* string -> real *)
-  fun ident -> 
-    (try ignore (float_of_string (Ident.to_string ident))
-    with Failure  "float_of_string" -> 
-      raise (EvalType_error (
-	   Printf.sprintf "\n*** fail to convert the string \"%s\" into an int"
-	     (Ident.to_string ident))));
-    [],[id "o", r]
-
-
 (** iterators profiles *)
 (* [type_to_array_type [x1;...;xn] c] returns the array type [x1^c;...;xn^c] *)
 let (type_to_array_type: 
@@ -268,8 +249,8 @@ type node_profile = (Ident.t * var_type) list * (Ident.t * var_type) list
 let (op2profile : Predef.op -> Lxm.t -> static_arg_eff list -> node_profile) = 
   fun op lxm sargs -> match op with
     | TRUE_n | FALSE_n -> b_profile
-    | ICONST_n id      -> si_profile id
-    | RCONST_n id      -> sr_profile id
+    | ICONST_n id      -> i_profile
+    | RCONST_n id      -> r_profile
     | NOT_n            -> bb_profile
     | REAL2INT_n       -> ri_profile
     | INT2REAL_n       -> ir_profile
@@ -277,15 +258,24 @@ let (op2profile : Predef.op -> Lxm.t -> static_arg_eff list -> node_profile) =
     | UMINUS_n         -> oo_profile
     | IUMINUS_n        -> ii_profile
     | RUMINUS_n        -> rr_profile
-    | NOR_n | DIESE_n  -> bl_profile lxm
-    | IMPL_n | AND_n | OR_n | XOR_n               -> bbb_profile 
-    | NEQ_n | EQ_n | LT_n | LTE_n | GT_n | GTE_n  -> aab_profile 
-    | MINUS_n  |  PLUS_n |  TIMES_n |  SLASH_n                   -> ooo_profile 
-    | RMINUS_n | RPLUS_n | RTIMES_n | RSLASH_n                  -> rrr_profile
+    | IMPL_n | AND_n | OR_n | XOR_n              -> bbb_profile 
+    | NEQ_n | EQ_n | LT_n | LTE_n | GT_n | GTE_n -> aab_profile 
+    | MINUS_n  |  PLUS_n |  TIMES_n |  SLASH_n                 -> ooo_profile 
+    | RMINUS_n | RPLUS_n | RTIMES_n | RSLASH_n                 -> rrr_profile
     | DIV_n | MOD_n | IMINUS_n | IPLUS_n | ISLASH_n | ITIMES_n -> iii_profile
     | Red | Fill | FillRed -> fillred_profile lxm sargs
-    | Map                 -> map_profile lxm sargs
-    | BoolRed             -> boolred_profile lxm sargs
+    | Map                  -> map_profile lxm sargs
+    | BoolRed              -> boolred_profile lxm sargs
+
+    | NOR_n | DIESE_n  -> assert false
+	(* XXX The current representation of node_profile prevent us
+	   from being able to represent "bool list" (i.e., operator
+	   of variable arity). I could extend the type node_profile,
+	   but is it worth the complication just to be able to define
+	   alias nodes on "nor" and "#"? Actually, even if I extend
+	   this data type, I don'ty know how I could generate an
+	   alias node for them anyway...
+	*)
 
 (* exported *)
 let (make_node_exp_eff : op -> Lxm.t -> static_arg_eff list -> node_exp_eff) =
@@ -308,16 +298,13 @@ let (make_node_exp_eff : op -> Lxm.t -> static_arg_eff list -> node_exp_eff) =
 
 (* exported *)
 let (type_eval : op -> Lxm.t -> CompiledData.static_arg_eff list -> typer) = 
-  fun op lxm sargs ll -> 
-    let node_eff = make_node_exp_eff op lxm sargs in
-    let lti = List.map (fun (id,t) -> t) node_eff.inlist_eff
-    and lto = List.map (fun (id,t) -> t) node_eff.outlist_eff in
-    let unwrap_type =  function Atype t -> t | _ -> assert false in
-    let subst_type t = function Atype t -> t | Any -> t | Overload -> t in
+  fun op lxm sargs ll ->
       match op with
 	| IF_n  ->  (
 	    (* VERRUE 1 *)
-	    (* j'arrive pas a traiter le if de facon generique (pour l'instant...) *)
+	    (* j'arrive pas a traiter le if de facon generique (pour l'instant...) 
+	       a cause du fait que le if peut renvoyer un tuple.
+	    *)
 	    match ll with
 	      | [[Bool_type_eff]; t; e] -> 
 		  if t = e then t else 
@@ -325,7 +312,9 @@ let (type_eval : op -> Lxm.t -> CompiledData.static_arg_eff list -> typer) =
 	      | x -> (arity_error x "3")
 	  )
 	| (NOR_n | DIESE_n) -> 
-	    (* VERRUE 2 *)
+	    (* VERRUE 2 : those operators have no profile, therefore i define an
+	       ad-hoc check for them.
+	   *)
 	    let check_nary_iter acc ceff =
 	      match ceff with (Bool_type_eff) -> acc | _ -> (type_error [ceff] "bool")
 	    in
@@ -333,6 +322,11 @@ let (type_eval : op -> Lxm.t -> CompiledData.static_arg_eff list -> typer) =
 	      [Bool_type_eff]
 	| _ -> 
 	    (* general case *)
+	    let node_eff = make_node_exp_eff op lxm sargs in
+	    let lti = List.map (fun (id,t) -> t) node_eff.inlist_eff
+	    and lto = List.map (fun (id,t) -> t) node_eff.outlist_eff in
+	    let unwrap_type =  function Atype t -> t | _ -> assert false in
+	    let subst_type t = function Atype t -> t | Any -> t | Overload -> t in
 	    let l = List.map (fun t -> Atype t) (List.flatten ll) in
 	      if (List.length l <> List.length lti) then
 		arity_error l (string_of_int (List.length lti))
@@ -497,6 +491,8 @@ let (const_eval: op -> Lxm.t -> static_arg_eff list -> const_evaluator) =
 
 (*********************************************************************************)
 	
+let finish_me msg = print_string ("\n\tXXX predefSemantics.ml:"^msg^" ->  finish me!\n")
+
 let (aa_clocker: clocker) =
   function
     | [clk1] -> clk1
-- 
GitLab