-
Erwan Jahier authored
before '..'.
Erwan Jahier authoredbefore '..'.
evalType.ml 5.25 KiB
(** Time-stamp: <modified the 30/05/2008 (at 17:46) by Erwan Jahier> *)
open Predef
open PredefSemantics
open SyntaxTree
open SyntaxTreeCore
open CompiledData
open Printf
open Lxm
open Errors
let finish_me msg = print_string ("\n\tXXX evalType.ml:"^msg^" -> finish me!\n")
let rec (f : id_solver -> val_exp_eff -> type_eff list) =
fun id_solver ve ->
match ve with
| CallByPosEff ({it=posop; src=lxm}, OperEff args) -> (
try eval_by_pos_type id_solver posop lxm args
with EvalType_error msg ->
raise (Compile_error(lxm, "type error: "^msg))
)
| CallByNameEff ({it=nmop; src=lxm}, nmargs ) ->
try eval_by_name_type id_solver nmop lxm nmargs
with EvalConst_error msg ->
raise (Compile_error(lxm, "\n*** can't eval constant: "^msg))
and (eval_by_pos_type :
id_solver -> by_pos_op_eff -> Lxm.t -> val_exp_eff list -> type_eff list) =
fun id_solver posop lxm args ->
match posop with
| Predef_eff (op,sargs) ->
PredefSemantics.type_eval op lxm sargs (List.map (f id_solver) args)
| CALL_eff node_exp_eff ->
let lto = snd (List.split node_exp_eff.it.outlist_eff) in
(try List.map type_eff_ext_to_type_eff lto
with Polymorphic | Overloaded -> assert false)
| IDENT_eff id -> (
(* [id] migth be a constant, but also a variable *)
try [type_of_const_eff (id_solver.id2const id lxm)]
with _ -> [(id_solver.id2var id lxm).var_type_eff]
)
| WITH_eff -> (
match args with
[a0;a1;a2] -> (
match (f id_solver a0) with
| [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)))
)
| TUPLE_eff -> List.flatten (List.map (f id_solver) args)
| CONCAT_eff -> (
match List.map (f id_solver) args with
| [[Array_type_eff (teff0, size0)]; [Array_type_eff (teff1, size1)]] -> (
if teff0 = teff1 then
[Array_type_eff (teff0, size0+size1)]
else
raise(EvalType_error(
sprintf "type combination error, can't concat %s with %s"
(CompiledDataDump.string_of_type_eff teff0)
(CompiledDataDump.string_of_type_eff teff1)))
)
| [_;_] ->
raise(EvalType_error("type combination error, array type expected"))
| _ ->
raise(EvalType_error(sprintf "arity error: 2 expected instead of %d"
(List.length args)))
)
| STRUCT_ACCESS_eff fid -> (
let type_args_eff = List.flatten (List.map (f id_solver) args) in
match type_args_eff with
| [Struct_type_eff (name, fl)] -> (
try
[fst (List.assoc fid fl)]
with Not_found ->
raise (EvalType_error
(Printf.sprintf "%s is not a field of struct %s"
(Ident.to_string fid)
(CompiledDataDump.string_of_type_eff(List.hd type_args_eff))))
)
| [x] -> type_error [x] "struct type"
| x -> arity_error x "1"
)
| ARRAY_ACCES_eff (_, teff) -> [teff]
| ARRAY_SLICE_eff (sieff,teff) ->
[Array_type_eff(teff, sieff.se_width)]
| HAT_eff(size,teff) -> [Array_type_eff(teff,size)]
| ARRAY_eff ->
(* check that args are of the same type *)
let type_args_eff = (List.map (f id_solver) args) in
let teff_elt =
List.fold_left
(fun acc teff ->
match acc with
| [] -> teff
| [sacc] -> if acc = teff then acc else
raise(EvalType_error(
"all array elements should be of the same type"))
| _ -> assert false
)
[]
type_args_eff
in
assert (List.length teff_elt = 1);
[Array_type_eff(List.hd teff_elt, List.length args)]
| WHEN_eff -> (
let type_args_eff = List.map (f id_solver) args in
match type_args_eff with
| [teff; clk_t] -> teff
| _ -> raise(EvalType_error("arity error (2 args expected)"))
)
| ARROW_eff
| FBY_eff -> (
let type_args_eff = List.map (f id_solver) args in
match type_args_eff with
| [init; teff] -> if init = teff then teff else
raise(EvalType_error("type mismatch. "))
| _ -> raise(EvalType_error("arity error (2 args expected)"))
)
| CURRENT_eff
| PRE_eff -> (
let type_args_eff = List.map (f id_solver) args in
match type_args_eff with
| [teff] -> teff
| _ -> raise(EvalType_error("arity error (1 arg expected)"))
)
| MERGE_eff _ -> finish_me "merge"; assert false
and (eval_by_name_type : id_solver -> by_name_op_eff -> Lxm.t ->
(Ident.t Lxm.srcflagged * val_exp_eff) list -> type_eff list) =
fun id_solver namop lxm namargs ->
match namop with
| STRUCT_anonymous_eff ->
(* ??? comment faire ici pour recuperer son type ???
il faut que je recherche l'aide des noms de champs
le type structure qui va bien !
- creer une table [liste des noms de champs -> ident de type structure] ?
- rajouter dans la table a sa creation une entree dont le nom
est compos du nom des champs ?
*)
finish_me "anonymous struct not yet supported";
assert false
(* failwith "Finish me: anonymous struct not yet supported" *)
| STRUCT_eff opid -> [id_solver.id2type opid lxm]