Hept Scoping should be ok and documented,

Hept Parsing too,
all the reset to review carefully,
Typing to cut from all the scoping.
master
Léonard Gérard 14 years ago committed by Léonard Gérard
parent 15448fdff9
commit a54e570d0f

@ -95,10 +95,6 @@ let rec skeleton ck = function
| Tprod ty_list -> Cprod (List.map (skeleton ck) ty_list) | Tprod ty_list -> Cprod (List.map (skeleton ck) ty_list)
| Tarray _ | Tid _ -> Ck ck | Tarray _ | Tid _ -> Ck ck
let rec const_skeleton ck se = match se.se_desc with
| Stuple se_list -> Cprod (List.map (const_skeleton ck) se_list)
| _ -> Ck ck
let ckofct = function | Ck ck -> ck_repr ck | Cprod ct_list -> Cbase let ckofct = function | Ck ck -> ck_repr ck | Cprod ct_list -> Cbase

@ -0,0 +1,59 @@
open Names
open Signature
open Types
open Clocks
open Modules
open Format
open Pp_tools
let print_qualname ff qn = match qn with
| { qual = "Pervasives"; name = n } -> print_name ff n
| { qual = m; name = n } when m = g_env.current_mod -> print_name ff n
| { qual = m; name = n } -> fprintf ff "%s.%a" m print_name n
let rec print_static_exp ff se = match se.se_desc with
| Sint i -> fprintf ff "%d" i
| Sbool b -> fprintf ff "%b" b
| Sfloat f -> fprintf ff "%f" f
| Sconstructor ln -> print_qualname ff ln
| Svar id -> fprintf ff "%a" print_qualname id
| Sop (op, se_list) ->
if is_infix (shortname op)
then
let op_s = opname op ^ " " in
fprintf ff "@[%a@]"
(print_list_l print_static_exp "(" op_s ")") se_list
else
fprintf ff "@[<2>%a@,%a@]"
print_qualname op print_static_exp_tuple se_list
| Sarray_power (se, n) ->
fprintf ff "%a^%a" print_static_exp se print_static_exp n
| Sarray se_list ->
fprintf ff "@[<2>%a@]" (print_list_r print_static_exp "["";""]") se_list
| Stuple se_list -> print_static_exp_tuple ff se_list
| Srecord f_se_list ->
print_record (print_couple print_qualname
print_static_exp """ = """) ff f_se_list
and print_static_exp_tuple ff l =
fprintf ff "@[<2>%a@]" (print_list_r print_static_exp "("","")") l
and print_type ff = function
| Tprod ty_list ->
fprintf ff "@[<hov2>%a@]" (print_list_r print_type "(" " *" ")") ty_list
| Tid id -> print_qualname ff id
| Tarray (ty, n) ->
fprintf ff "@[<hov2>%a^%a@]" print_type ty print_static_exp n
let print_size_constraint ff = function
| Cequal (e1, e2) ->
fprintf ff "@[%a = %a@]" print_static_exp e1 print_static_exp e2
| Clequal (e1, e2) ->
fprintf ff "@[%a <= %a@]" print_static_exp e1 print_static_exp e2
| Cfalse -> fprintf ff "Cfalse"
let print_param ff p =
fprintf ff "%a:%a" Names.print_name p.p_name print_type p.p_type

@ -14,14 +14,14 @@ open Types
let tglobal = [] let tglobal = []
let cglobal = [] let cglobal = []
let pbool = Modname({ qual = "Pervasives"; id = "bool" }) let pbool = { qual = "Pervasives"; name = "bool" }
let ptrue = Modname({ qual = "Pervasives"; id = "true" }) let ptrue = { qual = "Pervasives"; name = "true" }
let pfalse = Modname({ qual = "Pervasives"; id = "false" }) let pfalse = { qual = "Pervasives"; name = "false" }
let por = Modname({ qual = "Pervasives"; id = "or" }) let por = { qual = "Pervasives"; name = "or" }
let pint = Modname({ qual = "Pervasives"; id = "int" }) let pint = { qual = "Pervasives"; name = "int" }
let pfloat = Modname({ qual = "Pervasives"; id = "float" }) let pfloat = { qual = "Pervasives"; name = "float" }
let mk_pervasives s = Modname({ qual = "Pervasives"; id = s }) let mk_pervasives s = { qual = "Pervasives"; name = s }
let mk_static_int_op op args = let mk_static_int_op op args =
mk_static_exp ~ty:(Tid pint) (Sop (op,args)) mk_static_exp ~ty:(Tid pint) (Sop (op,args))
@ -37,4 +37,4 @@ let mk_static_bool b =
(* build the initial environment *) (* build the initial environment *)
let initialize () = let initialize () =
List.iter (fun (f, ty) -> Modules.add_type f ty) tglobal; List.iter (fun (f, ty) -> Modules.add_type f ty) tglobal;
List.iter (fun (f, ty) -> Modules.add_constr f ty) cglobal List.iter (fun (f, ty) -> Modules.add_constrs f ty) cglobal

@ -89,10 +89,10 @@ let print_location ff (Loc(p1,p2)) =
if f1 != f2 then (* Strange case *) if f1 != f2 then (* Strange case *)
fprintf ff fprintf ff
"File \"%s\" line %d, character %d, to file \"%s\" line %d, character %d@\n" "File \"%s\" line %d, character %d, to file \"%s\" line %d, character %d@."
f1 l1 n1 f2 l2 n2 f1 l1 n1 f2 l2 n2
else begin else begin (* Same file *)
if l2 > l1 then if l2 > l1 then
fprintf ff fprintf ff
"File \"%s\", line %d-%d, characters %d-%d:@\n" f1 l1 l2 n1 n2 "File \"%s\", line %d-%d, characters %d-%d:@\n" f1 l1 l2 n1 n2

@ -6,181 +6,254 @@
(* Organization : Demons, LRI, University of Paris-Sud, Orsay *) (* Organization : Demons, LRI, University of Paris-Sud, Orsay *)
(* *) (* *)
(**************************************************************************) (**************************************************************************)
(* global symbol tables *)
(* Module objects and global environnement management *)
open Misc open Misc
open Signature open Signature
open Names
open Types open Types
open Names
exception Already_defined exception Already_defined
exception Cannot_find_file of string
(** Warning: Whenever this type is modified, (** Warning: Whenever this type is modified,
interface_format_version in signature.ml should be incremented. *) interface_format_version in signature.ml should be incremented. *)
type env = (** Object serialized in compiled interfaces. *)
{ mutable name: string; type module_object =
mutable values: node NamesEnv.t; { m_name : string;
mutable types: type_def NamesEnv.t; m_values : node NamesEnv.t;
mutable constr: ty NamesEnv.t; m_types : type_def NamesEnv.t;
mutable structs: structure NamesEnv.t; m_consts : const_def NamesEnv.t;
mutable fields: name NamesEnv.t; m_constrs : name NamesEnv.t;
mutable consts: const_def NamesEnv.t; m_fields : name NamesEnv.t;
format_version : string; m_format_version : string; }
}
type env = {
type modules = (** Current module name *)
{ current: env; (* associated symbol table *) mutable current_mod : module_name;
mutable opened: env list; (* opened tables *) (** Modules opened and loaded into the env *)
mutable modules: env NamesEnv.t; (* tables loaded in memory *) mutable opened_mod : module_name list;
} (** Modules loaded into the env *)
mutable loaded_mod : module_name list;
let current = (** Node definitions *)
{ name = ""; values = NamesEnv.empty; types = NamesEnv.empty; mutable values : node QualEnv.t;
constr = NamesEnv.empty; structs = NamesEnv.empty; fields = NamesEnv.empty; (** Type definitions *)
consts = NamesEnv.empty; format_version = interface_format_version } mutable types : type_def QualEnv.t;
(** Constants definitions *)
let modules = mutable consts : const_def QualEnv.t;
{ current = current; opened = []; modules = NamesEnv.empty } (** Constructors mapped to their corresponding type *)
mutable constrs : qualname QualEnv.t;
let findfile filename = (** Fields mapped to their corresponding type *)
if Sys.file_exists filename then mutable fields : qualname QualEnv.t;
filename (** Accepted compiled interface version *)
else if not(Filename.is_implicit filename) then format_version : string }
raise(Cannot_find_file filename)
(** The global environnement *)
let g_env =
{ current_mod = "";
opened_mod = [];
loaded_mod = [];
values = QualEnv.empty;
types = QualEnv.empty;
constrs = QualEnv.empty;
fields = QualEnv.empty;
consts = QualEnv.empty;
format_version = interface_format_version }
let is_loaded m = List.mem m g_env.loaded_mod
let is_opened m = List.mem m g_env.opened_mod
(** Append a module to the global environnment *)
let _append_module mo =
(* Transforms a module object NamesEnv into its qualified version *)
let qualify mo_env = (* qualify env keys *)
NamesEnv.fold
(fun x v env -> QualEnv.add { qual = mo.m_name; name = x } v env)
mo_env QualEnv.empty in
let qualify_all mo_env = (* qualify env keys and values *)
NamesEnv.fold
(fun x v env ->
QualEnv.add {qual= mo.m_name; name= x} {qual= mo.m_name; name= v} env)
mo_env QualEnv.empty in
g_env.values <- QualEnv.append (qualify mo.m_values) g_env.values;
g_env.types <- QualEnv.append (qualify mo.m_types) g_env.types;
g_env.constrs <- QualEnv.append (qualify_all mo.m_constrs) g_env.constrs;
g_env.fields <- QualEnv.append (qualify_all mo.m_fields) g_env.fields;
g_env.consts <- QualEnv.append (qualify mo.m_consts) g_env.consts
(** Load a module into the global environnement unless already loaded *)
let _load_module modname =
if is_loaded modname then ()
else else
let rec find = function let name = String.uncapitalize modname in
[] -> let filename = Misc.findfile (name ^ ".epci") in
raise(Cannot_find_file filename) let ic =
| a::rest -> try
let b = Filename.concat a filename in open_in_bin filename
if Sys.file_exists b then b else find rest with
in find !load_path | Misc.Cannot_find_file(f) ->
Format.eprintf "Cannot find the compiled interface file %s.@." f;
let load_module modname = raise Error in
let name = String.uncapitalize modname in let mo:module_object =
try try
let filename = findfile (name ^ ".epci") in input_value ic
let ic = open_in_bin filename in with
try | End_of_file | Failure _ ->
let m:env = input_value ic in close_in ic;
if m.format_version <> interface_format_version then ( Format.eprintf "Corrupted compiled interface file %s.@\n\
Format.eprintf "The file %s was compiled with \ Please recompile %s.ept first.@." filename name;
an older version of the compiler.@\n \ raise Error in
Please recompile %s.ept first.@." filename name; if mo.m_format_version <> interface_format_version
raise Error then (
); Format.eprintf "The file %s was compiled with an older version \
close_in ic; of the compiler.@\nPlease recompile %s.ept first.@."
m filename name;
with raise Error );
| End_of_file | Failure _ -> _append_module mo
close_in ic;
Format.eprintf "Corrupted compiled interface file %s.@\n\
Please recompile %s.ept first.@." filename name;
raise Error (** Opens a module unless already opened
with by loading it into the global environnement and seting it as opened *)
| Cannot_find_file(filename) ->
Format.eprintf "Cannot find the compiled interface file %s.@."
filename;
raise Error
let find_module modname =
try
NamesEnv.find modname modules.modules
with
Not_found ->
let m = load_module modname in
modules.modules <- NamesEnv.add modname m modules.modules;
m
type 'a info = { qualid : qualident; info : 'a }
let find where qualname =
let rec findrec ident = function
| [] -> raise Not_found
| m :: l ->
try { qualid = { qual = m.name; id = ident };
info = where ident m }
with Not_found -> findrec ident l in
match qualname with
| Modname({ qual = m; id = ident } as q) ->
let current = if current.name = m then current else find_module m in
{ qualid = q; info = where ident current }
| Name(ident) -> findrec ident (current :: modules.opened)
(* exported functions *)
let open_module modname = let open_module modname =
let m = find_module modname in if is_opened modname then ()
modules.opened <- m :: modules.opened else
_load_module modname;
g_env.opened_mod <- modname::g_env.opened_mod
(** Initialize the global environnement :
set current module and open default modules *)
let initialize modname = let initialize modname =
current.name <- modname; g_env.current_mod <- modname;
g_env.opened_mod <- [];
g_env.loaded_mod <- [modname];
List.iter open_module !default_used_modules List.iter open_module !default_used_modules
let add_value f signature =
if NamesEnv.mem f current.values then raise Already_defined; (** { 3 Add functions prevent redefinitions } *)
current.values <- NamesEnv.add f signature current.values
let add_type f type_def = let _check_not_defined env f =
if NamesEnv.mem f current.types then raise Already_defined; if QualEnv.mem f env then raise Already_defined
current.types <- NamesEnv.add f type_def current.types
let add_constr f ty_res = let add_value f v =
if NamesEnv.mem f current.constr then raise Already_defined; _check_not_defined g_env.values f;
current.constr <- NamesEnv.add f ty_res current.constr g_env.values <- QualEnv.add f v g_env.values
let add_struct f fields = let add_type f v =
if NamesEnv.mem f current.structs then raise Already_defined; _check_not_defined g_env.types f;
current.structs <- NamesEnv.add f fields current.structs g_env.types <- QualEnv.add f v g_env.types
let add_field f n = let add_constrs f v =
if NamesEnv.mem f current.fields then raise Already_defined; _check_not_defined g_env.constrs f;
current.fields <- NamesEnv.add f n current.fields g_env.constrs <- QualEnv.add f v g_env.constrs
let add_const f n = let add_field f v =
if NamesEnv.mem f current.consts then raise Already_defined; _check_not_defined g_env.fields f;
current.consts <- NamesEnv.add f n current.consts g_env.fields <- QualEnv.add f v g_env.fields
let add_const f v =
let add_value_by_longname ln signature = _check_not_defined g_env.consts f;
match ln with g_env.consts <- QualEnv.add f v g_env.consts
| Modname { qual = modname; id = f } ->
let m =
if modname = current.name then (** { 3 Find functions look in the global environnement, nothing more } *)
current
else let _check_loaded_module m =
NamesEnv.find modname modules.modules in if not (List.mem m g_env.loaded_mod)
if not (NamesEnv.mem f m.values) then then (
m.values <- NamesEnv.add f signature m.values Format.eprintf "The module %s was not loaded." m;
| Name _ -> raise Not_found raise Error )
let find_value = find (fun ident m -> NamesEnv.find ident m.values) let _find env x =
let find_type = find (fun ident m -> NamesEnv.find ident m.types) try QualEnv.find x env
let find_constr = find (fun ident m -> NamesEnv.find ident m.constr) with Not_found ->
let find_struct = find (fun ident m -> NamesEnv.find ident m.structs) _check_loaded_module x.qual; (* should never arrive, sanity check *)
let find_field = find (fun ident m -> NamesEnv.find ident m.fields) raise Not_found
let find_const = find (fun ident m -> NamesEnv.find ident m.consts)
let find_value = _find g_env.values
let replace_value f signature = let find_type = _find g_env.types
current.values <- NamesEnv.remove f current.values; let find_constrs = _find g_env.constrs
current.values <- NamesEnv.add f signature current.values let find_field = _find g_env.fields
let find_const = _find g_env.consts
let write oc = output_value oc current
let longname n = Modname({ qual = current.name; id = n }) (** { 3 Load_check functions }
let currentname longname = Try to load the needed module and then to find it,
match longname with return true if in the table, return false if it can't find it. *)
| Name(n) -> longname
| Modname{ qual = q; id = id} -> let _check env q =
if current.name = q then Name(id) else longname _load_module q.qual;
try let _ = QualEnv.find q env in true
exception Undefined_type of longname with Not_found -> false
(** @return the unaliased version of a type. *)
let rec unalias_type = function let check_value = _check g_env.values
let check_type = _check g_env.types
let check_constrs = _check g_env.constrs
let check_field = _check g_env.fields
let check_const = _check g_env.consts
(** { 3 Qualify functions [qualify_* name] return the qualified name
matching [name] in the global env scope (current module :: opened modules).
@raise [Not_found] if not in scope } *)
let _qualify env name =
let tries m =
try
let _ = QualEnv.find { qual = m; name = name } env in
true
with Not_found -> false in
let m = List.find tries (g_env.current_mod::g_env.opened_mod) in
{ qual = m; name = name }
let qualify_value = _qualify g_env.values
let qualify_type = _qualify g_env.types
let qualify_constrs = _qualify g_env.constrs
let qualify_field = _qualify g_env.fields
let qualify_const = _qualify g_env.consts
(** @return the name as qualified with the current module *)
let current_qual n = { qual = g_env.current_mod; name = n }
exception Undefined_type of qualname
(** @return the unaliased version of a type. @raise Undefined_type *)
let rec unalias_type t = match t with
| Tid ty_name -> | Tid ty_name ->
(try (try
let { qualid = q; info = ty_desc } = find_type ty_name in match find_type ty_name with
match ty_desc with | Talias ty -> unalias_type ty
| Talias ty -> unalias_type ty | _ -> t
| _ -> Tid (Modname q)
with Not_found -> raise (Undefined_type ty_name)) with Not_found -> raise (Undefined_type ty_name))
| Tarray (ty, n) -> Tarray(unalias_type ty, n) | Tarray (ty, n) -> Tarray(unalias_type ty, n)
| Tprod ty_list -> Tprod (List.map unalias_type ty_list) | Tprod ty_list -> Tprod (List.map unalias_type ty_list)
(** Write the current module as a [module_object] to oc *)
let write_current_module oc =
(* Filter and transform a qualified env into the current module object env *)
let unqualify env = (* unqualify env keys *)
QualEnv.fold
(fun x v current ->
if x.qual = g_env.current_mod
then NamesEnv.add x.name v current
else current) env NamesEnv.empty in
let unqualify_all env = (* unqualify env keys and values *)
QualEnv.fold
(fun x v current ->
if x.qual = g_env.current_mod
then NamesEnv.add x.name v.name current
else current) env NamesEnv.empty in
let current =
{ m_name = g_env.current_mod;
m_values = unqualify g_env.values;
m_types = unqualify g_env.types;
m_constrs = unqualify_all g_env.constrs;
m_fields = unqualify_all g_env.fields;
m_consts = unqualify g_env.consts;
m_format_version = g_env.format_version } in
output_value oc current

@ -4,60 +4,46 @@
type name = string type name = string
type longname = and qualname = { qual: string; name: string }
| Name of name
| Modname of qualident
and qualident = { qual: string; id: string } type type_name = qualname
type fun_name = qualname
type field_name = qualname
type constructor_name = qualname
type constant_name = qualname
type module_name = name
type type_name = longname
type fun_name = longname let local_qualname = "$$%local_current_illegal_module_name%$$"
let local_qn name = { qual = local_qualname; name = name }
type field_name = longname module NamesEnv = struct
include (Map.Make(struct type t = name let compare = compare end))
type constructor_name = longname let append env0 env = fold (fun key v env -> add key v env) env0 env
type constant_name = longname
module NamesM = struct
type t = name
let compare = compare
end end
module NamesEnv = module QualEnv = struct
struct include (Map.Make(struct type t = qualname let compare = compare end))
include (Map.Make(NamesM))
let append env0 env = (** [append env' env] appends env' to env *)
fold (fun key v env -> add key v env) env0 env let append env' env = fold (fun key v env -> add key v env) env' env
end end
module LongNameEnv = Map.Make (struct
type t = longname
let compare = compare
end)
module S = Set.Make (struct type t = string let compare = compare end) module S = Set.Make (struct type t = string let compare = compare end)
let shortname = function let shortname { name = n; } = n
| Name s -> s
| Modname { id = id; } -> id
let fullname = function let fullname { qual = qual; name = n; } = qual ^ "." ^ n
| Name s -> s
| Modname { qual = qual; id = id; } -> qual ^ "." ^ id
let mk_longname s = let qualname_of_string s =
try try
let ind = String.index s '.' in let ind = String.index s '.' in
if ind = 0 || ind = String.length s - 1 if ind = 0 || ind = String.length s - 1
then invalid_arg "mk_longname: ill-formed identifier"; then invalid_arg "mk_longname: ill-formed identifier";
let id = String.sub s (ind + 1) (String.length s - ind - 1) in let n = String.sub s (ind + 1) (String.length s - ind - 1) in
Modname { qual = String.sub s 0 ind; id = id; } { qual = String.sub s 0 ind; name = n; }
with Not_found -> Name s with Not_found -> { qual = ""; name = s }
(** Are infix (** Are infix
[or], [quo], [mod], [land], [lor], [lxor], [lsl], [lsr], [asr] [or], [quo], [mod], [land], [lor], [lxor], [lsl], [lsr], [asr]
@ -73,22 +59,15 @@ let is_infix s =
| 'a' .. 'z' | 'A' .. 'Z' | '_' | '`' -> false | 'a' .. 'z' | 'A' .. 'Z' | '_' | '`' -> false
| _ -> true) | _ -> true)
open Format
let print_name ff n = let print_name ff n =
let n = if is_infix n let n = if is_infix n
then "( " ^ (n ^ " )") (* do not remove the space around n, since for example then "( " ^ (n ^ " )") (* do not remove the space around n, since for example
"(*" would create bugs *) "(*" would create bugs *)
else n else n
in Format.fprintf ff "%s" n in fprintf ff "%s" n
let print_longname ff n = let opname qn = match qn with
match n with | { qual = "Pervasives"; name = m; } -> m
| Name m -> print_name ff m | { qual = qual; name = n; } -> qual ^ "." ^ n
| Modname { qual = "Pervasives"; id = m } -> print_name ff m
| Modname { qual = m1; id = m2 } ->
Format.fprintf ff "%s." m1;
print_name ff m2
let opname ln = match ln with
| Name n -> n
| Modname { qual = "Pervasives"; id = m; } -> m
| Modname { qual = qual; id = id; } -> qual ^ "." ^ id

@ -12,7 +12,7 @@ open Types
(** Warning: Whenever these types are modified, (** Warning: Whenever these types are modified,
interface_format_version should be incremented. *) interface_format_version should be incremented. *)
let interface_format_version = "10" let interface_format_version = "20"
(** Node argument *) (** Node argument *)
type arg = { a_name : name option; a_type : ty } type arg = { a_name : name option; a_type : ty }
@ -20,30 +20,30 @@ type arg = { a_name : name option; a_type : ty }
(** Node static parameters *) (** Node static parameters *)
type param = { p_name : name; p_type : ty } type param = { p_name : name; p_type : ty }
(** Constraints on size expressions. *) (** Constraints on size expressions *)
type size_constraint = type size_constraint =
| Cequal of static_exp * static_exp (* e1 = e2*) | Cequal of static_exp * static_exp (* e1 = e2 *)
| Clequal of static_exp * static_exp (* e1 <= e2 *) | Clequal of static_exp * static_exp (* e1 <= e2 *)
| Cfalse | Cfalse
(** Node signature *) (** Node signature *)
type node = type node = {
{ node_inputs : arg list; node_inputs : arg list;
node_outputs : arg list; node_outputs : arg list;
node_statefull : bool; node_statefull : bool;
node_params : param list; (** Static parameters *) node_params : param list;
node_params_constraints : size_constraint list } node_params_constraints : size_constraint list }
type field = { f_name : name; f_type : ty } type field = { f_name : field_name; f_type : ty }
type structure = field list type structure = field list
type type_def = type type_def =
| Tabstract | Tabstract
| Talias of ty | Talias of ty
| Tenum of name list | Tenum of constructor_name list
| Tstruct of structure | Tstruct of structure
type const_def = { c_name : name; c_type : ty; c_value : static_exp } type const_def = { c_type : ty; c_value : static_exp }
let names_of_arg_list l = List.map (fun ad -> ad.a_name) l let names_of_arg_list l = List.map (fun ad -> ad.a_name) l
@ -55,18 +55,20 @@ let mk_param name ty = { p_name = name; p_type = ty }
let mk_field n ty = { f_name = n; f_type = ty } let mk_field n ty = { f_name = n; f_type = ty }
let mk_const_def name ty value = let mk_const_def ty value =
{ c_name = name; c_type = ty; c_value = value } { c_type = ty; c_value = value }
let mk_node ?(constraints = []) ins outs statefull params =
{ node_inputs = ins;
node_outputs = outs;
node_statefull = statefull;
node_params = params;
node_params_constraints = constraints }
let rec field_assoc f = function let rec field_assoc f = function
| [] -> raise Not_found | [] -> raise Not_found
| { f_name = n; f_type = ty }::l -> | { f_name = n; f_type = ty }::l ->
if shortname f = n then ty if f = n then ty
else field_assoc f l else field_assoc f l
open Format
let print_param ff p =
fprintf ff "%a:%a" Names.print_name p.p_name print_type p.p_type

@ -10,8 +10,7 @@
(** This module defines static expressions, used in params and for constants. (** This module defines static expressions, used in params and for constants.
const n: int = 3; const n: int = 3;
var x : int^n; var y : int^(n + 2); var x : int^n; var y : int^(n + 2);
x[n - 1], x[1 + 3],... x[n - 1], x[1 + 3],... *)
*)
open Names open Names
open Format open Format
@ -25,34 +24,26 @@ exception Partial_instanciation of static_exp
exception Not_static exception Not_static
(** Returns the op from an operator full name. *)
let op_from_app_name ln =
match ln with
| Modname { qual = "Pervasives" } -> ln
| _ -> raise Not_static
let partial_apply_op op se_list = let partial_apply_op op se_list =
match se_list with match se_list with
| [{ se_desc = Sint n1 }; { se_desc = Sint n2 }] -> | [{ se_desc = Sint n1 }; { se_desc = Sint n2 }] ->
(match op with (match op with
| Modname { qual = "Pervasives"; id = "+" } -> | { qual = "Pervasives"; name = "+" } ->
Sint (n1 + n2) Sint (n1 + n2)
| Modname { qual = "Pervasives"; id = "-" } -> | { qual = "Pervasives"; name = "-" } ->
Sint (n1 - n2) Sint (n1 - n2)
| Modname { qual = "Pervasives"; id = "*" } -> | { qual = "Pervasives"; name = "*" } ->
Sint (n1 * n2) Sint (n1 * n2)
| Modname { qual = "Pervasives"; id = "/" } -> | { qual = "Pervasives"; name = "/" } ->
let n = if n2 = 0 then raise Instanciation_failed else n1 / n2 in let n = if n2 = 0 then raise Instanciation_failed else n1 / n2 in
Sint n Sint n
| Modname { qual = "Pervasives"; id = "=" } -> | { qual = "Pervasives"; name = "=" } ->
Sbool (n1 = n2) Sbool (n1 = n2)
| _ -> assert false (*TODO: add missing operators*) | _ -> assert false (*TODO: add missing operators*)
) )
| [{ se_desc = Sint n }] -> | [{ se_desc = Sint n }] ->
(match op with (match op with
| Modname { qual = "Pervasives"; id = "~-" } -> Sint (-n) | { qual = "Pervasives"; name = "~-" } -> Sint (-n)
| _ -> assert false (*TODO: add missing operators*) | _ -> assert false (*TODO: add missing operators*)
) )
| _ -> Sop(op, se_list) | _ -> Sop(op, se_list)
@ -67,12 +58,10 @@ let eval_core eval apply_op env se = match se.se_desc with
| Sint _ | Sfloat _ | Sbool _ | Sconstructor _ -> se | Sint _ | Sfloat _ | Sbool _ | Sconstructor _ -> se
| Svar ln -> ( | Svar ln -> (
try (* first try to find in global const env *) try (* first try to find in global const env *)
let { info = cd } = find_const ln in let cd = find_const ln in
eval env cd.c_value eval env cd.c_value
with Not_found -> ( with Not_found -> (* then try to find in local env *)
match ln with (* then try to find in local env *) eval env (QualEnv.find ln env))
| Name n -> eval env (NamesEnv.find n env)
| Modname _ -> raise Not_found ) )
| Sop (op, se_list) -> | Sop (op, se_list) ->
let se_list = List.map (eval env) se_list in let se_list = List.map (eval env) se_list in
{ se with se_desc = apply_op op se_list } { se with se_desc = apply_op op se_list }
@ -109,7 +98,8 @@ let int_of_static_exp env se =
| Sint i -> i | Sint i -> i
| _ -> | _ ->
(Format.eprintf "Internal compiler error, \ (Format.eprintf "Internal compiler error, \
[eval_int] received the static_exp %a.@." Types.print_static_exp se; [eval_int] received the static_exp %a.@."
Global_printer.print_static_exp se;
assert false) assert false)
(** [is_true env constr] returns whether the constraint is satisfied (** [is_true env constr] returns whether the constraint is satisfied
@ -152,10 +142,7 @@ let rec solve const_env =
in the map (mapping vars to size exps). *) in the map (mapping vars to size exps). *)
let rec static_exp_subst m se = let rec static_exp_subst m se =
match se.se_desc with match se.se_desc with
| Svar ln -> | Svar qn -> (try QualEnv.find qn m with | Not_found -> se)
(match ln with
| Name n -> (try NamesEnv.find n m with | Not_found -> se)
| Modname _ -> se)
| Sop (op, se_list) -> | Sop (op, se_list) ->
{ se with se_desc = Sop (op, List.map (static_exp_subst m) se_list) } { se with se_desc = Sop (op, List.map (static_exp_subst m) se_list) }
| Sarray_power (se, n) -> | Sarray_power (se, n) ->
@ -181,12 +168,3 @@ let instanciate_constr m constr =
List.map (replace_one m) constr List.map (replace_one m) constr
open Format
let print_size_constraint ff = function
| Cequal (e1, e2) ->
fprintf ff "@[%a = %a@]" print_static_exp e1 print_static_exp e2
| Clequal (e1, e2) ->
fprintf ff "@[%a <= %a@]" print_static_exp e1 print_static_exp e2
| Cfalse -> fprintf ff "Cfalse"

@ -34,47 +34,9 @@ let prod = function
| [ty] -> ty | [ty] -> ty
| ty_list -> Tprod ty_list | ty_list -> Tprod ty_list
(** DO NOT use this after the typing, since it could give invalid_type *) (** DO NOT use this after the typing, since it could give invalid_type *)
let mk_static_exp ?(loc = no_location) ?(ty = invalid_type) desc = let mk_static_exp ?(loc = no_location) ?(ty = invalid_type) desc =
{ se_desc = desc; se_ty = ty; se_loc = loc } { se_desc = desc; se_ty = ty; se_loc = loc }
open Pp_tools
open Format
let rec print_static_exp ff se = match se.se_desc with
| Sint i -> fprintf ff "%d" i
| Sbool b -> fprintf ff "%b" b
| Sfloat f -> fprintf ff "%f" f
| Sconstructor ln -> print_longname ff ln
| Svar id -> fprintf ff "%a" print_longname id
(* | Sop (op, [e_l; e_r]) -> *)
(* fprintf ff "(@[<2>%a@ %a %a@])" *)
(* print_static_exp e_l print_longname op print_static_exp r *)
| Sop (op, se_list) ->
if is_infix (shortname op)
then
let op_s = opname op ^ " " in
fprintf ff "@[%a@]"
(print_list_l print_static_exp "(" op_s ")") se_list
else
fprintf ff "@[<2>%a@,%a@]"
print_longname op print_static_exp_tuple se_list
| Sarray_power (se, n) ->
fprintf ff "%a^%a" print_static_exp se print_static_exp n
| Sarray se_list ->
fprintf ff "@[<2>%a@]" (print_list_r print_static_exp "["";""]") se_list
| Stuple se_list -> print_static_exp_tuple ff se_list
| Srecord f_se_list ->
print_record (print_couple print_longname
print_static_exp """ = """) ff f_se_list
and print_static_exp_tuple ff l =
fprintf ff "@[<2>%a@]" (print_list_r print_static_exp "("","")") l
and print_type ff = function
| Tprod ty_list ->
fprintf ff "@[<hov2>%a@]" (print_list_r print_type "(" " *" ")") ty_list
| Tid id -> print_longname ff id
| Tarray (ty, n) ->
fprintf ff "@[<hov2>%a^%a@]" print_type ty print_static_exp n

@ -13,7 +13,6 @@ open Names
open Heptagon open Heptagon
open Signature open Signature
open Modules open Modules
open Typing
open Pp_tools open Pp_tools
open Types open Types
@ -21,7 +20,8 @@ module Type =
struct struct
let sigtype { sig_name = name; sig_inputs = i_list; sig_statefull = statefull; let sigtype { sig_name = name; sig_inputs = i_list; sig_statefull = statefull;
sig_outputs = o_list; sig_params = params } = sig_outputs = o_list; sig_params = params } =
let typed_params, const_env = build_node_params NamesEnv.empty params in let typed_params, const_env =
Typing.build_node_params NamesEnv.empty params in
let check_arg a = { a with a_type = check_type const_env a.a_type } in let check_arg a = { a with a_type = check_type const_env a.a_type } in
name, { node_inputs = List.map check_arg i_list; name, { node_inputs = List.map check_arg i_list;
node_outputs = List.map check_arg o_list; node_outputs = List.map check_arg o_list;

@ -40,7 +40,7 @@ let edesc funs statefull ed =
| Efby _ | Epre _ -> ed, true | Efby _ | Epre _ -> ed, true
| Eapp({ a_op = Earrow }, _, _) -> ed, true | Eapp({ a_op = Earrow }, _, _) -> ed, true
| Eapp({ a_op = (Enode f | Efun f) } as app, e_list, r) -> | Eapp({ a_op = (Enode f | Efun f) } as app, e_list, r) ->
let { qualid = q; info = ty_desc } = find_value f in let ty_desc = find_value f in
let op = if ty_desc.node_statefull then Enode f else Efun f in let op = if ty_desc.node_statefull then Enode f else Efun f in
Eapp({ app with a_op = op }, e_list, r), Eapp({ app with a_op = op }, e_list, r),
ty_desc.node_statefull or statefull ty_desc.node_statefull or statefull

@ -17,6 +17,7 @@ open Modules
open Initial open Initial
open Static open Static
open Types open Types
open Global_printer
open Heptagon open Heptagon
open Hept_mapfold open Hept_mapfold
@ -38,11 +39,11 @@ type error =
| Esome_fields_are_missing | Esome_fields_are_missing
| Esubscripted_value_not_an_array of ty | Esubscripted_value_not_an_array of ty
| Earray_subscript_should_be_const | Earray_subscript_should_be_const
| Eundefined_const of longname | Eundefined_const of qualname
| Econstraint_solve_failed of size_constraint | Econstraint_solve_failed of size_constraint
| Etype_should_be_static of ty | Etype_should_be_static of ty
| Erecord_type_expected of ty | Erecord_type_expected of ty
| Eno_such_field of ty * longname | Eno_such_field of ty * qualname
| Eempty_record | Eempty_record
| Eempty_array | Eempty_array
| Efoldi_bad_args of ty | Efoldi_bad_args of ty
@ -78,8 +79,8 @@ let message loc kind =
Format.eprintf "%aType Clash: this expression has type %a, @\n\ Format.eprintf "%aType Clash: this expression has type %a, @\n\
but is expected to have type %a.@." but is expected to have type %a.@."
print_location loc print_location loc
Types.print_type actual_ty print_type actual_ty
Types.print_type expected_ty print_type expected_ty
| Earity_clash(actual_arit, expected_arit) -> | Earity_clash(actual_arit, expected_arit) ->
Format.eprintf "%aType Clash: this expression expects %d arguments,@\n\ Format.eprintf "%aType Clash: this expression expects %d arguments,@\n\
but is expected to have %d.@." but is expected to have %d.@."
@ -116,7 +117,7 @@ let message loc kind =
Format.eprintf Format.eprintf
"%aSubscript used on a non array type : %a.@." "%aSubscript used on a non array type : %a.@."
print_location loc print_location loc
Types.print_type ty Global_printer.print_type ty
| Earray_subscript_should_be_const -> | Earray_subscript_should_be_const ->
Format.eprintf Format.eprintf
"%aSubscript has to be a static value.@." "%aSubscript has to be a static value.@."
@ -135,17 +136,17 @@ let message loc kind =
Format.eprintf Format.eprintf
"%aThis type should be static : %a.@." "%aThis type should be static : %a.@."
print_location loc print_location loc
Types.print_type ty print_type ty
| Erecord_type_expected ty -> | Erecord_type_expected ty ->
Format.eprintf Format.eprintf
"%aA record was expected (found %a).@." "%aA record was expected (found %a).@."
print_location loc print_location loc
Types.print_type ty print_type ty
| Eno_such_field (ty, f) -> | Eno_such_field (ty, f) ->
Format.eprintf Format.eprintf
"%aThe record type '%a' does not have a '%s' field.@." "%aThe record type '%a' does not have a '%s' field.@."
print_location loc print_location loc
Types.print_type ty print_type ty
(shortname f) (shortname f)
| Eempty_record -> | Eempty_record ->
Format.eprintf Format.eprintf
@ -160,7 +161,7 @@ let message loc kind =
"%aThe function given to foldi should expect an integer \ "%aThe function given to foldi should expect an integer \
as the last but one argument (found: %a).@." as the last but one argument (found: %a).@."
print_location loc print_location loc
Types.print_type ty print_type ty
end; end;
raise Error raise Error
@ -296,11 +297,10 @@ let simplify_type loc ty =
Instanciation_failed -> message loc (Etype_should_be_static ty) Instanciation_failed -> message loc (Etype_should_be_static ty)
let build_subst names values = let build_subst names values =
if List.length names <> List.length values then if List.length names <> List.length values
error (Estatic_arity_clash (List.length values, List.length names)); then error (Estatic_arity_clash (List.length values, List.length names));
List.fold_left2 (fun m n v -> QualEnv.add n v m)
List.fold_left2 (fun m { p_name = n } v -> NamesEnv.add n v m) QualEnv.empty names values
NamesEnv.empty names values
let rec subst_type_vars m = function let rec subst_type_vars m = function
| Tarray(ty, e) -> Tarray(subst_type_vars m ty, static_exp_subst m e) | Tarray(ty, e) -> Tarray(subst_type_vars m ty, static_exp_subst m e)
@ -407,7 +407,7 @@ let check_static_field_unicity l =
[loc] is the location used for error reporting.*) [loc] is the location used for error reporting.*)
let struct_info_from_name n = let struct_info_from_name n =
try try
let { qualid = q; let { qualname = q;
info = fields } = find_struct n in info = fields } = find_struct n in
q, fields q, fields
with with
@ -426,18 +426,19 @@ let struct_info ty = match ty with
[loc] is the location used for error reporting.*) [loc] is the location used for error reporting.*)
let struct_info_from_field f = let struct_info_from_field f =
try try
let { qualid = q; info = n } = find_field f in let { qualname = q; info = n } = find_field f in
struct_info_from_name (Modname { qual = q.qual; id = n }) struct_info_from_name { qual = q.qual; name = n }
with with
Not_found -> error (Eundefined (fullname f)) Not_found -> error (Eundefined (fullname f))
(** [check_type t] checks that t exists *) (** [check_type t] checks that t exists *)
(*TODO should be already done in scoping *)
let rec check_type const_env = function let rec check_type const_env = function
| Tarray(ty, e) -> | Tarray(ty, e) ->
let typed_e = expect_static_exp const_env (Tid Initial.pint) e in let typed_e = expect_static_exp const_env (Tid Initial.pint) e in
Tarray(check_type const_env ty, typed_e) Tarray(check_type const_env ty, typed_e)
| Tid ty_name -> | Tid ty_name ->
(try Tid(Modname((find_type ty_name).qualid)) (try Tid((find_type ty_name).qualname)
with Not_found -> error (Eundefined(fullname ty_name))) with Not_found -> error (Eundefined(fullname ty_name)))
| Tprod l -> | Tprod l ->
Tprod (List.map (check_type const_env) l) Tprod (List.map (check_type const_env) l)
@ -450,23 +451,20 @@ and typing_static_exp const_env se =
| Sfloat v -> Sfloat v, Tid Initial.pfloat | Sfloat v -> Sfloat v, Tid Initial.pfloat
| Svar ln -> | Svar ln ->
(try (* this can be a global const*) (try (* this can be a global const*)
let { qualid = q; info = cd } = Modules.find_const ln in let { qualname = q; info = cd } = Modules.find_const ln in
Svar (Modname q), cd.Signature.c_type Svar q, cd.Signature.c_type
(* TODO verifier... *)
with Not_found -> (* or a static parameter *) with Not_found -> (* or a static parameter *)
(match ln with (try Svar ln, QualEnv.find ln const_env
| Name n -> with Not_found -> error (Eundefined_const ln) ) )
(try Svar ln, NamesEnv.find n const_env
with Not_found -> error (Eundefined_const ln))
| Modname _ -> error (Eundefined_const ln))
)
| Sconstructor c -> | Sconstructor c ->
let { qualid = q; info = ty } = find_constr c in let { qualname = q; info = ty } = find_constr c in
Sconstructor(Modname q), ty Sconstructor q, ty
| Sop (op, se_list) -> | Sop (op, se_list) ->
let { qualid = q; info = ty_desc } = find_value op in let { qualname = q; info = ty_desc } = find_value op in
let typed_se_list = typing_static_args const_env let typed_se_list = typing_static_args const_env
(types_of_arg_list ty_desc.node_inputs) se_list in (types_of_arg_list ty_desc.node_inputs) se_list in
Sop (Modname q, typed_se_list), Sop (q, typed_se_list),
prod (types_of_arg_list ty_desc.node_outputs) prod (types_of_arg_list ty_desc.node_outputs)
| Sarray_power (se, n) -> | Sarray_power (se, n) ->
let typed_n = expect_static_exp const_env (Tid Initial.pint) n in let typed_n = expect_static_exp const_env (Tid Initial.pint) n in
@ -496,8 +494,8 @@ and typing_static_exp const_env se =
check_static_field_unicity f_se_list; check_static_field_unicity f_se_list;
let f_se_list = let f_se_list =
List.map (typing_static_field const_env fields List.map (typing_static_field const_env fields
(Tid (Modname q)) q.qual) f_se_list in (Tid q) q.qual) f_se_list in
Srecord f_se_list, Tid (Modname q) Srecord f_se_list, Tid q
in in
{ se with se_ty = ty; se_desc = desc }, ty { se with se_ty = ty; se_desc = desc }, ty
@ -508,7 +506,7 @@ and typing_static_field const_env fields t1 modname (f,se) =
try try
let ty = check_type const_env (field_assoc f fields) in let ty = check_type const_env (field_assoc f fields) in
let typed_se = expect_static_exp const_env ty se in let typed_se = expect_static_exp const_env ty se in
Modname { qual = modname; id = shortname f }, typed_se { qual = modname; name = shortname f }, typed_se
with with
Not_found -> message se.se_loc (Eno_such_field (t1, f)) Not_found -> message se.se_loc (Eno_such_field (t1, f))
@ -563,8 +561,8 @@ let rec typing const_env h e =
check_field_unicity l; check_field_unicity l;
let l = let l =
List.map (typing_field List.map (typing_field
const_env h fields (Tid (Modname q)) q.qual) l in const_env h fields (Tid q) q.qual) l in
Estruct l, Tid (Modname q) Estruct l, Tid q
| Epre (None, e) -> | Epre (None, e) ->
let typed_e,ty = typing const_env h e in let typed_e,ty = typing const_env h e in
@ -583,9 +581,12 @@ let rec typing const_env h e =
| Eiterator (it, ({ a_op = (Enode f | Efun f); | Eiterator (it, ({ a_op = (Enode f | Efun f);
a_params = params } as app), a_params = params } as app),
n, e_list, reset) -> n, e_list, reset) ->
let { qualid = q; info = ty_desc } = find_value f in let { qualname = q; info = ty_desc } = find_value f in
let op, expected_ty_list, result_ty_list = kind (Modname q) ty_desc in let op, expected_ty_list, result_ty_list = kind q ty_desc in
let m = build_subst ty_desc.node_params params in (*TODO verifier....*)
let node_params =
List.map (fun { p_name = n } -> local_qn n) ty_desc.node_params in
let m = build_subst node_params params in
let expected_ty_list = let expected_ty_list =
List.map (subst_type_vars m) expected_ty_list in List.map (subst_type_vars m) expected_ty_list in
let result_ty_list = List.map (subst_type_vars m) result_ty_list in let result_ty_list = List.map (subst_type_vars m) result_ty_list in
@ -611,7 +612,7 @@ and typing_field const_env h fields t1 modname (f, e) =
try try
let ty = check_type const_env (field_assoc f fields) in let ty = check_type const_env (field_assoc f fields) in
let typed_e = expect const_env h ty e in let typed_e = expect const_env h ty e in
Modname { qual = modname; id = shortname f }, typed_e { qual = modname; name = shortname f }, typed_e
with with
Not_found -> message e.e_loc (Eno_such_field (t1, f)) Not_found -> message e.e_loc (Eno_such_field (t1, f))
@ -642,9 +643,12 @@ and typing_app const_env h op e_list =
t1, op, [typed_e1; typed_e2; typed_e3] t1, op, [typed_e1; typed_e2; typed_e3]
| { a_op = (Efun f | Enode f); a_params = params } as app, e_list -> | { a_op = (Efun f | Enode f); a_params = params } as app, e_list ->
let { qualid = q; info = ty_desc } = find_value f in let { qualname = q; info = ty_desc } = find_value f in
let op, expected_ty_list, result_ty_list = kind (Modname q) ty_desc in let op, expected_ty_list, result_ty_list = kind q ty_desc in
let m = build_subst ty_desc.node_params params in (*TODO verifier....*)
let node_params =
List.map (fun { p_name = n } -> local_qn n) ty_desc.node_params in
let m = build_subst node_params params in
let expected_ty_list = List.map (subst_type_vars m) expected_ty_list in let expected_ty_list = List.map (subst_type_vars m) expected_ty_list in
let typed_e_list = typing_args const_env h let typed_e_list = typing_args const_env h
expected_ty_list e_list in expected_ty_list e_list in
@ -678,7 +682,7 @@ and typing_app const_env h op e_list =
let typed_e, t1 = typing const_env h e in let typed_e, t1 = typing const_env h e in
let q, fields = struct_info t1 in let q, fields = struct_info t1 in
let t2 = field_type const_env fn fields t1 e.e_loc in let t2 = field_type const_env fn fields t1 e.e_loc in
let fn = Modname { qual = q.qual; id = shortname fn } in let fn = { qual = q.qual; name = shortname fn } in
let f = { f with se_desc = Sconstructor fn } in let f = { f with se_desc = Sconstructor fn } in
t2, { op with a_params = [f] }, [typed_e] t2, { op with a_params = [f] }, [typed_e]
@ -690,7 +694,7 @@ and typing_app const_env h op e_list =
| Sconstructor fn -> fn | Sconstructor fn -> fn
| _ -> assert false) in | _ -> assert false) in
let f = { f with se_desc = let f = { f with se_desc =
Sconstructor (Modname { qual = q.qual; id = shortname fn }) } in Sconstructor { qual = q.qual; name = shortname fn } } in
let t2 = field_type const_env fn fields t1 e1.e_loc in let t2 = field_type const_env fn fields t1 e1.e_loc in
let typed_e2 = expect const_env h t2 e2 in let typed_e2 = expect const_env h t2 e2 in
t1, { op with a_params = [f] } , [typed_e1; typed_e2] t1, { op with a_params = [f] } , [typed_e1; typed_e2]
@ -945,7 +949,7 @@ and typing_switch_handlers const_env h acc ty switch_handlers =
let typed_b, defined_names, _ = typing_block const_env h b in let typed_b, defined_names, _ = typing_block const_env h b in
{ w_block = typed_b; { w_block = typed_b;
(* Replace handler name with fully qualified name *) (* Replace handler name with fully qualified name *)
w_name = Modname((find_constr name).qualid)}, w_name = (find_constr name).qualname},
defined_names in defined_names in
let typed_switch_handlers, defined_names_list = let typed_switch_handlers, defined_names_list =
@ -1050,7 +1054,9 @@ let solve loc cl =
let build_node_params const_env l = let build_node_params const_env l =
let check_param env p = let check_param env p =
let ty = check_type const_env p.p_type in let ty = check_type const_env p.p_type in
{ p with p_type = ty }, NamesEnv.add p.p_name ty env let p = { p with p_type = ty } in
let n = Names.local_qn p.p_name in
p, QualEnv.add n ty env
in in
mapfold check_param const_env l mapfold check_param const_env l
@ -1061,7 +1067,7 @@ let node ({ n_name = f; n_statefull = statefull;
n_params = node_params; } as n) = n_params = node_params; } as n) =
try try
let typed_params, const_env = let typed_params, const_env =
build_node_params NamesEnv.empty node_params in build_node_params QualEnv.empty node_params in
let typed_i_list, (input_names, h) = let typed_i_list, (input_names, h) =
build const_env Env.empty i_list in build const_env Env.empty i_list in
let typed_o_list, (output_names, h) = build const_env h o_list in let typed_o_list, (output_names, h) = build const_env h o_list in
@ -1075,9 +1081,6 @@ let node ({ n_name = f; n_statefull = statefull;
included_env defined_names output_names; included_env defined_names output_names;
included_env output_names defined_names; included_env output_names defined_names;
(* if not (statefull) & (List.length o_list <> 1)
then error (Etoo_many_outputs);*)
let cl = get_size_constraint () in let cl = get_size_constraint () in
let cl = solve loc cl in let cl = solve loc cl in
add_value f (signature statefull typed_i_list typed_o_list typed_params cl); add_value f (signature statefull typed_i_list typed_o_list typed_params cl);
@ -1098,13 +1101,13 @@ let deftype { t_name = n; t_desc = tdesc; t_loc = loc } =
| Type_alias ln -> add_type n (Talias ln) | Type_alias ln -> add_type n (Talias ln)
| Type_enum(tag_name_list) -> | Type_enum(tag_name_list) ->
add_type n (Tenum tag_name_list); add_type n (Tenum tag_name_list);
List.iter (fun tag -> add_constr tag (Tid (longname n))) tag_name_list List.iter (fun tag -> add_constr tag (Tid (qualname n))) tag_name_list
| Type_struct(field_ty_list) -> | Type_struct(field_ty_list) ->
let field_ty_list = let field_ty_list =
List.map (fun f -> List.map (fun f ->
mk_field f.f_name mk_field f.f_name
(simplify_type loc (simplify_type loc
(check_type NamesEnv.empty f.f_type))) (check_type QualEnv.empty f.f_type)))
field_ty_list in field_ty_list in
add_type n (Tstruct field_ty_list); add_type n (Tstruct field_ty_list);
add_struct n field_ty_list; add_struct n field_ty_list;
@ -1114,10 +1117,10 @@ let deftype { t_name = n; t_desc = tdesc; t_loc = loc } =
TypingError(error) -> message loc error TypingError(error) -> message loc error
let typing_const_dec cd = let typing_const_dec cd =
let ty = check_type NamesEnv.empty cd.c_type in let ty = check_type QualEnv.empty cd.c_type in
let se = expect_static_exp NamesEnv.empty ty cd.c_value in let se = expect_static_exp QualEnv.empty ty cd.c_value in
let cd = { cd with c_value = se; c_type = ty } in let cd = { cd with c_value = se; c_type = ty } in
add_const cd.c_name (mk_const_def cd.c_name cd.c_type cd.c_value); add_const cd.c_name (mk_const_def cd.c_type cd.c_value);
cd cd
let program let program

@ -15,6 +15,7 @@ open Idents
open Modules open Modules
open Static open Static
open Format open Format
open Global_printer
open Pp_tools open Pp_tools
open Types open Types
open Signature open Signature
@ -68,7 +69,7 @@ and print_exp ff e =
) )
| Estruct(f_e_list) -> | Estruct(f_e_list) ->
print_list_r print_list_r
(fun ff (field, e) -> print_longname ff field;fprintf ff " = "; (fun ff (field, e) -> print_qualname ff field;fprintf ff " = ";
print_exp ff e) print_exp ff e)
"{" ";" "}" ff f_e_list; "{" ";" "}" ff f_e_list;
fprintf ff "}@]" fprintf ff "}@]"
@ -78,10 +79,10 @@ and print_exp ff e =
print_iterator ff it; print_iterator ff it;
fprintf ff " "; fprintf ff " ";
(match params with (match params with
| [] -> print_longname ff ln | [] -> print_qualname ff ln
| l -> | l ->
fprintf ff "("; fprintf ff "(";
print_longname ff ln; print_qualname ff ln;
print_call_params ff params; print_call_params ff params;
fprintf ff ")" fprintf ff ")"
); );
@ -114,7 +115,7 @@ and print_op ff op params e_list =
| Earray, _, e_list -> | Earray, _, e_list ->
print_list_r print_exp "[" "," "]" ff e_list print_list_r print_exp "[" "," "]" ff e_list
| (Efun f|Enode f), params, e_list -> | (Efun f|Enode f), params, e_list ->
print_longname ff f; print_qualname ff f;
print_call_params ff params; print_call_params ff params;
print_exps ff e_list print_exps ff e_list
| Efield, [field], [e] -> | Efield, [field], [e] ->
@ -210,7 +211,7 @@ and print_eq_list ff = function
and print_state_handler ff and print_state_handler ff
{ s_state = s; s_block = b; s_until = until; s_unless = unless } = { s_state = s; s_block = b; s_until = until; s_unless = unless } =
fprintf ff " @[<v 2>state "; fprintf ff " @[<v 2>state ";
fprintf ff "%s@," s; fprintf ff "%a@," print_name s;
print_block ff b; print_block ff b;
if until <> [] then if until <> [] then
begin begin
@ -228,7 +229,7 @@ and print_state_handler ff
and print_switch_handler ff { w_name = tag; w_block = b } = and print_switch_handler ff { w_name = tag; w_block = b } =
fprintf ff " @[<v 2>| "; fprintf ff " @[<v 2>| ";
print_longname ff tag; print_qualname ff tag;
fprintf ff "@,"; fprintf ff "@,";
print_block ff b; print_block ff b;
fprintf ff "@]" fprintf ff "@]"
@ -264,25 +265,25 @@ and print_block ff { b_local = v_list; b_equs = eqs; b_defnames = defnames } =
let print_type_def ff { t_name = name; t_desc = tdesc } = let print_type_def ff { t_name = name; t_desc = tdesc } =
match tdesc with match tdesc with
| Type_abs -> fprintf ff "@[type %s@.@]" name | Type_abs -> fprintf ff "@[type %a@.@]" print_qualname name
| Type_alias ty -> | Type_alias ty ->
fprintf ff "@[type %s@ = %a@.@]" name print_type ty fprintf ff "@[type %a@ = %a@.@]" print_qualname name print_type ty
| Type_enum(tag_name_list) -> | Type_enum(tag_name_list) ->
fprintf ff "@[type %s = " name; fprintf ff "@[type %a = " print_qualname name;
print_list_r print_name "" "| " "" ff tag_name_list; print_list_r print_qualname "" "| " "" ff tag_name_list;
fprintf ff "@.@]" fprintf ff "@.@]"
| Type_struct(f_ty_list) -> | Type_struct(f_ty_list) ->
fprintf ff "@[type %s = " name; fprintf ff "@[type %a = " print_qualname name;
print_list_r print_list_r
(fun ff { f_name = field; f_type = ty } -> (fun ff { f_name = field; f_type = ty } ->
print_name ff field; print_qualname ff field;
fprintf ff ": "; fprintf ff ": ";
print_type ff ty) "{" ";" "}" ff f_ty_list; print_type ff ty) "{" ";" "}" ff f_ty_list;
fprintf ff "@.@]" fprintf ff "@.@]"
let print_const_dec ff c = let print_const_dec ff c =
fprintf ff "@[const "; fprintf ff "@[const ";
print_name ff c.c_name; print_qualname ff c.c_name;
fprintf ff " : "; fprintf ff " : ";
print_type ff c.c_type; print_type ff c.c_type;
fprintf ff " = "; fprintf ff " = ";
@ -317,7 +318,7 @@ let print_node ff
n_block = nb; n_output = no; n_contract = contract; n_block = nb; n_output = no; n_contract = contract;
n_params = params; } = n_params = params; } =
fprintf ff "@[<v 2>node "; fprintf ff "@[<v 2>node ";
print_name ff n; print_qualname ff n;
fprintf ff "@[%a@]" print_node_params params; fprintf ff "@[%a@]" print_node_params params;
fprintf ff "@[%a@]" (print_list_r print_vd "(" ";" ")") ni; fprintf ff "@[%a@]" (print_list_r print_vd "(" ";" ")") ni;
fprintf ff " returns "; fprintf ff " returns ";

@ -24,7 +24,10 @@ type iterator_type =
| Ifoldi | Ifoldi
| Imapfold | Imapfold
type exp = { e_desc : desc; e_ty : ty; e_loc : location } type exp = {
e_desc : desc;
e_ty : ty;
e_loc : location }
and desc = and desc =
| Econst of static_exp | Econst of static_exp
@ -36,7 +39,10 @@ and desc =
| Eapp of app * exp list * exp option | Eapp of app * exp list * exp option
| Eiterator of iterator_type * app * static_exp * exp list * exp option | Eiterator of iterator_type * app * static_exp * exp list * exp option
and app = { a_op: op; a_params: static_exp list; a_unsafe: bool } and app = {
a_op : op;
a_params : static_exp list;
a_unsafe : bool }
and op = and op =
| Eequal | Eequal
@ -59,7 +65,10 @@ and pat =
| Etuplepat of pat list | Etuplepat of pat list
| Evarpat of var_ident | Evarpat of var_ident
type eq = { eq_desc : eqdesc; eq_statefull : bool; eq_loc : location } type eq = {
eq_desc : eqdesc;
eq_statefull : bool;
eq_loc : location }
and eqdesc = and eqdesc =
| Eautomaton of state_handler list | Eautomaton of state_handler list
@ -69,82 +78,92 @@ and eqdesc =
| Eeq of pat * exp | Eeq of pat * exp
and block = { and block = {
b_local : var_dec list; b_local : var_dec list;
b_equs : eq list; b_equs : eq list;
b_defnames : ty Env.t; b_defnames : ty Env.t;
b_statefull : bool; b_statefull : bool;
b_loc : location } b_loc : location }
and state_handler = { and state_handler = {
s_state : state_name; s_state : state_name;
s_block : block; s_block : block;
s_until : escape list; s_until : escape list;
s_unless : escape list } s_unless : escape list }
and escape = { and escape = {
e_cond : exp; e_cond : exp;
e_reset : bool; e_reset : bool;
e_next_state : state_name } e_next_state : state_name }
and switch_handler = { w_name : constructor_name; w_block : block } and switch_handler = {
w_name : constructor_name;
w_block : block }
and present_handler = { p_cond : exp; p_block : block } and present_handler = {
p_cond : exp;
p_block : block }
and var_dec = { and var_dec = {
v_ident : var_ident; v_ident : var_ident;
v_type : ty; v_type : ty;
v_last : last; v_last : last;
v_loc : location } v_loc : location }
and last = Var | Last of static_exp option and last = Var | Last of static_exp option
type type_dec = { t_name : name; t_desc : type_dec_desc; t_loc : location } type type_dec = {
t_name : qualname;
t_desc : type_dec_desc;
t_loc : location }
and type_dec_desc = and type_dec_desc =
| Type_abs | Type_abs
| Type_alias of ty | Type_alias of ty
| Type_enum of name list | Type_enum of constructor_name list
| Type_struct of structure | Type_struct of structure
type contract = { type contract = {
c_assume : exp; c_assume : exp;
c_enforce : exp; c_enforce : exp;
c_block : block } c_block : block }
type node_dec = { type node_dec = {
n_name : name; n_name : qualname;
n_statefull : bool; n_statefull : bool;
n_input : var_dec list; n_input : var_dec list;
n_output : var_dec list; n_output : var_dec list;
n_contract : contract option; n_contract : contract option;
n_block : block; n_block : block;
n_loc : location; n_loc : location;
n_params : param list; n_params : param list;
n_params_constraints : size_constraint list } n_params_constraints : size_constraint list }
type const_dec = { type const_dec = {
c_name : name; c_name : qualname;
c_type : ty; c_type : ty;
c_value : static_exp; c_value : static_exp;
c_loc : location } c_loc : location }
type program = { type program = {
p_modname : name; p_modname : name;
p_opened : name list; p_opened : name list;
p_types : type_dec list; p_types : type_dec list;
p_nodes : node_dec list; p_nodes : node_dec list;
p_consts : const_dec list } p_consts : const_dec list }
type signature = { type signature = {
sig_name : name; sig_name : qualname;
sig_inputs : arg list; sig_inputs : arg list;
sig_statefull : bool; sig_statefull : bool;
sig_outputs : arg list; sig_outputs : arg list;
sig_params : param list } sig_params : param list;
sig_loc : location }
type interface = interface_decl list type interface = interface_decl list
and interface_decl = { interf_desc : interface_desc; interf_loc : location } and interface_decl = {
interf_desc : interface_desc;
interf_loc : location }
and interface_desc = and interface_desc =
| Iopen of name | Iopen of name
@ -188,17 +207,14 @@ let mk_simple_equation pat e =
let mk_switch_equation ?(statefull = true) e l = let mk_switch_equation ?(statefull = true) e l =
mk_equation ~statefull:statefull (Eswitch (e, l)) mk_equation ~statefull:statefull (Eswitch (e, l))
(** @return a size exp operator from a Heptagon operator. *) let mk_signature name ins outs statefull params loc =
let op_from_app app = { sig_name = name;
match app.a_op with sig_inputs = ins;
| Efun op -> op_from_app_name op sig_statefull = statefull;
| _ -> raise Not_static sig_outputs = outs;
sig_params = params;
(** Translates a Heptagon exp into a static size exp. *) sig_loc = loc }
(*let rec static_exp_of_exp e =
match e.e_desc with
| Econst se -> se
| _ -> raise Not_static *)
(** @return the set of variables defined in [pat]. *) (** @return the set of variables defined in [pat]. *)
let vars_pat pat = let vars_pat pat =

@ -26,8 +26,9 @@ let parse parsing_fun lexing_fun lexbuf =
let l = Loc(pos1,pos2) in let l = Loc(pos1,pos2) in
syntax_error l syntax_error l
let parse_implementation lexbuf = let parse_implementation modname lexbuf =
parse Hept_parser.program Hept_lexer.token lexbuf let p = parse Hept_parser.program Hept_lexer.token lexbuf in
{ p with Hept_parsetree.p_modname = modname }
let parse_interface lexbuf = let parse_interface lexbuf =
parse Hept_parser.interface Hept_lexer.token lexbuf parse Hept_parser.interface Hept_lexer.token lexbuf
@ -35,39 +36,39 @@ let parse_interface lexbuf =
let compile_impl pp p = let compile_impl pp p =
(* Typing *) (* Typing *)
let p = do_pass Typing.program "Typing" p pp true in (*let p = pass "Typing" true Typing.program p pp in*)
let p = do_pass Statefull.program "Statefullness check" p pp true in let p = silent_pass "Statefullness check" true Statefull.program p in
if !print_types then Interface.Printer.print stdout; (*if !print_types then Interface.Printer.print stdout;*)
(* Causality check *) (* Causality check *)
let p = do_silent_pass Causality.program "Causality check" p true in let p = silent_pass "Causality check" true Causality.program p in
(* Initialization check *) (* Initialization check *)(*
let p = let p = silent_pass "Initialization check" !init Initialization.program p in*)
do_silent_pass Initialization.program "Initialization check" p !init in
(* Completion of partial definitions *) (* Completion of partial definitions *)
let p = do_pass Completion.program "Completion" p pp true in let p = pass "Completion" true Completion.program p pp in
(* Inlining *)(*
let p = let p =
let call_inline_pass = (List.length !inline > 0) || !Misc.flatten in let call_inline_pass = (List.length !inline > 0) || !Misc.flatten in
do_pass Inline.program "Inlining" p pp call_inline_pass in pass "Inlining" call_inline_pass Inline.program p pp in *)
(* Automata *) (* Automata *)
let p = do_pass Automata.program "Automata" p pp true in (*let p = pass "Automata" true Automata.program p pp in*)
(* Present *) (* Present *)
let p = do_pass Present.program "Present" p pp true in let p = pass "Present" true Present.program p pp in
(* Shared variables (last) *) (* Shared variables (last) *)
let p = do_pass Last.program "Last" p pp true in let p = pass "Last" true Last.program p pp in
(* Reset *) (* Reset *)
let p = do_pass Reset.program "Reset" p pp true in let p = pass "Reset" true Reset.program p pp in
(* Every *) (* Every *)
let p = do_pass Every.program "Every" p pp true in let p = pass "Every" true Every.program p pp in
(* Return the transformed AST *) (* Return the transformed AST *)
p p
@ -87,14 +88,14 @@ let compile_interface modname filename =
init_compiler modname; init_compiler modname;
(* Parsing of the file *) (* Parsing of the file *)
let l = parse_interface lexbuf in let l = do_silent_pass "Parsing" parse_interface lexbuf in
(* Convert the parse tree to Heptagon AST *) (* Convert the parse tree to Heptagon AST *)
let l = Hept_scoping.translate_interface l in let l = do_silent_pass "Scoping" Hept_scoping.translate_interface l in
(* Compile*) (* Compile*)
Interface.Type.main l; (*Interface.Type.main l;
if !print_types then Interface.Printer.print stdout; if !print_types then Interface.Printer.print stdout;*)
Modules.write itc; Modules.write itc;

@ -28,17 +28,13 @@ let check_implementation modname filename =
init_compiler modname; init_compiler modname;
(* Parsing of the file *) (* Parsing of the file *)
let p = parse_implementation lexbuf in let p = do_silent_pass parse_implementation "Parsing" lexbuf true in
comment "Parsing";
(* Convert the parse tree to Heptagon AST *) (* Convert the parse tree to Heptagon AST *)
let p = Hept_scoping.translate_program p in let p = do_pass Hept_scoping.translate_program "Scoping" p pp true in
comment "Scoping";
pp p;
(* Call the compiler*) (* Call the compiler*)
let p = Hept_compiler.compile_impl pp p in let p = do_silent_pass Hept_compiler.compile_impl "Checking" p true in
comment "Checking";
close_all_files () close_all_files ()

@ -146,7 +146,7 @@ label_ty_list:
; ;
label_ty: label_ty:
IDENT COLON ty_ident { ($1, $3) } IDENT COLON ty_ident { $1, $3 }
; ;
node_decs: node_decs:
@ -158,14 +158,14 @@ node_dec:
| node_or_fun ident node_params LPAREN in_params RPAREN | node_or_fun ident node_params LPAREN in_params RPAREN
RETURNS LPAREN out_params RPAREN RETURNS LPAREN out_params RPAREN
contract b=block(LET) TEL contract b=block(LET) TEL
{{ n_name = $2; {{ n_name = $2;
n_statefull = $1; n_statefull = $1;
n_input = $5; n_input = $5;
n_output = $9; n_output = $9;
n_contract = $11; n_contract = $11;
n_block = b; n_block = b;
n_params = $3; n_params = $3;
n_loc = (Loc($startpos,$endpos)) }} n_loc = (Loc($startpos,$endpos)) }}
; ;
node_or_fun: node_or_fun:
@ -216,7 +216,7 @@ contract:
; ;
opt_assume: opt_assume:
| /* empty */ { mk_constructor_exp Initial.ptrue (Loc($startpos,$endpos)) } | /* empty */ { mk_constructor_exp ptrue (Loc($startpos,$endpos)) }
| ASSUME exp { $2 } | ASSUME exp { $2 }
; ;
@ -250,7 +250,7 @@ ident_list:
; ;
ty_ident: ty_ident:
| longname | qualname
{ Tid $1 } { Tid $1 }
| ty_ident POWER simple_exp | ty_ident POWER simple_exp
{ Tarray ($1, $3) } { Tarray ($1, $3) }
@ -293,8 +293,8 @@ _equ:
{ Epresent(List.rev $3, b) } { Epresent(List.rev $3, b) }
| IF exp THEN tb=block(DO) ELSE fb=block(DO) END | IF exp THEN tb=block(DO) ELSE fb=block(DO) END
{ Eswitch($2, { Eswitch($2,
[{ w_name = Name("true"); w_block = tb }; [{ w_name = ptrue; w_block = tb };
{ w_name = Name("false"); w_block = fb }]) } { w_name = pfalse; w_block = fb }]) }
| RESET equs EVERY exp | RESET equs EVERY exp
{ Ereset(mk_block [] $2 (Loc($startpos,$endpos)), $4) } { Ereset(mk_block [] $2 (Loc($startpos,$endpos)), $4) }
; ;
@ -343,7 +343,7 @@ switch_handler:
; ;
constructor_or_bool: constructor_or_bool:
| BOOL { Name(if $1 then "true" else "false") } | BOOL { if $1 then Q Initial.ptrue else Q Initial.pfalse }
| constructor { $1 } | constructor { $1 }
switch_handlers: switch_handlers:
@ -394,13 +394,13 @@ _simple_exp:
| LBRACE field_exp_list RBRACE { Estruct $2 } | LBRACE field_exp_list RBRACE { Estruct $2 }
| LBRACKET array_exp_list RBRACKET { mk_call Earray $2 } | LBRACKET array_exp_list RBRACKET { mk_call Earray $2 }
| LPAREN tuple_exp RPAREN { mk_call Etuple $2 } | LPAREN tuple_exp RPAREN { mk_call Etuple $2 }
| simple_exp DOT c=longname | simple_exp DOT c=qualname
{ mk_call ~params:[mk_constructor_exp c (Loc($startpos(c),$endpos(c)))] { mk_call ~params:[mk_constructor_exp c (Loc($startpos(c),$endpos(c)))]
Efield [$1] } Efield [$1] }
; ;
node_name: node_name:
| longname call_params { mk_app (Enode $1) $2 } | qualname call_params { mk_app (Enode $1) $2 }
exp: exp:
@ -462,13 +462,13 @@ _exp:
| exp AROBASE exp | exp AROBASE exp
{ mk_call Econcat [$1; $3] } { mk_call Econcat [$1; $3] }
/*Iterators*/ /*Iterators*/
| iterator longname DOUBLE_LESS simple_exp DOUBLE_GREATER LPAREN exps RPAREN | iterator qualname DOUBLE_LESS simple_exp DOUBLE_GREATER LPAREN exps RPAREN
{ mk_iterator_call $1 $2 [] $4 $7 } { mk_iterator_call $1 $2 [] $4 $7 }
| iterator LPAREN longname DOUBLE_LESS array_exp_list DOUBLE_GREATER | iterator LPAREN qualname DOUBLE_LESS array_exp_list DOUBLE_GREATER
RPAREN DOUBLE_LESS simple_exp DOUBLE_GREATER LPAREN exps RPAREN RPAREN DOUBLE_LESS simple_exp DOUBLE_GREATER LPAREN exps RPAREN
{ mk_iterator_call $1 $3 $5 $9 $12 } { mk_iterator_call $1 $3 $5 $9 $12 }
/*Records operators */ /*Records operators */
| LBRACE simple_exp WITH DOT c=longname EQUAL exp RBRACE | LBRACE simple_exp WITH DOT c=qualname EQUAL exp RBRACE
{ mk_call ~params:[mk_constructor_exp c (Loc($startpos(c),$endpos(c)))] { mk_call ~params:[mk_constructor_exp c (Loc($startpos(c),$endpos(c)))]
Efield_update [$2; $7] } Efield_update [$2; $7] }
; ;
@ -491,24 +491,24 @@ indexes:
; ;
constructor: constructor:
| Constructor { Name($1) } %prec prec_ident | Constructor { ToQ $1 } %prec prec_ident
| Constructor DOT Constructor { Modname({qual = $1; id = $3}) } | Constructor DOT Constructor { Q {qual = $1; name = $3} }
; ;
longname: qualname:
| ident { Name($1) } | ident { ToQ $1 }
| Constructor DOT ident { Modname({qual = $1; id = $3}) } | Constructor DOT ident { Q {qual = $1; name = $3} }
; ;
const: c=_const { mk_static_exp c ~loc:(Loc($startpos,$endpos)) } const: c=_const { mk_static_exp c (Loc($startpos,$endpos)) }
_const: _const:
| INT { Sint $1 } | INT { Sint $1 }
| FLOAT { Sfloat $1 } | FLOAT { Sfloat $1 }
| BOOL { Sbool $1 } | BOOL { Sbool $1 }
| constructor { Sconstructor $1 } | constructor { Sconstructor $1 }
| Constructor DOT ident | Constructor DOT ident
{ Svar (Modname({qual = $1; id = $3})) } { Svar (Q {qual = $1; name = $3}) }
; ;
tuple_exp: tuple_exp:
@ -527,7 +527,7 @@ array_exp_list:
; ;
field_exp: field_exp:
| longname EQUAL exp { ($1, $3) } | qualname EQUAL exp { ($1, $3) }
; ;
/* identifiers */ /* identifiers */
@ -569,10 +569,11 @@ _interface_decl:
| VAL node_or_fun ident node_params LPAREN params_signature RPAREN | VAL node_or_fun ident node_params LPAREN params_signature RPAREN
RETURNS LPAREN params_signature RPAREN RETURNS LPAREN params_signature RPAREN
{ Isignature({ sig_name = $3; { Isignature({ sig_name = $3;
sig_inputs = $6; sig_inputs = $6;
sig_statefull = $2; sig_statefull = $2;
sig_outputs = $10; sig_outputs = $10;
sig_params = $4; }) } sig_params = $4;
sig_loc = (Loc($startpos,$endpos)) }) }
; ;
params_signature: params_signature:

@ -13,6 +13,31 @@ open Location
open Signature open Signature
open Types open Types
type qualname =
| Q of Names.qualname (* already qualified name *)
| ToQ of name (* name to qualify in the scoping process *)
type type_name = qualname
type fun_name = qualname
type field_name = qualname
type constructor_name = qualname
type constant_name = qualname
type module_name = name
type static_exp = { se_desc: static_exp_desc; se_ty: ty; se_loc: location }
and static_exp_desc =
| Svar of constant_name
| Sint of int
| Sfloat of float
| Sbool of bool
| Sconstructor of constructor_name
| Stuple of static_exp list
| Sarray_power of static_exp * static_exp (** power : 0^n : [0,0,0,0,0,..] *)
| Sarray of static_exp list (** [ e1, e2, e3 ] *)
| Srecord of (field_name * static_exp) list (** { f1 = e1; f2 = e2; ... } *)
| Sop of fun_name * static_exp list (** defined ops for now in pervasives *)
type iterator_type = type iterator_type =
| Imap | Imap
| Ifold | Ifold
@ -21,7 +46,7 @@ type iterator_type =
type ty = type ty =
| Tprod of ty list | Tprod of ty list
| Tid of longname | Tid of qualname
| Tarray of ty * exp | Tarray of ty * exp
and exp = and exp =
@ -34,7 +59,7 @@ and desc =
| Elast of name | Elast of name
| Epre of exp option * exp | Epre of exp option * exp
| Efby of exp * exp | Efby of exp * exp
| Estruct of (longname * exp) list | Estruct of (qualname * exp) list
| Eapp of app * exp list | Eapp of app * exp list
| Eiterator of iterator_type * app * exp * exp list | Eiterator of iterator_type * app * exp * exp list
@ -43,8 +68,8 @@ and app = { a_op: op; a_params: exp list; }
and op = and op =
| Eequal | Eequal
| Etuple | Etuple
| Enode of longname | Enode of qualname
| Efun of longname | Efun of qualname
| Eifthenelse | Eifthenelse
| Earrow | Earrow
| Efield | Efield
@ -89,7 +114,7 @@ and escape =
e_next_state : name; } e_next_state : name; }
and switch_handler = and switch_handler =
{ w_name : longname; { w_name : constructor_name;
w_block : block; } w_block : block; }
and present_handler = and present_handler =
@ -148,11 +173,12 @@ type program =
type arg = { a_type : ty; a_name : name option } type arg = { a_type : ty; a_name : name option }
type signature = type signature =
{ sig_name : name; { sig_name : name;
sig_inputs : arg list; sig_inputs : arg list;
sig_statefull : bool; sig_statefull : bool;
sig_outputs : arg list; sig_outputs : arg list;
sig_params : var_dec list; } sig_params : var_dec list;
sig_loc : location }
type interface = interface_decl list type interface = interface_decl list
@ -178,13 +204,16 @@ let mk_call ?(params=[]) op exps =
let mk_op_call ?(params=[]) s exps = let mk_op_call ?(params=[]) s exps =
mk_call ~params:params mk_call ~params:params
(Efun (Modname { qual = "Pervasives"; id = s })) exps (Efun (Q { qual = "Pervasives"; name = s })) exps
let mk_iterator_call it ln params n exps = let mk_iterator_call it ln params n exps =
Eiterator (it, mk_app (Enode ln) params, n, exps) Eiterator (it, mk_app (Enode ln) params, n, exps)
let mk_static_exp ?(ty = invalid_type) desc loc =
{ se_desc = desc; se_ty = ty; se_loc = loc }
let mk_constructor_exp f loc = let mk_constructor_exp f loc =
mk_exp (Econst (mk_static_exp (Sconstructor f))) loc mk_exp (Econst (mk_static_exp (Sconstructor f) loc)) loc
let mk_type_dec name desc loc = let mk_type_dec name desc loc =
{ t_name = name; t_desc = desc; t_loc = loc } { t_name = name; t_desc = desc; t_loc = loc }
@ -204,9 +233,12 @@ let mk_block locals eqs loc =
b_loc = loc } b_loc = loc }
let mk_const_dec id ty e loc = let mk_const_dec id ty e loc =
{ c_name = id; c_type = ty; c_value = e; { c_name = id; c_type = ty; c_value = e; c_loc = loc }
c_loc = loc }
let mk_arg name ty = let mk_arg name ty =
{ a_type = ty; a_name = name } { a_type = ty; a_name = name }
let ptrue = Q Initial.ptrue
let pfalse = Q Initial.pfalse

@ -1,6 +1,28 @@
(** Scoping. Introduces unique indexes for local names and replace global (** Scoping. Introduces unique indexes for local names and replace global
names by qualified names *) names by qualified names *)
(* [local_const] is the environnement with local constant variables,
that is for now only the statics node parameters.
It is built with [build_const].
When qualifying a constant var,
it is first check in the local_const env, so qualified with [local_qn]
if not found we try to qualify with the global env. *)
(* The global environement is initialized by the scoping pass.
This allow at the same time
to qualify types, constants, constructors, fields and node calls,
according to the current module definitions and opened modules. *)
(* [env] of type Rename.t is the renaming environnement
used to map a var name to a var ident.
It is initialized at node declaration level with the inputs and outputs,
and then appended with the local var declarations at each block level
with the [build] function. *)
(* convention : static params are set as the first static args,
op<a1,a2> (a3) == op <a1> (a2,a3) == op (a1,a2,a3) *)
open Location open Location
open Types open Types
open Hept_parsetree open Hept_parsetree
@ -8,27 +30,38 @@ open Names
open Idents open Idents
open Format open Format
open Static open Static
open Global_printer
open Modules open Modules
module Error = module Error =
struct struct
type error = type error =
| Evar of string | EvarUnbound of name
| Econst_var of string | EqualUnbound of qualname
| Evariable_already_defined of string | Econst_var of name
| Econst_variable_already_defined of string | Enotlast of name
| Evariable_already_defined of name
| Econst_variable_already_defined of name
| Estatic_exp_expected | Estatic_exp_expected
let message loc kind = let message loc kind =
begin match kind with begin match kind with
| Evar name -> | EvarUnbound name ->
eprintf "%aThe value identifier %s is unbound.@." eprintf "%aThe value identifier %s is unbound.@."
print_location loc print_location loc
name name
|EqualUnbound q ->
eprintf "%aThe qualified name %a can't be found.@."
print_location loc
print_qualname q
| Econst_var name -> | Econst_var name ->
eprintf "%aThe const identifier %s is unbound.@." eprintf "%aThe const identifier %s is unbound.@."
print_location loc print_location loc
name name
| Enotlast name ->
eprintf "%aThe variable identifier %s should be declared as a last.@."
print_location loc
name
| Evariable_already_defined name -> | Evariable_already_defined name ->
eprintf "%aThe variable %s is already defined.@." eprintf "%aThe variable %s is already defined.@."
print_location loc print_location loc
@ -42,140 +75,199 @@ struct
print_location loc print_location loc
end; end;
raise Misc.Error raise Misc.Error
exception ScopingError of error
let error kind = raise (ScopingError(kind))
end end
open Error
(** { 3 qualify when ToQ and check when Q according to the global env } *)
let _qualify_with_error qfun cqfun q = match q with
| ToQ name ->
(*TODO good error*)
(try qfun name with Not_found -> error (EvarUnbound name))
| Q q ->
if cqfun q then q else error (EqualUnbound q)
let qualify_value = _qualify_with_error qualify_value check_value
let qualify_type = _qualify_with_error qualify_type check_type
let qualify_constrs = _qualify_with_error qualify_constrs check_constrs
let qualify_field = _qualify_with_error qualify_field check_field
(** Qualify with [Names.local_qualname] when in local_const,
otherwise qualify according to the global env *)
let qualify_const local_const c = match c with
| ToQ c ->
if S.mem c local_const
then local_qn c
else (try qualify_const c with Not_found -> raise Not_static)
| Q q ->
if check_const q then q else raise Not_static
module Rename = module Rename =
struct struct
open Error
include include
(Map.Make (struct type t = string let compare = String.compare end)) (Map.Make (struct type t = string let compare = String.compare end))
let append env0 env = (** Rename a var *)
fold (fun key v env -> add key v env) env0 env let var loc env n =
try fst (find n env)
let name loc env n = with Not_found -> message loc (EvarUnbound n)
(** Rename a last *)
let last loc env n =
try try
find n env let id, last = find n env in
with if not last then message loc (Enotlast n) else id
Not_found -> Error.message loc (Error.Evar(n)) with Not_found -> message loc (EvarUnbound n)
(** Add a var *)
let add_var loc env n =
if mem n env then message loc (Evariable_already_defined n)
else (* create a new id for this var and add it to the env *)
add n (ident_of_name n, false) env
(** Add a last *)
let add_last loc env n =
if mem n env then message loc (Evariable_already_defined n)
else (* create a new id for this var and add it to the env *)
add n (ident_of_name n, true) env
(** Add a var dec *)
let add env vd =
let add = match vd.v_last with
| Var -> add_var
| Last _ -> add_last in
add vd.v_loc env vd.v_name
(** Append a list of var dec *)
let append env vd_list = List.fold_left add env vd_list
end end
(*Functions to build the renaming map*)
let add_var loc x env = (** Function to build the defined static parameters set *)
if Rename.mem x env then let build_const loc vd_list =
Error.message loc (Error.Evariable_already_defined x) let _add_const_var loc c local_const =
else (* create a new id for this var and add it to the env *) if S.mem c local_const
Rename.add x (ident_of_name x) env then Error.message loc (Error.Econst_variable_already_defined c)
else S.add c local_const in
let add_const_var loc x env = let build local_const vd =
if NamesEnv.mem x env then _add_const_var loc vd.v_name local_const in
Error.message loc (Error.Econst_variable_already_defined x) List.fold_left build S.empty vd_list
else (* create a new id for this var and add it to the env *)
NamesEnv.add x x env
(** { 3 Translate the AST into Heptagon. } *)
let build_vd_list env l =
let build_vd env vd =
add_var vd.v_loc vd.v_name env
in
List.fold_left build_vd env l
let build_cd env cd =
add_const_var cd.c_loc cd.c_name env
let build_id_list loc env l =
let build_id env vd =
add_const_var loc vd.v_name env
in
List.fold_left build_id env l
(* Translate the AST into Heptagon. *)
let translate_iterator_type = function let translate_iterator_type = function
| Imap -> Heptagon.Imap | Imap -> Heptagon.Imap
| Ifold -> Heptagon.Ifold | Ifold -> Heptagon.Ifold
| Ifoldi -> Heptagon.Ifoldi | Ifoldi -> Heptagon.Ifoldi
| Imapfold -> Heptagon.Imapfold | Imapfold -> Heptagon.Imapfold
let op_from_app loc app = (** convention : static params are set as the first static args,
op<a1,a2> (a3) == op <a1> (a2,a3) == op (a1,a2,a3) *)
let static_app_from_app app args=
match app.a_op with match app.a_op with
| Efun op | Enode op -> op_from_app_name op | Efun (Q ({ qual = "pervasives" } as q))
| Enode (Q ({ qual = "pervasives" } as q)) ->
q, (app.a_params @ args)
| _ -> raise Not_static | _ -> raise Not_static
let rec static_exp_of_exp const_env e = let rec translate_static_exp local_const se =
let desc = match e.e_desc with try
| Evar n -> let se_d = translate_static_exp_desc local_const se.se_desc in
if NamesEnv.mem n const_env then Types.mk_static_exp ~loc:se.se_loc se_d
Svar (Name n) with
else | ScopingError err -> message se.se_loc err
(try
let { qualid = q } = find_const (Name n) in and translate_static_exp_desc local_const ed =
Svar (Modname q) let t = translate_static_exp local_const in
with Not_found -> raise Not_static) match ed with
| Econst se -> se.se_desc | Svar q -> Types.Svar (qualify_const local_const q)
| Eapp({ a_op = Earray_fill; a_params = [n] }, [e]) -> | Sint i -> Types.Sint i
Sarray_power (static_exp_of_exp const_env e, | Sfloat f -> Types.Sfloat f
static_exp_of_exp const_env n) | Sbool b -> Types.Sbool b
| Eapp({ a_op = Earray }, e_list) -> | Sconstructor c -> Types.Sconstructor (qualify_constrs c)
Sarray (List.map (static_exp_of_exp const_env) e_list) | Stuple se_list -> Types.Stuple (List.map t se_list)
| Eapp({ a_op = Etuple }, e_list) -> | Sarray_power (se,sn) -> Types.Sarray_power (t se, t sn)
Stuple (List.map (static_exp_of_exp const_env) e_list) | Sarray se_list -> Types.Sarray (List.map t se_list)
| Eapp(app, e_list) -> | Srecord se_f_list ->
let op = op_from_app e.e_loc app in let qualf (f, se) = (qualify_field f, t se) in
Sop(op, List.map (static_exp_of_exp const_env) e_list) Types.Srecord (List.map qualf se_f_list)
| Estruct e_list -> | Sop (fn, se_list) -> Types.Sop (qualify_value fn, List.map t se_list)
Srecord (List.map (fun (f,e) -> f,
static_exp_of_exp const_env e) e_list) let rec static_exp_of_exp local_const e =
| _ -> raise Not_static try
in let t = static_exp_of_exp local_const in
mk_static_exp ~loc:e.e_loc desc let desc = match e.e_desc with
| Evar n -> Types.Svar (qualify_const local_const (ToQ n))
| Econst se -> translate_static_exp_desc local_const se.se_desc
| Eapp({ a_op = Earray_fill; a_params = [n] }, [e]) ->
Types.Sarray_power (t e, t n)
| Eapp({ a_op = Earray }, e_list) ->
Types.Sarray (List.map t e_list)
| Eapp({ a_op = Etuple }, e_list) ->
Types.Stuple (List.map t e_list)
| Eapp(app, e_list) ->
let op, args = static_app_from_app app e_list in
Types.Sop (op, List.map t args)
| Estruct e_list ->
Types.Srecord (List.map (fun (f,e) -> qualify_field f, t e) e_list)
| _ -> raise Not_static in
Types.mk_static_exp ~loc:e.e_loc desc
with
| ScopingError err -> message e.e_loc err
let expect_static_exp local_const e =
try static_exp_of_exp local_const e
with Not_static -> message e.e_loc Estatic_exp_expected
let expect_static_exp const_env e = let rec translate_type loc local_const ty =
try try
static_exp_of_exp const_env e (match ty with
| Tprod ty_list ->
Types.Tprod(List.map (translate_type loc local_const) ty_list)
| Tid ln -> Types.Tid (qualify_type ln)
| Tarray (ty, e) ->
let ty = translate_type loc local_const ty in
Types.Tarray (ty, expect_static_exp local_const e))
with with
Not_static -> Error.message e.e_loc Error.Estatic_exp_expected | ScopingError err -> message loc err
let rec translate_type const_env = function
| Tprod ty_list -> Types.Tprod(List.map (translate_type const_env) ty_list)
| Tid ln -> Types.Tid ln
| Tarray (ty, e) ->
let ty = translate_type const_env ty in
Types.Tarray (ty, expect_static_exp const_env e)
and translate_exp const_env env e = and translate_exp local_const env e =
let desc = let desc =
try (* try to see if the exp is a constant *) try (* try to see if the exp is a constant *)
Heptagon.Econst (static_exp_of_exp const_env e) Heptagon.Econst (static_exp_of_exp local_const e)
with with
Not_static -> translate_desc e.e_loc const_env env e.e_desc in Not_static -> translate_desc e.e_loc local_const env e.e_desc in
{ Heptagon.e_desc = desc; { Heptagon.e_desc = desc;
Heptagon.e_ty = Types.invalid_type; Heptagon.e_ty = Types.invalid_type;
Heptagon.e_loc = e.e_loc } Heptagon.e_loc = e.e_loc }
and translate_desc loc const_env env = function and translate_desc loc local_const env = function
| Econst c -> Heptagon.Econst c | Econst c -> Heptagon.Econst (translate_static_exp local_const c)
| Evar x -> | Evar x -> Heptagon.Evar (Rename.var loc env x)
if Rename.mem x env then (* defined var *) | Elast x -> Heptagon.Elast (Rename.last loc env x)
Heptagon.Evar (Rename.name loc env x) | Epre (None, e) -> Heptagon.Epre (None, translate_exp local_const env e)
else (* undefined var *)
Error.message loc (Error.Evar x)
| Elast x -> Heptagon.Elast (Rename.name loc env x)
| Epre (None, e) -> Heptagon.Epre (None, translate_exp const_env env e)
| Epre (Some c, e) -> | Epre (Some c, e) ->
Heptagon.Epre (Some (expect_static_exp const_env c), Heptagon.Epre (Some (expect_static_exp local_const c),
translate_exp const_env env e) translate_exp local_const env e)
| Efby (e1, e2) -> Heptagon.Efby (translate_exp const_env env e1, | Efby (e1, e2) -> Heptagon.Efby (translate_exp local_const env e1,
translate_exp const_env env e2) translate_exp local_const env e2)
| Estruct f_e_list -> | Estruct f_e_list ->
let f_e_list = let f_e_list =
List.map (fun (f,e) -> f, translate_exp const_env env e) f_e_list in List.map (fun (f,e) -> qualify_field f, translate_exp local_const env e)
f_e_list in
Heptagon.Estruct f_e_list Heptagon.Estruct f_e_list
| Eapp ({ a_op = op; a_params = params }, e_list) -> | Eapp ({ a_op = op; a_params = params }, e_list) ->
let e_list = List.map (translate_exp const_env env) e_list in let e_list = List.map (translate_exp local_const env) e_list in
let params = List.map (expect_static_exp const_env) params in let params = List.map (expect_static_exp local_const) params in
let app = Heptagon.mk_op ~params:params (translate_op op) in let app = Heptagon.mk_op ~params:params (translate_op op) in
Heptagon.Eapp (app, e_list, None) Heptagon.Eapp (app, e_list, None)
| Eiterator (it, { a_op = op; a_params = params }, n, e_list) -> | Eiterator (it, { a_op = op; a_params = params }, n, e_list) ->
let e_list = List.map (translate_exp const_env env) e_list in let e_list = List.map (translate_exp local_const env) e_list in
let n = expect_static_exp const_env n in let n = expect_static_exp local_const n in
let params = List.map (expect_static_exp const_env) params in let params = List.map (expect_static_exp local_const) params in
let app = Heptagon.mk_op ~params:params (translate_op op) in let app = Heptagon.mk_op ~params:params (translate_op op) in
Heptagon.Eiterator (translate_iterator_type it, Heptagon.Eiterator (translate_iterator_type it,
app, n, e_list, None) app, n, e_list, None)
@ -194,161 +286,183 @@ and translate_op = function
| Eselect_slice -> Heptagon.Eselect_slice | Eselect_slice -> Heptagon.Eselect_slice
| Econcat -> Heptagon.Econcat | Econcat -> Heptagon.Econcat
| Eselect_dyn -> Heptagon.Eselect_dyn | Eselect_dyn -> Heptagon.Eselect_dyn
| Efun ln -> Heptagon.Efun ln | Efun ln -> Heptagon.Efun (qualify_value ln)
| Enode ln -> Heptagon.Enode ln | Enode ln -> Heptagon.Enode (qualify_value ln)
and translate_pat loc env = function and translate_pat loc env = function
| Evarpat x -> Heptagon.Evarpat (Rename.name loc env x) | Evarpat x -> Heptagon.Evarpat (Rename.var loc env x)
| Etuplepat l -> Heptagon.Etuplepat (List.map (translate_pat loc env) l) | Etuplepat l -> Heptagon.Etuplepat (List.map (translate_pat loc env) l)
let rec translate_eq const_env env eq = let rec translate_eq local_const env eq =
{ Heptagon.eq_desc = translate_eq_desc eq.eq_loc const_env env eq.eq_desc ; { Heptagon.eq_desc = translate_eq_desc eq.eq_loc local_const env eq.eq_desc ;
Heptagon.eq_statefull = false; Heptagon.eq_statefull = false;
Heptagon.eq_loc = eq.eq_loc } Heptagon.eq_loc = eq.eq_loc }
and translate_eq_desc loc const_env env = function and translate_eq_desc loc local_const env = function
| Eswitch(e, switch_handlers) -> | Eswitch(e, switch_handlers) ->
let sh = List.map let sh = List.map
(translate_switch_handler loc const_env env) (translate_switch_handler loc local_const env)
switch_handlers in switch_handlers in
Heptagon.Eswitch (translate_exp const_env env e, sh) Heptagon.Eswitch (translate_exp local_const env e, sh)
| Eeq(p, e) -> | Eeq(p, e) ->
Heptagon.Eeq (translate_pat loc env p, translate_exp const_env env e) Heptagon.Eeq (translate_pat loc env p, translate_exp local_const env e)
| Epresent (present_handlers, b) -> | Epresent (present_handlers, b) ->
Heptagon.Epresent Heptagon.Epresent
(List.map (translate_present_handler const_env env) present_handlers (List.map (translate_present_handler local_const env) present_handlers
, fst (translate_block const_env env b)) , fst (translate_block local_const env b))
| Eautomaton state_handlers -> | Eautomaton state_handlers ->
Heptagon.Eautomaton (List.map (translate_state_handler const_env env) Heptagon.Eautomaton (List.map (translate_state_handler local_const env)
state_handlers) state_handlers)
| Ereset (b, e) -> | Ereset (b, e) ->
let b, _ = translate_block const_env env b in let b, _ = translate_block local_const env b in
Heptagon.Ereset (b, translate_exp const_env env e) Heptagon.Ereset (b, translate_exp local_const env e)
and translate_block const_env env b = and translate_block local_const env b =
let env = build_vd_list env b.b_local in let env = Rename.append env b.b_local in
{ Heptagon.b_local = translate_vd_list const_env env b.b_local; { Heptagon.b_local = translate_vd_list local_const env b.b_local;
Heptagon.b_equs = List.map (translate_eq const_env env) b.b_equs; Heptagon.b_equs = List.map (translate_eq local_const env) b.b_equs;
Heptagon.b_defnames = Env.empty ; Heptagon.b_defnames = Env.empty;
Heptagon.b_statefull = false; Heptagon.b_statefull = false;
Heptagon.b_loc = b.b_loc }, env Heptagon.b_loc = b.b_loc }, env
and translate_state_handler const_env env sh = and translate_state_handler local_const env sh =
let b, env = translate_block const_env env sh.s_block in let b, env = translate_block local_const env sh.s_block in
{ Heptagon.s_state = sh.s_state; { Heptagon.s_state = sh.s_state;
Heptagon.s_block = b; Heptagon.s_block = b;
Heptagon.s_until = List.map (translate_escape const_env env) sh.s_until; Heptagon.s_until = List.map (translate_escape local_const env) sh.s_until;
Heptagon.s_unless = List.map (translate_escape const_env env) sh.s_unless; } Heptagon.s_unless =
List.map (translate_escape local_const env) sh.s_unless; }
and translate_escape const_env env esc = and translate_escape local_const env esc =
{ Heptagon.e_cond = translate_exp const_env env esc.e_cond; { Heptagon.e_cond = translate_exp local_const env esc.e_cond;
Heptagon.e_reset = esc.e_reset; Heptagon.e_reset = esc.e_reset;
Heptagon.e_next_state = esc.e_next_state } Heptagon.e_next_state = esc.e_next_state }
and translate_present_handler const_env env ph = and translate_present_handler local_const env ph =
{ Heptagon.p_cond = translate_exp const_env env ph.p_cond; { Heptagon.p_cond = translate_exp local_const env ph.p_cond;
Heptagon.p_block = fst (translate_block const_env env ph.p_block) } Heptagon.p_block = fst (translate_block local_const env ph.p_block) }
and translate_switch_handler loc const_env env sh = and translate_switch_handler loc local_const env sh =
{ Heptagon.w_name = sh.w_name; try
Heptagon.w_block = fst (translate_block const_env env sh.w_block) } { Heptagon.w_name = qualify_constrs sh.w_name;
Heptagon.w_block = fst (translate_block local_const env sh.w_block) }
with
| ScopingError err -> message loc err
and translate_var_dec const_env env vd = and translate_var_dec local_const env vd =
{ Heptagon.v_ident = Rename.name vd.v_loc env vd.v_name; (* env is initialized with the declared vars before their translation *)
Heptagon.v_type = translate_type const_env vd.v_type; { Heptagon.v_ident = Rename.var vd.v_loc env vd.v_name;
Heptagon.v_last = translate_last const_env env vd.v_last; Heptagon.v_type = translate_type vd.v_loc local_const vd.v_type;
Heptagon.v_loc = vd.v_loc } Heptagon.v_last = translate_last local_const vd.v_last;
Heptagon.v_loc = vd.v_loc }
and translate_vd_list const_env env = and translate_vd_list local_const env =
List.map (translate_var_dec const_env env) List.map (translate_var_dec local_const env)
and translate_last const_env env = function and translate_last local_const = function
| Var -> Heptagon.Var | Var -> Heptagon.Var
| Last (None) -> Heptagon.Last None | Last (None) -> Heptagon.Last None
| Last (Some e) -> Heptagon.Last (Some (expect_static_exp const_env e)) | Last (Some e) -> Heptagon.Last (Some (expect_static_exp local_const e))
let translate_contract const_env env ct = let translate_contract local_const env ct =
let b, _ = translate_block const_env env ct.c_block in let b, _ = translate_block local_const env ct.c_block in
{ Heptagon.c_assume = translate_exp const_env env ct.c_assume; { Heptagon.c_assume = translate_exp local_const env ct.c_assume;
Heptagon.c_enforce = translate_exp const_env env ct.c_enforce; Heptagon.c_enforce = translate_exp local_const env ct.c_enforce;
Heptagon.c_block = b } Heptagon.c_block = b }
let param_of_var_dec const_env vd = let params_of_var_decs local_const =
Signature.mk_param vd.v_name (translate_type const_env vd.v_type) List.map (fun vd -> Signature.mk_param
vd.v_name
let translate_node const_env env node = (translate_type vd.v_loc local_const vd.v_type))
let const_env = build_id_list node.n_loc const_env node.n_params in
let env = build_vd_list env (node.n_input @ node.n_output) in let translate_node node =
let b, env = translate_block const_env env node.n_block in (* Node's params go to local_const env *)
{ Heptagon.n_name = node.n_name; let local_const = build_const node.n_loc node.n_params in
(* Inputs and outputs define the initial local env *)
let env0 = Rename.append Rename.empty (node.n_input @ node.n_output) in
let b, env = translate_block local_const env0 node.n_block in
(* the env of the block is used in the contract translation *)
let n = current_qual node.n_name in
{ Heptagon.n_name = n;
Heptagon.n_statefull = node.n_statefull; Heptagon.n_statefull = node.n_statefull;
Heptagon.n_input = translate_vd_list const_env env node.n_input; Heptagon.n_input = translate_vd_list local_const env0 node.n_input;
Heptagon.n_output = translate_vd_list const_env env node.n_output; Heptagon.n_output = translate_vd_list local_const env0 node.n_output;
Heptagon.n_contract = Misc.optional Heptagon.n_contract =
(translate_contract const_env env) node.n_contract; Misc.optional (translate_contract local_const env) node.n_contract;
Heptagon.n_block = b; Heptagon.n_block = b;
Heptagon.n_loc = node.n_loc; Heptagon.n_loc = node.n_loc;
Heptagon.n_params = List.map (param_of_var_dec const_env) node.n_params; Heptagon.n_params = params_of_var_decs local_const node.n_params;
Heptagon.n_params_constraints = []; } Heptagon.n_params_constraints = []; }
let translate_typedec const_env ty = let translate_typedec ty =
let onetype = function let n = current_qual ty.t_name in
| Type_abs -> Heptagon.Type_abs let tydesc = match ty.t_desc with
| Type_alias ty -> Heptagon.Type_alias (translate_type const_env ty) | Type_abs ->
| Type_enum(tag_list) -> Heptagon.Type_enum(tag_list) add_type n Signature.Tabstract;
| Type_struct(field_ty_list) -> Heptagon.Type_abs
let translate_field_type (f,ty) = | Type_alias t ->
Signature.mk_field f (translate_type const_env ty) in let t = translate_type ty.t_loc S.empty t in
Heptagon.Type_struct (List.map translate_field_type field_ty_list) add_type n (Signature.Talias t);
in Heptagon.Type_alias t
{ Heptagon.t_name = ty.t_name; | Type_enum(tag_list) ->
Heptagon.t_desc = onetype ty.t_desc; let tag_list = List.map current_qual tag_list in
Heptagon.t_loc = ty.t_loc } List.iter (fun tag -> add_constrs tag n) tag_list;
add_type n (Signature.Tenum tag_list);
let translate_const_dec const_env cd = Heptagon.Type_enum tag_list
{ Heptagon.c_name = cd.c_name; | Type_struct(field_ty_list) ->
Heptagon.c_type = translate_type const_env cd.c_type; let translate_field_type (f,t) =
Heptagon.c_value = expect_static_exp const_env cd.c_value; let f = current_qual f in
Heptagon.c_loc = cd.c_loc; }, build_cd const_env cd let t = translate_type ty.t_loc S.empty t in
add_field f n;
Signature.mk_field f t in
let field_list = List.map translate_field_type field_ty_list in
add_type n (Signature.Tstruct field_list);
Heptagon.Type_struct field_list in
{ Heptagon.t_name = n;
Heptagon.t_desc = tydesc;
Heptagon.t_loc = ty.t_loc }
let translate_const_dec cd =
let c_name = current_qual cd.c_name in
let c_type = translate_type cd.c_loc S.empty cd.c_type in
let c_value = expect_static_exp S.empty cd.c_value in
add_const c_name (Signature.mk_const_def c_type c_value);
{ Heptagon.c_name = c_name;
Heptagon.c_type = c_type;
Heptagon.c_value = c_value;
Heptagon.c_loc = cd.c_loc; }
let translate_program p = let translate_program p =
List.iter open_module p.p_opened; List.iter open_module p.p_opened;
let p_consts, const_env =
Misc.mapfold translate_const_dec NamesEnv.empty p.p_consts in
{ Heptagon.p_modname = p.p_modname; { Heptagon.p_modname = p.p_modname;
Heptagon.p_opened = p.p_opened; Heptagon.p_opened = p.p_opened;
Heptagon.p_types = List.map (translate_typedec const_env) p.p_types; Heptagon.p_types = List.map translate_typedec p.p_types;
Heptagon.p_nodes = Heptagon.p_nodes = List.map translate_node p.p_nodes;
List.map (translate_node const_env Rename.empty) p.p_nodes; Heptagon.p_consts = List.map translate_const_dec p.p_consts; }
Heptagon.p_consts = p_consts; }
let translate_arg const_env a =
Signature.mk_arg a.a_name (translate_type const_env a.a_type)
let translate_signature s = let translate_signature s =
let const_env = build_id_list no_location NamesEnv.empty s.sig_params in let local_const = build_const s.sig_loc s.sig_params in
{ Heptagon.sig_name = s.sig_name; let translate_arg a =
Heptagon.sig_inputs = List.map (translate_arg const_env) s.sig_inputs; Signature.mk_arg a.a_name (translate_type s.sig_loc local_const a.a_type) in
Heptagon.sig_outputs = List.map (translate_arg const_env) s.sig_outputs; let n = current_qual s.sig_name in
Heptagon.sig_statefull = s.sig_statefull; let i = List.map translate_arg s.sig_inputs in
Heptagon.sig_params = List.map (param_of_var_dec const_env) s.sig_params; } let o = List.map translate_arg s.sig_outputs in
let p = params_of_var_decs local_const s.sig_params in
let translate_interface_desc const_env = function add_value n (Signature.mk_node i o s.sig_statefull p);
| Iopen n -> Heptagon.Iopen n, const_env Heptagon.mk_signature n i o s.sig_statefull p s.sig_loc
| Itypedef tydec ->
Heptagon.Itypedef (translate_typedec const_env tydec), const_env
| Iconstdef const_dec -> let translate_interface_desc = function
let const_dec, const_env = translate_const_dec const_env const_dec in | Iopen n -> open_module n; Heptagon.Iopen n
Heptagon.Iconstdef const_dec, const_env | Itypedef tydec -> Heptagon.Itypedef (translate_typedec tydec)
| Isignature s -> Heptagon.Isignature (translate_signature s) , const_env | Iconstdef const_dec -> Heptagon.Iconstdef (translate_const_dec const_dec)
| Isignature s -> Heptagon.Isignature (translate_signature s)
let translate_interface_decl const_env idecl =
let desc, const_env = let translate_interface_decl idecl =
translate_interface_desc const_env idecl.interf_desc in let desc = translate_interface_desc idecl.interf_desc in
{ Heptagon.interf_desc = desc; { Heptagon.interf_desc = desc;
Heptagon.interf_loc = idecl.interf_loc }, const_env Heptagon.interf_loc = idecl.interf_loc }
let translate_interface i = let translate_interface i = List.map translate_interface_decl i
let i, _ = Misc.mapfold translate_interface_decl NamesEnv.empty i in
i

@ -48,7 +48,7 @@ let intro_type states =
let state_type = "st" ^ n in let state_type = "st" ^ n in
state_type_dec_list := state_type_dec_list :=
(mk_type_dec state_type (Type_enum (list states))) :: !state_type_dec_list; (mk_type_dec state_type (Type_enum (list states))) :: !state_type_dec_list;
Name(state_type) current_qual state_type
(** Allows to classify an automaton : (** Allows to classify an automaton :
Moore automatons doesn't have strong transitions, Moore automatons doesn't have strong transitions,

@ -389,8 +389,7 @@ let typedec
| Heptagon.Type_abs -> Type_abs | Heptagon.Type_abs -> Type_abs
| Heptagon.Type_alias ln -> Type_alias ln | Heptagon.Type_alias ln -> Type_alias ln
| Heptagon.Type_enum tag_list -> Type_enum tag_list | Heptagon.Type_enum tag_list -> Type_enum tag_list
| Heptagon.Type_struct field_ty_list -> | Heptagon.Type_struct field_ty_list -> Type_struct field_ty_list
Type_struct field_ty_list
in in
{ t_name = n; t_desc = onetype tdesc; t_loc = loc } { t_name = n; t_desc = onetype tdesc; t_loc = loc }

@ -9,9 +9,10 @@
open Misc open Misc
open Modules
open Location open Location
open Compiler_utils open Compiler_utils
open Hept_compiler
@ -35,31 +36,22 @@ let compile_impl modname filename =
init_compiler modname; init_compiler modname;
add_include (Filename.dirname filename); add_include (Filename.dirname filename);
(* Set pretty printer to the Heptagon one *)
let pp = Hept_compiler.pp in
(* Parsing of the file *) (* Parsing of the file *)
let p = Hept_compiler.parse_implementation lexbuf in let p = do_silent_pass "Parsing" (parse_implementation modname) lexbuf in
let p = { p with Hept_parsetree.p_modname = modname } in
comment "Parsing";
(* Convert the parse tree to Heptagon AST *) (* Convert the parse tree to Heptagon AST *)
let p = Hept_scoping.translate_program p in let p = do_pass "Scoping" Hept_scoping.translate_program p pp in
comment "Scoping";
pp p;
(* Process the Heptagon AST *) (* Process the Heptagon AST *)
let p = Hept_compiler.compile_impl pp p in let p = compile_impl pp p in
Modules.write itc; Modules.write_current_module itc;
(* Set pretty printer to the Minils one *) (* Set pretty printer to the Minils one *)
let pp = Mls_compiler.pp in let pp = Mls_compiler.pp in
(* Compile Heptagon to MiniLS *) (* Compile Heptagon to MiniLS *)
let p = Hept2mls.program p in let p = do_pass "Translation into MiniLs" Hept2mls.program p pp in
Mls_printer.print mlsc p; Mls_printer.print mlsc p;
comment "Translation into MiniLs";
pp p;
(* Process the MiniLS AST *) (* Process the MiniLS AST *)
let p = Mls_compiler.compile pp p in let p = Mls_compiler.compile pp p in
@ -69,9 +61,7 @@ let compile_impl modname filename =
close_all_files () close_all_files ()
with with x -> close_all_files (); raise x
| x -> close_all_files (); raise x
let main () = let main () =
@ -95,7 +85,7 @@ let main () =
"-noinit", Arg.Clear init, doc_noinit; "-noinit", Arg.Clear init, doc_noinit;
"-fti", Arg.Set full_type_info, doc_full_type_info; "-fti", Arg.Set full_type_info, doc_full_type_info;
] ]
(Hept_compiler.compile compile_impl) (compile compile_impl)
errmsg; errmsg;
with with
| Misc.Error -> exit 2;; | Misc.Error -> exit 2;;

@ -26,7 +26,7 @@ let static_exp_of_int i =
let gen_obj_name n = let gen_obj_name n =
(shortname n) ^ "_mem" ^ (gen_symbol ()) (shortname n) ^ "_mem" ^ (gen_symbol ())
let op_from_string op = Modname { qual = "Pervasives"; id = op; } let op_from_string op = { qual = "Pervasives"; name = op; }
let rec lhs_of_idx_list e = function let rec lhs_of_idx_list e = function
| [] -> e | idx :: l -> mk_lhs (Larray (lhs_of_idx_list e l, idx)) | [] -> e | idx :: l -> mk_lhs (Larray (lhs_of_idx_list e l, idx))
@ -206,8 +206,8 @@ let rec translate_eq map call_context { Minils.eq_lhs = pat; Minils.eq_rhs = e }
let vf = translate_var_dec map vf in let vf = translate_var_dec map vf in
let vt = translate_var_dec map vt in let vt = translate_var_dec map vt in
let action = let action =
Acase (cond, [Name "true", mk_block ~locals:vt true_act; Acase (cond, [ptrue, mk_block ~locals:vt true_act;
Name "false", mk_block ~locals:vf false_act]) in pfalse, mk_block ~locals:vf false_act]) in
v, si, j, (control map ck action) :: s v, si, j, (control map ck action) :: s
| Minils.Evarpat x, | Minils.Evarpat x,
@ -251,8 +251,8 @@ let rec translate_eq map call_context { Minils.eq_lhs = pat; Minils.eq_rhs = e }
Aassgn (x, mk_exp (Elhs (lhs_of_idx_list (lhs_of_exp e1) idx))) in Aassgn (x, mk_exp (Elhs (lhs_of_idx_list (lhs_of_exp e1) idx))) in
let false_act = Aassgn (x, translate map (si, j, s) e2) in let false_act = Aassgn (x, translate map (si, j, s) e2) in
let cond = bound_check_expr idx bounds in let cond = bound_check_expr idx bounds in
let action = Acase (cond, [ Name "true", mk_block [true_act]; let action = Acase (cond, [ ptrue, mk_block [true_act];
Name "false", mk_block [false_act] ]) in pfalse, mk_block [false_act] ]) in
v, si, j, (control map ck action) :: s v, si, j, (control map ck action) :: s
| Minils.Evarpat x, | Minils.Evarpat x,
@ -264,7 +264,7 @@ let rec translate_eq map call_context { Minils.eq_lhs = pat; Minils.eq_rhs = e }
let action = Aassgn (lhs_of_idx_list x idx, let action = Aassgn (lhs_of_idx_list x idx,
translate map (si, j, s) e2) in translate map (si, j, s) e2) in
let cond = bound_check_expr idx bounds in let cond = bound_check_expr idx bounds in
let action = Acase (cond, [ Name "true", mk_block [action] ]) in let action = Acase (cond, [ ptrue, mk_block [action] ]) in
let copy = Aassgn (x, translate map (si, j, s) e1) in let copy = Aassgn (x, translate map (si, j, s) e1) in
v, si, j, (control map ck copy) :: (control map ck action) :: s v, si, j, (control map ck copy) :: (control map ck action) :: s
@ -327,7 +327,7 @@ and mk_node_call map call_context app loc name_list args =
let e = mk_exp (Eop(f, args)) in let e = mk_exp (Eop(f, args)) in
[], [], [], [Aassgn(List.hd name_list, e) ] [], [], [], [Aassgn(List.hd name_list, e) ]
| Minils.Enode f when Itfusion.is_anon_node f -> | Minils.Enode f when Itfusion.is_anon_node f ->
let add_input env vd = let add_input env vd =
Env.add vd.Minils.v_ident (mk_lhs (Lvar vd.Minils.v_ident)) env in Env.add vd.Minils.v_ident (mk_lhs (Lvar vd.Minils.v_ident)) env in
let build env vd a = let build env vd a =
@ -346,7 +346,7 @@ and mk_node_call map call_context app loc name_list args =
act_list act_list
in in
let nd = Itfusion.find_anon_node f in let nd = Itfusion.find_anon_node f in
let map = List.fold_left add_input map nd.Minils.n_input in let map = List.fold_left add_input map nd.Minils.n_input in
let map = List.fold_left2 build map nd.Minils.n_output name_list in let map = List.fold_left2 build map nd.Minils.n_output name_list in
let map = List.fold_left add_input map nd.Minils.n_local in let map = List.fold_left add_input map nd.Minils.n_local in
@ -480,24 +480,24 @@ let translate_node
let resetm = { let resetm = {
m_name = Mreset; m_inputs = []; m_outputs = []; m_name = Mreset; m_inputs = []; m_outputs = [];
m_body = mk_block si } in m_body = mk_block si } in
{ cd_name = f; cd_mems = m; cd_params = params; { cd_name = shortname f; cd_mems = m; cd_params = params;
cd_objs = j; cd_methods = [stepm; resetm]; cd_objs = j; cd_methods = [stepm; resetm];
cd_loc = loc } cd_loc = loc }
let translate_ty_def { Minils.t_name = name; Minils.t_desc = tdesc; let translate_ty_def { Minils.t_name = name; Minils.t_desc = tdesc;
Minils.t_loc = loc } = Minils.t_loc = loc } =
let tdesc = let tdesc = match tdesc with
match tdesc with | Minils.Type_abs -> Type_abs
| Minils.Type_abs -> Type_abs | Minils.Type_alias ln -> Type_alias ln
| Minils.Type_alias ln -> Type_alias ln | Minils.Type_enum tag_name_list ->
| Minils.Type_enum tag_name_list -> Type_enum tag_name_list Type_enum (List.map shortname tag_name_list)
| Minils.Type_struct field_ty_list -> | Minils.Type_struct field_ty_list ->
Type_struct field_ty_list Type_struct field_ty_list in
in { t_name = name; t_desc = tdesc; t_loc = loc } { t_name = shortname name; t_desc = tdesc; t_loc = loc }
let translate_const_def { Minils.c_name = name; Minils.c_value = se; let translate_const_def { Minils.c_name = name; Minils.c_value = se;
Minils.c_type = ty; Minils.c_loc = loc } = Minils.c_type = ty; Minils.c_loc = loc } =
{ c_name = name; { c_name = shortname name;
c_value = se; c_value = se;
c_type = ty; c_type = ty;
c_loc = loc } c_loc = loc }

@ -12,10 +12,9 @@ open Compiler_utils
let pp p = if !verbose then Mls_printer.print stdout p let pp p = if !verbose then Mls_printer.print stdout p
let parse prog_name parsing_fun lexing_fun lexbuf = let parse parsing_fun lexing_fun lexbuf =
try try
let p = parsing_fun lexing_fun lexbuf in parsing_fun lexing_fun lexbuf
{ p with p_modname = prog_name }
with with
| Mls_lexer.Lexical_error(err, loc) -> | Mls_lexer.Lexical_error(err, loc) ->
lexical_error err loc lexical_error err loc
@ -26,22 +25,23 @@ let parse prog_name parsing_fun lexing_fun lexbuf =
syntax_error l syntax_error l
let parse_implementation prog_name lexbuf = let parse_implementation prog_name lexbuf =
parse prog_name Mls_parser.program Mls_lexer.token lexbuf let p = parse Mls_parser.program Mls_lexer.token lexbuf in
{ p with Mls_parsetree.p_modname = prog_name }
let compile pp p = let compile pp p =
(* Clocking *) (* Clocking *)
let p = do_pass Clocking.program "Clocking" p pp true in let p = pass "Clocking" true Clocking.program p pp in
(* Check that the dataflow code is well initialized *) (* Check that the dataflow code is well initialized *)
(*let p = do_silent_pass Init.program "Initialization check" p !init in *) (*let p = silent_pass "Initialization check" !init Init.program p in *)
(* Iterator fusion *) (* Iterator fusion *)
let p = do_pass Itfusion.program "Iterator fusion" p pp true in (*let p = pass "Iterator fusion" false Itfusion.program p pp in*)
(* Normalization to maximize opportunities *) (* Normalization to maximize opportunities *)
let p = do_pass Normalize.program "Normalization" p pp true in let p = pass "Normalization" true Normalize.program p pp in
(* Scheduling *) (* Scheduling *)
let p = do_pass Schedule.program "Scheduling" p pp true in let p = pass "Scheduling" true Schedule.program p pp in
p p

@ -36,12 +36,11 @@ let compile_impl modname filename =
let pp = Mls_compiler.pp in let pp = Mls_compiler.pp in
(* Parsing of the file *) (* Parsing of the file *)
let p = let p = do_silent_pass "Parsing" (Mls_compiler.parse_implementation modname)
do_silent_pass Mls_compiler.parse_implementation "Parsing" lexbuf true in lexbuf in
let p = { p with Minils.p_modname = modname } in
(* Convert Parse tree to Minils AST *) (* Convert Parse tree to Minils AST *)
let p = Mls_scoping.translate_program "Scoping" p pp true in let p = do_pass "Scoping" Mls_scoping.translate_program p pp in
(* Process the MiniLS AST *) (* Process the MiniLS AST *)
let p = Mls_compiler.compile pp p in let p = Mls_compiler.compile pp p in

@ -28,14 +28,14 @@ type iterator_type =
| Imapfold | Imapfold
type type_dec = { type type_dec = {
t_name: name; t_name: qualname;
t_desc: tdesc; t_desc: tdesc;
t_loc: location } t_loc: location }
and tdesc = and tdesc =
| Type_abs | Type_abs
| Type_alias of ty | Type_alias of ty
| Type_enum of name list | Type_enum of constructor_name list
| Type_struct of structure | Type_struct of structure
and exp = { and exp = {
@ -58,7 +58,7 @@ and edesc =
| Estruct of (field_name * exp) list | Estruct of (field_name * exp) list
(** { field=exp; ... } *) (** { field=exp; ... } *)
| Eiterator of iterator_type * app * static_exp * exp list * var_ident option | Eiterator of iterator_type * app * static_exp * exp list * var_ident option
(** map f <<n>> (exp,exp...) reset ident *) (** map f <<n>> (exp, exp...) reset ident *)
and app = { a_op: op; a_params: static_exp list; a_unsafe: bool } and app = { a_op: op; a_params: static_exp list; a_unsafe: bool }
(** Unsafe applications could have side effects (** Unsafe applications could have side effects
@ -79,8 +79,7 @@ and op =
| Eselect_dyn (** arg1.[arg3...] default arg2 *) | Eselect_dyn (** arg1.[arg3...] default arg2 *)
| Eupdate (** [ arg1 with arg3..arg_n = arg2 ] *) | Eupdate (** [ arg1 with arg3..arg_n = arg2 ] *)
| Econcat (** arg1@@arg2 *) | Econcat (** arg1@@arg2 *)
(*
*)
type pat = type pat =
| Etuplepat of pat list | Etuplepat of pat list
@ -104,7 +103,7 @@ type contract = {
c_eq : eq list } c_eq : eq list }
type node_dec = { type node_dec = {
n_name : name; n_name : qualname;
n_input : var_dec list; n_input : var_dec list;
n_output : var_dec list; n_output : var_dec list;
n_contract : contract option; n_contract : contract option;
@ -115,7 +114,7 @@ type node_dec = {
n_params_constraints : size_constraint list } n_params_constraints : size_constraint list }
type const_dec = { type const_dec = {
c_name : name; c_name : qualname;
c_type : ty; c_type : ty;
c_value : static_exp; c_value : static_exp;
c_loc : location } c_loc : location }

@ -6,6 +6,7 @@ open Clocks
open Static open Static
open Format open Format
open Signature open Signature
open Global_printer
open Pp_tools open Pp_tools
open Minils open Minils
@ -29,7 +30,7 @@ let rec print_pat ff = function
let rec print_ck ff = function let rec print_ck ff = function
| Cbase -> fprintf ff "base" | Cbase -> fprintf ff "base"
| Con (ck, c, n) -> | Con (ck, c, n) ->
fprintf ff "%a on %a(%a)" print_ck ck print_longname c print_ident n fprintf ff "%a on %a(%a)" print_ck ck print_qualname c print_ident n
| Cvar { contents = Cindex n } -> fprintf ff "base" | Cvar { contents = Cindex n } -> fprintf ff "base"
| Cvar { contents = Clink ck } -> print_ck ff ck | Cvar { contents = Clink ck } -> print_ck ff ck
@ -50,10 +51,10 @@ let print_local_vars ff = function
let print_const_dec ff c = let print_const_dec ff c =
if !Misc.full_type_info then if !Misc.full_type_info then
fprintf ff "const %a : %a = %a" fprintf ff "const %a : %a = %a"
print_name c.c_name print_type c.c_type print_static_exp c.c_value print_qualname c.c_name print_type c.c_type print_static_exp c.c_value
else else
fprintf ff "const %a = %a" fprintf ff "const %a = %a"
print_name c.c_name print_static_exp c.c_value; print_qualname c.c_name print_static_exp c.c_value;
fprintf ff "@." fprintf ff "@."
@ -95,12 +96,12 @@ and print_exp_desc ff = function
print_app (app, args) print_every reset print_app (app, args) print_every reset
| Ewhen (e, c, n) -> | Ewhen (e, c, n) ->
fprintf ff "@[<2>(%a@ when %a(%a))@]" fprintf ff "@[<2>(%a@ when %a(%a))@]"
print_exp e print_longname c print_ident n print_exp e print_qualname c print_ident n
| Emerge (x, tag_e_list) -> | Emerge (x, tag_e_list) ->
fprintf ff "@[<2>merge %a@ %a@]" fprintf ff "@[<2>merge %a@ %a@]"
print_ident x print_tag_e_list tag_e_list print_ident x print_tag_e_list tag_e_list
| Estruct f_e_list -> | Estruct f_e_list ->
print_record (print_couple print_longname print_exp """ = """) ff f_e_list print_record (print_couple print_qualname print_exp """ = """) ff f_e_list
| Eiterator (it, f, param, args, reset) -> | Eiterator (it, f, param, args, reset) ->
fprintf ff "@[<2>(%s (%a)<<%a>>)@,%a@]%a" fprintf ff "@[<2>(%s (%a)<<%a>>)@,%a@]%a"
(iterator_to_string it) (iterator_to_string it)
@ -115,7 +116,7 @@ and print_app ff (app, args) = match app.a_op, app.a_params, args with
| Etuple, _, a -> print_exp_tuple ff a | Etuple, _, a -> print_exp_tuple ff a
| (Efun(f)|Enode(f)), p, a -> | (Efun(f)|Enode(f)), p, a ->
fprintf ff "@[%a@,%a@,%a@]" fprintf ff "@[%a@,%a@,%a@]"
print_longname f print_params p print_exp_tuple a print_qualname f print_params p print_exp_tuple a
| Eifthenelse, _, [e1; e2; e3] -> | Eifthenelse, _, [e1; e2; e3] ->
fprintf ff "@[<hv>if %a@ then %a@ else %a@]" fprintf ff "@[<hv>if %a@ then %a@ else %a@]"
print_exp e1 print_exp e2 print_exp e3 print_exp e1 print_exp e2 print_exp e3
@ -139,7 +140,7 @@ and print_app ff (app, args) = match app.a_op, app.a_params, args with
fprintf ff "@[<2>%a@ @@ %a@]" print_exp e1 print_exp e2 fprintf ff "@[<2>%a@ @@ %a@]" print_exp e1 print_exp e2
and print_handler ff c = and print_handler ff c =
fprintf ff "@[<2>%a@]" (print_couple print_longname print_exp "("" -> "")") c fprintf ff "@[<2>%a@]" (print_couple print_qualname print_exp "("" -> "")") c
and print_tag_e_list ff tag_e_list = and print_tag_e_list ff tag_e_list =
fprintf ff "@[%a@]" (print_list print_handler """""") tag_e_list fprintf ff "@[%a@]" (print_list print_handler """""") tag_e_list
@ -163,14 +164,14 @@ let rec print_type_dec ff { t_name = name; t_desc = tdesc } =
| Type_abs -> () | Type_abs -> ()
| Type_alias ty -> fprintf ff " =@ %a" print_type ty | Type_alias ty -> fprintf ff " =@ %a" print_type ty
| Type_enum tag_name_list -> | Type_enum tag_name_list ->
fprintf ff " =@ %a" (print_list print_name """|""") tag_name_list fprintf ff " =@ %a" (print_list print_qualname """|""") tag_name_list
| Type_struct f_ty_list -> | Type_struct f_ty_list ->
fprintf ff " =@ %a" (print_record print_field) f_ty_list in fprintf ff " =@ %a" (print_record print_field) f_ty_list in
fprintf ff "@[<2>type %s%a@]@." name print_type_desc tdesc fprintf ff "@[<2>type %a%a@]@." print_qualname name print_type_desc tdesc
and print_field ff field = and print_field ff field =
fprintf ff "@[%a: %a@]" print_name field.f_name print_type field.f_type fprintf ff "@[%a: %a@]" print_qualname field.f_name print_type field.f_type
let print_contract ff { c_local = l; c_eq = eqs; let print_contract ff { c_local = l; c_eq = eqs;
@ -185,8 +186,8 @@ let print_contract ff { c_local = l; c_eq = eqs;
let print_node ff { n_name = n; n_input = ni; n_output = no; let print_node ff { n_name = n; n_input = ni; n_output = no;
n_contract = contract; n_local = nl; n_contract = contract; n_local = nl;
n_equs = ne; n_params = params } = n_equs = ne; n_params = params } =
fprintf ff "@[node %s%a%a@ returns %a@]@\n%a%a%a@]@\n@." fprintf ff "@[node %a%a%a@ returns %a@]@\n%a%a%a@]@\n@."
n print_qualname n
print_node_params params print_node_params params
print_vd_tuple ni print_vd_tuple ni
print_vd_tuple no print_vd_tuple no
@ -196,9 +197,9 @@ let print_node ff { n_name = n; n_input = ni; n_output = no;
let print oc { p_opened = pm; p_types = pt; p_nodes = pn; p_consts = pc } = let print oc { p_opened = pm; p_types = pt; p_nodes = pn; p_consts = pc } =
let ff = formatter_of_out_channel oc in ( let ff = formatter_of_out_channel oc in
List.iter (print_open_module ff) pm; List.iter (print_open_module ff) pm;
List.iter (print_const_dec ff) pc; List.iter (print_const_dec ff) pc;
List.iter (print_type_dec ff) pt; List.iter (print_type_dec ff) pt;
List.iter (print_node ff) pn; List.iter (print_node ff) pn;
fprintf ff "@?" ) fprintf ff "@?"

@ -46,14 +46,13 @@ let rec vd_mem n = function
(** @return whether [ty] corresponds to a record type. *) (** @return whether [ty] corresponds to a record type. *)
let is_record_type ty = match ty with let is_record_type ty = match ty with
| Tid n -> | Tid n ->
(try (match Modules.find_type n with
ignore (Modules.find_struct n); true | Tenum _ -> true
with | _ -> false)
Not_found -> false)
| _ -> false | _ -> false
let is_op = function let is_op = function
| Modname { qual = "Pervasives"; id = _ } -> true | _ -> false | { qual = "Pervasives"; name = _ } -> true | _ -> false
let exp_list_of_static_exp_list se_list = let exp_list_of_static_exp_list se_list =

@ -113,7 +113,7 @@ rule token = parse
| newline { new_line lexbuf; token lexbuf } | newline { new_line lexbuf; token lexbuf }
| [' ' '\t'] + { token lexbuf } | [' ' '\t'] + { token lexbuf }
| "." { DOT } | "." { DOT }
| ".." { DOTDOt } | ".." { DOTDOT }
| "(" { LPAREN } | "(" { LPAREN }
| ")" { RPAREN } | ")" { RPAREN }
| "*" { STAR } | "*" { STAR }

@ -77,8 +77,8 @@ open Mls_utils
| P v=x { Some(v) } | P v=x { Some(v) }
qualified(x) : qualified(x) :
| n=x { Name(n) } | n=x { Modules.qualname n }
| m=CONSTRUCTOR DOT n=x { Modname({ qual = m; id = n }) } | m=CONSTRUCTOR DOT n=x { { qual = m; name = n } }
structure(field): LBRACE s=snlist(SEMICOL,field) RBRACE {s} structure(field): LBRACE s=snlist(SEMICOL,field) RBRACE {s}
@ -94,31 +94,30 @@ opens: OPEN c=CONSTRUCTOR {c}
const_decs: c=list(const_dec) {c} const_decs: c=list(const_dec) {c}
const_dec: const_dec:
| CONST n=NAME COLON t=type_ident EQUAL e=const | CONST n=qualname COLON t=type_ident EQUAL e=const
{ mk_const_dec n t e (Loc($startpos,$endpos)) } { mk_const_dec n t e (Loc($startpos,$endpos)) }
name: n=NAME | LPAREN n=infix_ RPAREN | LPAREN n=prefix_ RPAREN { n } name: n=NAME | LPAREN n=infix RPAREN | LPAREN n=prefix RPAREN { n }
ident: n=name { ident_of_name n } qualname: n=name { Modules.qualname n }
field_type : n=NAME COLON t=type_ident { mk_field n t } field_type : n=qualname COLON t=type_ident { mk_field n t }
type_ident: NAME { Tid(Name($1)) } type_ident: qualname { Tid($1) }
type_decs: t=list(type_dec) {t} type_decs: t=list(type_dec) {t}
type_dec: type_dec:
| TYPE n=NAME | TYPE n=qualname
{ mk_type_dec Type_abs n (Loc ($startpos,$endpos)) } { mk_type_dec Type_abs n (Loc ($startpos,$endpos)) }
| TYPE n=NAME EQUAL e=snlist(BAR,NAME) | TYPE n=qualname EQUAL e=snlist(BAR,constructor)
{ mk_type_dec (Type_enum e) n (Loc ($startpos,$endpos)) } { mk_type_dec (Type_enum e) n (Loc ($startpos,$endpos)) }
| TYPE n=NAME EQUAL s=structure(field_type) | TYPE n=qualname EQUAL s=structure(field_type)
{ mk_type_dec (Type_struct s) n (Loc ($startpos,$endpos)) } { mk_type_dec (Type_struct s) n (Loc ($startpos,$endpos)) }
node_decs: ns=list(node_dec) {ns} node_decs: ns=list(node_dec) {ns}
node_dec: node_dec:
NODE n=name p=params(n_param) LPAREN args=args RPAREN NODE n=qualname p=params(n_param) LPAREN args=args RPAREN
RETURNS LPAREN out=args RPAREN vars=loc_vars eqs=equs RETURNS LPAREN out=args RPAREN vars=loc_vars eqs=equs
{ mk_node ~input:args ~output:out ~local:vars { mk_node p args out vars eqs ~loc:(Loc ($startpos,$endpos)) n }
~eq:eqs ~loc:(Loc ($startpos,$endpos)) n }
args_t: SEMICOL p=args {p} args_t: SEMICOL p=args {p}
@ -140,10 +139,6 @@ ck:
| ck_base { Cbase } | ck_base { Cbase }
| ck=ck ON c=constructor LPAREN x=NAME RPAREN { Con (ck, c, x) } | ck=ck ON c=constructor LPAREN x=NAME RPAREN { Con (ck, c, x) }
ct:
| LPAREN ctl=snlist(STAR,ct) RPAREN { Cprod ctl }
| c=ck { Ck c }
clock_annot: clock_annot:
| /*empty*/ { Cbase } | /*empty*/ { Cbase }
| COLONCOLON c=ck { c } | COLONCOLON c=ck { c }
@ -159,68 +154,75 @@ pat:
| n=NAME {Evarpat n} | n=NAME {Evarpat n}
| LPAREN p=snlist(COMMA, pat) RPAREN {Etuplepat p} | LPAREN p=snlist(COMMA, pat) RPAREN {Etuplepat p}
longname: l=qualified(name) {l} /* qualified var (not a constructor) */ longname: l=qualified(name) {l}
constructor: /* of type longname */ constructor: /* of type longname */
| ln=qualified(CONSTRUCTOR) { ln } | ln=qualified(CONSTRUCTOR) { ln }
| b=BOOL { Name(if b then "true" else "false") } | b=BOOL { if b then Initial.ptrue else Initial.pfalse }
field: field:
| ln=longname { mk_static_exp ~loc:(Loc($startpos,$endpos)) (Sconstructor ln)} | c=constructor { mk_constructor_exp c (Loc($startpos,$endpos))}
const : c=_const { mk_static_exp ~loc:(Loc ($startpos,$endpos)) c } const: c=_const { mk_static_exp ~loc:(Loc ($startpos,$endpos)) c }
_const: _const:
| i=INT { Sint i } | i=INT { Sint i }
| f=FLOAT { Sfloat f } | f=FLOAT { Sfloat f }
| c=constructor { Sconstructor c } | c=constructor { Sconstructor c }
| t=tuple(const) { Stuple t }
exps: LPAREN e=slist(COMMA, exp) RPAREN {e} exps: LPAREN e=slist(COMMA, exp) RPAREN {e}
field_exp: longname EQUAL exp { ($1, $3) } field_exp: longname EQUAL exp { ($1, $3) }
simple_exp: simple_exp:
| e=_simple_exp {mk_exp e (Loc ($startpos,$endpos)) } | e=_simple_exp {mk_exp e (Loc ($startpos,$endpos)) }
_simple_exp: _simple_exp:
| n=NAME { Evar (ident_of_name n) } | n=NAME { Evar n }
| s=structure(field_exp) { Estruct s } | s=structure(field_exp) { Estruct s }
| t=tuple(exp) { Eapp(mk_app Etuple, t, None) } | t=tuple(exp_woc) { mk_call [] Etuple t None }
| LBRACKET es=slist(COMMA, exp) RBRACKET { Eapp(mk_app Earray, es, None) } | t=tuple(const)
{Econst (mk_static_exp ~loc:(Loc ($startpos,$endpos)) (Stuple t))}
| LBRACKET es=slist(COMMA, exp) RBRACKET { mk_call [] Earray es None }
| LPAREN e=_exp RPAREN { e } | LPAREN e=_exp RPAREN { e }
exp: exp:
| e=simple_exp { e } | e=simple_exp { e }
| e=_exp { mk_exp e (Loc ($startpos,$endpos)) } | e=_exp { mk_exp e (Loc ($startpos,$endpos)) }
exp_woc:
| e=simple_exp { e }
| e=_exp_woc { mk_exp e (Loc ($startpos,$endpos)) }
_exp: _exp:
| e=_exp_woc {e}
| c=const { Econst c } | c=const { Econst c }
| v=const FBY e=exp { Efby(Some(v), e) } _exp_woc:
| v=exp FBY e=exp { Efby(Some(v), e) }
| PRE exp { Efby(None,$2) } | PRE exp { Efby(None,$2) }
| op=funapp a=exps r=reset { Eapp(op, a, r) } | app=funapp a=exps r=reset { Eapp(app, a, r) }
| e1=exp i_op=infix e2=exp | e1=exp i_op=infix e2=exp
{ Eapp(mk_app (Efun i_op), [e1; e2], None) } { mk_op_call i_op [e1; e2] }
| p_op=prefix e=exp %prec prefixs | p_op=prefix e=exp %prec prefixs
{ Eapp(mk_app (Efun p_op), [e], None) } { mk_op_call p_op [e] }
| IF e1=exp THEN e2=exp ELSE e3=exp | IF e1=exp THEN e2=exp ELSE e3=exp
{ Eapp( mk_app Eifthenelse, [e1; e2; e3], None) } { mk_call [] Eifthenelse [e1; e2; e3] None }
| e=simple_exp DOT f=field | e=simple_exp DOT f=field
{ Eapp( mk_app ~params:[f] Efield, [e], None) } { mk_call [f] Efield [e] None }
| e=exp WHEN c=constructor LPAREN n=ident RPAREN { Ewhen(e, c, n) } | e=exp WHEN c=constructor LPAREN n=name RPAREN { Ewhen(e, c, n) }
| MERGE n=ident h=handlers { Emerge(n, h) } | MERGE n=name h=handlers { Emerge(n, h) }
| LPAREN r=exp WITH DOT f=field EQUAL nv=exp | LPAREN r=exp WITH DOT f=field EQUAL nv=exp
{ Eapp(mk_app ~params:[f] Efield_update, [r; nv], None) } { mk_call [f] Efield_update [r; nv] None }
| e=exp POWER p=e_param | e=exp POWER p=e_param
{ Eapp(mk_app ~params:[p] Earray_fill, [e], None) } { mk_call [p] Earray_fill [e] None }
| e=simple_exp i=indexes(exp) /* not e_params to solve conflicts */ | e=simple_exp i=indexes(exp) /* not e_params to solve conflicts */
{ Eapp(mk_app ~params:i Eselect, [e], None) } { mk_call i Eselect [e] None }
| e=simple_exp i=indexes(exp) DEFAULT d=exp | e=simple_exp i=indexes(exp) DEFAULT d=exp
{ Eapp(mk_app Eselect_dyn, [e; d]@i, None) } { mk_call [] Eselect_dyn ([e; d]@i) None }
| LPAREN e=exp WITH i=indexes(e_param) EQUAL nv=exp | LPAREN e=exp WITH i=indexes(e_param) EQUAL nv=exp
{ Eapp(mk_app ~params:i Eupdate, [e; nv], None) } { mk_call i Eupdate [e; nv] None }
| e=simple_exp LBRACKET i1=e_param DOTDOT i2=e_param RBRACKET | e=simple_exp LBRACKET i1=e_param DOTDOT i2=e_param RBRACKET
{ Eapp(mk_app ~params:[i1; i2] Eselect_slice, [e], None) } { mk_call [i1; i2] Eselect_slice [e] None }
| e1=exp AROBASE e2=exp { Eapp(mk_app Econcat, [e1;e2], None) } | e1=exp AROBASE e2=exp { mk_call [] Econcat [e1;e2] None }
| LPAREN f=iterator LPAREN op=funapp RPAREN | LPAREN f=iterator LPAREN op=funapp RPAREN
DOUBLE_LESS p=e_param DOUBLE_GREATER DOUBLE_LESS p=e_param DOUBLE_GREATER
RPAREN a=exps r=reset { Eiterator(f,op,p,a,r) } RPAREN a=exps r=reset { Eiterator(f,op,p,a,r) }
@ -232,7 +234,7 @@ index(param): LBRACKET p=param RBRACKET { p }
/* Merge handlers ( B -> e)( C -> ec)... */ /* Merge handlers ( B -> e ) ( C -> ec )... */
handlers: hs=nonempty_list(handler) { hs } handlers: hs=nonempty_list(handler) { hs }
handler: LPAREN c=constructor ARROW e=exp RPAREN { c,e } handler: LPAREN c=constructor ARROW e=exp RPAREN { c,e }
@ -242,22 +244,20 @@ iterator:
| FOLD { Ifold } | FOLD { Ifold }
| MAPFOLD { Imapfold } | MAPFOLD { Imapfold }
reset: r=option(RESET,ident) { r } reset: r=option(RESET,name) { r }
/* TODO : Scoping to deal with node and fun ! */
funapp: ln=longname p=params(e_param) { mk_app p (Enode ln) } funapp: ln=longname p=params(e_param) { mk_app p (Enode ln) }
/* inline so that precendance of POWER is respected in exp */ /* inline so that precendance of POWER is respected in exp */
%inline e_param: e=exp { e } %inline e_param: e=exp { e }
n_param: n=NAME { mk_param n } n_param: n=NAME COLON ty=type_ident { mk_param n ty }
params(param): params(param):
| /*empty*/ { [] } | /*empty*/ { [] }
| DOUBLE_LESS p=slist(COMMA, param) DOUBLE_GREATER { p } | DOUBLE_LESS p=slist(COMMA, param) DOUBLE_GREATER { p }
/*Inlining is compulsory in order to preserve priorities*/ /*Inlining is compulsory in order to preserve priorities*/
%inline infix: op=infix_ { Name(op) } %inline infix:
%inline infix_:
| op=INFIX0 | op=INFIX1 | op=INFIX2 | op=INFIX3 | op=INFIX4 { op } | op=INFIX0 | op=INFIX1 | op=INFIX2 | op=INFIX3 | op=INFIX4 { op }
| STAR { "*" } | STAR { "*" }
| EQUAL { "=" } | EQUAL { "=" }
@ -265,8 +265,7 @@ params(param):
| AMPERSAND { "&" } | AMPERAMPER { "&&" } | AMPERSAND { "&" } | AMPERAMPER { "&&" }
| OR { "or" } | BARBAR { "||" } | OR { "or" } | BARBAR { "||" }
%inline prefix: op=prefix_ { Name(op) } %inline prefix:
%inline prefix_:
| op = PREFIX { op } | op = PREFIX { op }
| NOT { "not" } | NOT { "not" }
| op = SUBTRACTIVE { "~" ^ op } /*TODO test 3 * -2 and co */ | op = SUBTRACTIVE { "~" ^ op } /*TODO test 3 * -2 and co */

@ -14,6 +14,11 @@ open Static
open Types open Types
open Clocks open Clocks
type var_name = name
type ck =
| Cbase
| Con of ck * constructor_name * var_name
type exp = { type exp = {
e_desc: edesc; e_desc: edesc;
@ -23,18 +28,18 @@ and app = { a_op: Minils.op; a_params: exp list }
and edesc = and edesc =
| Econst of static_exp | Econst of static_exp
| Evar of name | Evar of var_name
| Efby of exp option * exp | Efby of exp option * exp
| Eapp of Minils.app * exp list * name option | Eapp of app * exp list * var_name option
| Ewhen of exp * constructor_name * name | Ewhen of exp * constructor_name * var_name
| Emerge of name * (constructor_name * exp) list | Emerge of var_name * (constructor_name * exp) list
| Estruct of (field_name * exp) list | Estruct of (field_name * exp) list
| Eiterator of | Eiterator of
Minils.iterator_type * app * exp * exp list * name option Minils.iterator_type * app * exp * exp list * var_name option
and pat = and pat =
| Etuplepat of pat list | Etuplepat of pat list
| Evarpat of name | Evarpat of var_name
and eq = { and eq = {
eq_lhs : pat; eq_lhs : pat;
@ -42,61 +47,62 @@ and eq = {
eq_loc : location } eq_loc : location }
and var_dec = { and var_dec = {
v_ident : name; v_name : var_name;
v_type : ty; v_type : ty;
v_clock : ck; v_clock : ck;
v_loc : location } v_loc : location }
type node_dec = { type node_dec = {
n_name : name; n_name : qualname;
n_input : var_dec list; n_input : var_dec list;
n_output : var_dec list; n_output : var_dec list;
n_contract : Minils.contract option; n_contract : Minils.contract option;
n_local : var_dec list; n_local : var_dec list;
n_equs : eq list; n_equs : eq list;
n_loc : location; n_loc : location;
n_params : param list } n_params : param list }
type program = { type program = {
p_modname : name; p_modname : name;
p_format_version : string; p_format_version : string;
p_opened : name list; p_opened : name list;
p_types : Minils.type_dec list; p_types : Minils.type_dec list;
p_nodes : node_dec list; p_nodes : node_dec list;
p_consts : Minils.const_dec list } p_consts : Minils.const_dec list }
(** {Helper functions to build the Parsetree *) (** {Helper functions to build the Parsetree *)
let mk_node let mk_node params input output locals eqs ?(loc = no_location)
?(input = []) ?(output = []) ?(contract = None) ?(local = []) ?(eq = []) ?(contract = None) ?(constraints = []) name =
?(loc = no_location) ?(param = []) ?(constraints = []) ?(pinst = []) name =
{ n_name = name; { n_name = name;
n_input = input; n_input = input;
n_output = output; n_output = output;
n_contract = contract; n_contract = contract;
n_local = local; n_local = locals;
n_equs = eq; n_equs = eqs;
n_loc = loc; n_loc = loc;
n_params = param } n_params = params }
(** The modname field has to be set when known, TODO LG : format_version *)
let mk_program o n t c = let mk_program o n t c =
{ p_modname = ""; p_format_version = ""; { p_modname = Modules.current.Modules.modname;
p_opened = o; p_nodes = n; p_types = t; p_consts = c } p_format_version = "";
p_opened = o;
p_nodes = n;
p_types = t;
p_consts = c }
let mk_exp desc loc = { e_desc = desc; e_loc = loc } let mk_exp desc loc = { e_desc = desc; e_loc = loc }
let mk_app params op = { a_op = op; a_params = params } let mk_app params op = { a_op = op; a_params = params }
let void = mk_exp (Eapp (Minils.mk_app Minils.Etuple, [], None)) let void = mk_exp (Eapp (mk_app [] Minils.Etuple, [], None))
let mk_call ?(unsafe=false) ?(params=[]) reset op exps = let mk_call params op exps reset =
Eapp (Minils.mk_app ~unsafe:unsafe op ~params:params, exps, reset) Eapp (mk_app params op, exps, reset)
let mk_op_call ?(params=[]) s exps = let mk_op_call ?(params=[]) s exps =
mk_call ~params:params None mk_call params (Minils.Efun { qual = "Pervasives"; name = s }) exps None
(Minils.Efun (Modname { qual = "Pervasives"; id = s })) exps
let mk_iterator_call it ln params reset n exps = let mk_iterator_call it ln params reset n exps =
Eiterator (it, mk_app params (Minils.Enode ln), n, exps, reset) Eiterator (it, mk_app params (Minils.Enode ln), n, exps, reset)
@ -108,6 +114,6 @@ let mk_equation lhs rhs loc =
{ eq_lhs = lhs; eq_rhs = rhs; eq_loc = loc } { eq_lhs = lhs; eq_rhs = rhs; eq_loc = loc }
let mk_var_dec name ty clock loc = let mk_var_dec name ty clock loc =
{ v_ident = name; v_type = ty; v_clock = clock; v_loc = loc } { v_name = name; v_type = ty; v_clock = clock; v_loc = loc }

@ -12,7 +12,7 @@ open Minils
module Error = module Error =
struct struct
type error = type error =
| Enode_unbound of longname | Enode_unbound of qualname
| Epartial_instanciation of static_exp | Epartial_instanciation of static_exp
let message loc kind = let message loc kind =
@ -34,8 +34,8 @@ sig
type key = private static_exp (** Fully instantiated param *) type key = private static_exp (** Fully instantiated param *)
type env = key NamesEnv.t type env = key NamesEnv.t
val instantiate: env -> static_exp list -> key list val instantiate: env -> static_exp list -> key list
val get_node_instances : LongNameEnv.key -> key list list val get_node_instances : QualEnv.key -> key list list
val add_node_instance : LongNameEnv.key -> key list -> unit val add_node_instance : QualEnv.key -> key list -> unit
val build : env -> param list -> key list -> env val build : env -> param list -> key list -> env
module Instantiate : module Instantiate :
sig sig
@ -63,7 +63,7 @@ struct
module M = (** Map instance to its instantiated node *) module M = (** Map instance to its instantiated node *)
Map.Make( Map.Make(
struct struct
type t = longname * instance type t = qualname * instance
let compare (l1,i1) (l2,i2) = let compare (l1,i1) (l2,i2) =
let cl = compare l1 l2 in let cl = compare l1 l2 in
if cl = 0 then compare_instances i1 i2 else cl if cl = 0 then compare_instances i1 i2 else cl
@ -73,7 +73,7 @@ struct
let nodes_names = ref M.empty let nodes_names = ref M.empty
(** Maps a node to its list of instances *) (** Maps a node to its list of instances *)
let nodes_instances = ref LongNameEnv.empty let nodes_instances = ref QualEnv.empty
(** create a params instance *) (** create a params instance *)
let instantiate m se = let instantiate m se =
@ -91,32 +91,30 @@ struct
[ln] with the static parameters [params] and stores it. *) [ln] with the static parameters [params] and stores it. *)
let generate_new_name ln params = match params with let generate_new_name ln params = match params with
| [] -> nodes_names := M.add (ln, params) ln !nodes_names | [] -> nodes_names := M.add (ln, params) ln !nodes_names
| _ -> (match ln with | _ -> let { qual = q; name = n } = ln in
| Modname { qual = q; id = id } -> let new_ln = { qual = q;
let new_ln = Modname { qual = q;
(* TODO ??? c'est quoi ce nom ??? *) (* TODO ??? c'est quoi ce nom ??? *)
(* l'utilite de fresh n'est vrai que si toute les fonctions (* l'utilite de fresh n'est vrai que si toute les fonctions
sont touchees.. ce qui n'est pas vrai cf main_nodes *) sont touchees.. ce qui n'est pas vrai cf main_nodes *)
(* TODO mettre les valeurs des params dans le nom *) (* TODO mettre les valeurs des params dans le nom *)
id = id^(Idents.name (Idents.fresh "")) } in name = n^(Idents.name (Idents.fresh "")) } in
nodes_names := M.add (ln, params) new_ln !nodes_names nodes_names := M.add (ln, params) new_ln !nodes_names
| _ -> assert false)
(** Adds an instance of a node. *) (** Adds an instance of a node. *)
let add_node_instance ln params = let add_node_instance ln params =
(* get the already defined instances *) (* get the already defined instances *)
let instances = try LongNameEnv.find ln !nodes_instances let instances = try QualEnv.find ln !nodes_instances
with Not_found -> S.empty in with Not_found -> S.empty in
if S.mem params instances then () (* nothing to do *) if S.mem params instances then () (* nothing to do *)
else ( (* it's a new instance *) else ( (* it's a new instance *)
let instances = S.add params instances in let instances = S.add params instances in
nodes_instances := LongNameEnv.add ln instances !nodes_instances; nodes_instances := QualEnv.add ln instances !nodes_instances;
generate_new_name ln params ) generate_new_name ln params )
(** @return the list of instances of a node. *) (** @return the list of instances of a node. *)
let get_node_instances ln = let get_node_instances ln =
let instances_set = let instances_set =
try LongNameEnv.find ln !nodes_instances try QualEnv.find ln !nodes_instances
with Not_found -> S.empty in with Not_found -> S.empty in
S.elements instances_set S.elements instances_set
@ -135,13 +133,14 @@ struct
let static_exp funs m se = let static_exp funs m se =
let se, _ = Global_mapfold.static_exp funs m se in let se, _ = Global_mapfold.static_exp funs m se in
let se = match se.se_desc with let se = match se.se_desc with
| Svar ln -> | Svar { qual = q; name = n } ->
(match ln with if q = local_qualname
| Name n -> then (* This var is a static parameter, it has to be instanciated *)
(try NamesEnv.find n m (try NamesEnv.find n m
with Not_found -> (* It should then be in the global env *) with Not_found ->
se) Format.eprintf "local param not local";
| Modname _ -> se) assert false;)
else se
| _ -> se in | _ -> se in
se, m se, m
@ -176,19 +175,17 @@ struct
let n, _ = Mls_mapfold.node_dec_it funs m n in let n, _ = Mls_mapfold.node_dec_it funs m n in
(* Add to the global environment the signature of the new instance *) (* Add to the global environment the signature of the new instance *)
let ln = Modname { qual = modname; id = n.n_name } in let { info = node_sig } = find_value n.n_name in
let { info = node_sig } = find_value ln in
let node_sig, _ = Global_mapfold.node_it global_funs m node_sig in let node_sig, _ = Global_mapfold.node_it global_funs m node_sig in
let node_sig = { node_sig with node_params = []; let node_sig = { node_sig with node_params = [];
node_params_constraints = [] } in node_params_constraints = [] } in
(* Find the name that was associated to this instance *) (* Find the name that was associated to this instance *)
let ln = node_for_params_call ln params in let ln = node_for_params_call n.n_name params in
Modules.add_value_by_longname ln node_sig; Modules.add_value_by_longname ln node_sig;
{ n with n_name = shortname ln; n_params = []; n_params_constraints = [];} { n with n_name = ln; n_params = []; n_params_constraints = []; }
let node_dec modname n = let node_dec modname n =
let ln = Modname { qual = modname; id = n.n_name } in List.map (node_dec_instance modname n) (get_node_instances n.n_name)
List.map (node_dec_instance modname n) (get_node_instances ln)
let program p = let program p =
{ p { p
@ -201,13 +198,13 @@ open Param_instances
type info = type info =
{ mutable opened : program NamesEnv.t; { mutable opened : program NamesEnv.t;
mutable called_nodes : ((longname * static_exp list) list) LongNameEnv.t; } mutable called_nodes : ((qualname * static_exp list) list) QualEnv.t; }
let info = let info =
{ (** opened programs*) { (** opened programs*)
opened = NamesEnv.empty; opened = NamesEnv.empty;
(** Maps a node to the list of (node name, params) it calls *) (** Maps a node to the list of (node name, params) it calls *)
called_nodes = LongNameEnv.empty } called_nodes = QualEnv.empty }
(** Loads the modname.epo file. *) (** Loads the modname.epo file. *)
let load_object_file modname = let load_object_file modname =
@ -240,17 +237,14 @@ let load_object_file modname =
(** @return the node with name [ln], loading the corresponding (** @return the node with name [ln], loading the corresponding
object file if necessary. *) object file if necessary. *)
let node_by_longname ln = let node_by_longname ({ qual = q; name = n } as node) =
match ln with if not (NamesEnv.mem q info.opened)
| Modname { qual = q; id = id } -> then load_object_file q;
if not (NamesEnv.mem q info.opened) then try
load_object_file q; let p = NamesEnv.find q info.opened in
(try List.find (fun n -> n.n_name = node) p.p_nodes
let p = NamesEnv.find q info.opened in with
List.find (fun n -> n.n_name = id) p.p_nodes Not_found -> Error.message no_location (Error.Enode_unbound node)
with
Not_found -> Error.message no_location (Error.Enode_unbound ln))
| _ -> assert false
(** @return the list of nodes called by the node named [ln], with the (** @return the list of nodes called by the node named [ln], with the
corresponding params (static parameters appear as free variables). *) corresponding params (static parameters appear as free variables). *)
@ -260,7 +254,7 @@ let collect_node_calls ln =
| [] -> acc | [] -> acc
| _ -> | _ ->
(match ln with (match ln with
| Modname { qual = "Pervasives" } -> acc | { qual = "Pervasives" } -> acc
| _ -> (ln, params)::acc) | _ -> (ln, params)::acc)
in in
let edesc funs acc ed = match ed with let edesc funs acc ed = match ed with
@ -279,24 +273,12 @@ let collect_node_calls ln =
(** @return the list of nodes called by the node named [ln]. This list is (** @return the list of nodes called by the node named [ln]. This list is
computed lazily the first time it is needed. *) computed lazily the first time it is needed. *)
let called_nodes ln = let called_nodes ln =
if not (LongNameEnv.mem ln info.called_nodes) then ( if not (QualEnv.mem ln info.called_nodes) then (
let called = collect_node_calls ln in let called = collect_node_calls ln in
info.called_nodes <- LongNameEnv.add ln called info.called_nodes; info.called_nodes <- QualEnv.add ln called info.called_nodes;
called called
) else ) else
LongNameEnv.find ln info.called_nodes QualEnv.find ln info.called_nodes
(*
(** Checks that a static expression does not contain any static parameter. *)
let check_no_static_var se =
let static_exp_desc funs acc sed = match sed with
| Svar (Name n) -> Error.message se.se_loc (Error.Evar_unbound n)
| _ -> raise Misc.Fallback
in
let funs = { Global_mapfold.defaults with
static_exp_desc = static_exp_desc } in
ignore (Global_mapfold.static_exp_it funs false se)
*)
(** Generates the list of instances of nodes needed to call (** Generates the list of instances of nodes needed to call
[ln] with static parameters [params]. *) [ln] with static parameters [params]. *)
@ -316,7 +298,7 @@ let rec call_node (ln, params) =
let program p = let program p =
(* Find the nodes without static parameters *) (* Find the nodes without static parameters *)
let main_nodes = List.filter (fun n -> is_empty n.n_params) p.p_nodes in let main_nodes = List.filter (fun n -> is_empty n.n_params) p.p_nodes in
let main_nodes = List.map (fun n -> (longname n.n_name, [])) main_nodes in let main_nodes = List.map (fun n -> n.n_name, []) main_nodes in
info.opened <- NamesEnv.add p.p_modname p NamesEnv.empty; info.opened <- NamesEnv.add p.p_modname p NamesEnv.empty;
(* Creates the list of instances starting from these nodes *) (* Creates the list of instances starting from these nodes *)
List.iter call_node main_nodes; List.iter call_node main_nodes;

@ -22,7 +22,7 @@ let add_anon_node inputs outputs locals eqs =
let replace_anon_node n nd = let replace_anon_node n nd =
anon_nodes := LongNameEnv.add n nd !anon_nodes anon_nodes := LongNameEnv.add n nd !anon_nodes
let find_anon_node n = let find_anon_node n =
LongNameEnv.find n !anon_nodes LongNameEnv.find n !anon_nodes
let is_anon_node n = let is_anon_node n =
@ -51,9 +51,9 @@ let vd_of_arg ad =
an app object. *) an app object. *)
let get_node_inp_outp app = match app.a_op with let get_node_inp_outp app = match app.a_op with
| (Enode f | Efun f) when is_anon_node f -> | (Enode f | Efun f) when is_anon_node f ->
(* first check if it is an anonymous node *) (* first check if it is an anonymous node *)
let nd = find_anon_node f in let nd = find_anon_node f in
nd.n_input, nd.n_output nd.n_input, nd.n_output
| Enode f | Efun f -> | Enode f | Efun f ->
(* it is a regular node*) (* it is a regular node*)
let { info = ty_desc } = find_value f in let { info = ty_desc } = find_value f in
@ -113,7 +113,7 @@ let edesc funs acc ed =
let _, outp = get_node_inp_outp f in let _, outp = get_node_inp_outp f in
let eq = mk_equation (pat_of_vd_list outp) call in let eq = mk_equation (pat_of_vd_list outp) call in
(* create the lambda *) (* create the lambda *)
let anon = mk_app (Enode (add_anon_node inp outp [] (eq::acc_eq_list))) in let anon = mk_app (Enode (add_anon_node inp outp [] (eq::acc_eq_list))) in
Eiterator(Imap, anon, n, args, r), acc Eiterator(Imap, anon, n, args, r), acc
) else ) else
ed, acc ed, acc

@ -7,6 +7,7 @@
(* *) (* *)
(**************************************************************************) (**************************************************************************)
open Misc open Misc
open Initial
open Names open Names
open Idents open Idents
open Signature open Signature
@ -15,8 +16,6 @@ open Mls_utils
open Types open Types
open Clocks open Clocks
let ctrue = Name "true"
and cfalse = Name "false"
let equation (d_list, eq_list) e = let equation (d_list, eq_list) e =
let add_one_var ty d_list = let add_one_var ty d_list =
@ -112,9 +111,9 @@ let rec merge e x ci_a_list =
let ifthenelse context e1 e2 e3 = let ifthenelse context e1 e2 e3 =
let context, n = intro context e1 in let context, n = intro context e1 in
let n = (match n with Evar n -> n | _ -> assert false) in let n = (match n with Evar n -> n | _ -> assert false) in
let context, e2 = whenc context e2 ctrue n in let context, e2 = whenc context e2 ptrue n in
let context, e3 = whenc context e3 cfalse n in let context, e3 = whenc context e3 pfalse n in
context, merge e1 n [ctrue, e2; cfalse, e3] context, merge e1 n [ptrue, e2; pfalse, e3]
let const e c = let const e c =
let rec const = function let rec const = function
@ -194,10 +193,10 @@ let rec translate kind context e =
(* normalize anonymous nodes *) (* normalize anonymous nodes *)
(match app.a_op with (match app.a_op with
| Enode f when Itfusion.is_anon_node f -> | Enode f when Itfusion.is_anon_node f ->
let nd = Itfusion.find_anon_node f in let nd = Itfusion.find_anon_node f in
let d_list, eq_list = translate_eq_list nd.n_local nd.n_equs in let d_list, eq_list = translate_eq_list nd.n_local nd.n_equs in
let nd = { nd with n_equs = eq_list; n_local = d_list } in let nd = { nd with n_equs = eq_list; n_local = d_list } in
Itfusion.replace_anon_node f nd Itfusion.replace_anon_node f nd
| _ -> () ); | _ -> () );
(* Add an intermediate equation for each array lit argument. *) (* Add an intermediate equation for each array lit argument. *)

@ -77,7 +77,6 @@ let eqs funs () eq_list =
let eqs, () = Mls_mapfold.eqs funs () eq_list in let eqs, () = Mls_mapfold.eqs funs () eq_list in
schedule eqs, () schedule eqs, ()
let edesc funs () = function
| Eiterator(it, ({ a_op = Enode f } as app), | Eiterator(it, ({ a_op = Enode f } as app),
n, e_list, r) when Itfusion.is_anon_node f -> n, e_list, r) when Itfusion.is_anon_node f ->
let nd = Itfusion.find_anon_node f in let nd = Itfusion.find_anon_node f in

@ -59,27 +59,20 @@ let int_of_static_exp se =
Static.int_of_static_exp NamesEnv.empty se Static.int_of_static_exp NamesEnv.empty se
(** Returns the information concerning a node given by name. *) (** Returns the information concerning a node given by name. *)
let node_info classln = let node_info {qual = modname; name = modname_name } =
match classln with try
| Modname {qual = modname; id = modname_name } -> modname, find_value {qual = modname; name = modname_name }
begin try with Not_found ->
modname, find_value (Modname({qual = modname; (* name might be of the form Module.name, remove the module name*)
id = modname_name })) (*let ind_name = (String.length modname) + 1 in
with Not_found -> let name = String.sub modname_name ind_name
(* name might be of the form Module.name, remove the module name*) ((String.length modname_name)-ind_name) in
(*let ind_name = (String.length modname) + 1 in begin try
let name = String.sub modname_name ind_name modname, find_value (Modname({qual = modname;
((String.length modname_name)-ind_name) in id = name }))
begin try with Not_found ->*)
modname, find_value (Modname({qual = modname; Error.message no_location (Error.Enode modname)
id = name })) (*end *)
with Not_found ->*)
Error.message no_location (Error.Enode modname)
(*end *)
end
| Name n ->
assert false;
Error.message no_location (Error.Enode n)
let output_names_list sig_info = let output_names_list sig_info =
let remove_option ad = match ad.a_name with let remove_option ad = match ad.a_name with
@ -176,7 +169,7 @@ let rec assoc_type n var_env =
let rec unalias_ctype = function let rec unalias_ctype = function
| Cty_id ty_name -> | Cty_id ty_name ->
(try (try
let { qualid = q; info = ty_desc } = find_type (longname ty_name) in let { qualname = q; info = ty_desc } = find_type (qualname ty_name) in
match ty_desc with match ty_desc with
| Talias ty -> unalias_ctype (ctype_of_otype ty) | Talias ty -> unalias_ctype (ctype_of_otype ty)
| _ -> Cty_id ty_name | _ -> Cty_id ty_name
@ -202,8 +195,8 @@ let rec assoc_type_lhs lhs var_env =
| Cfield(x, f) -> | Cfield(x, f) ->
let ty = assoc_type_lhs x var_env in let ty = assoc_type_lhs x var_env in
let n = struct_name ty in let n = struct_name ty in
let { info = fields } = find_struct (longname n) in let { info = fields } = find_struct (qualname n) in
ctype_of_otype (field_assoc (Name f) fields) ctype_of_otype (field_assoc (qualname f) fields)
(** Creates the statement a = [e_1, e_2, ..], which gives a list (** Creates the statement a = [e_1, e_2, ..], which gives a list
a[i] = e_i.*) a[i] = e_i.*)
@ -287,9 +280,8 @@ let rec cexpr_of_exp var_env exp =
and cexprs_of_exps var_env exps = and cexprs_of_exps var_env exps =
List.map (cexpr_of_exp var_env) exps List.map (cexpr_of_exp var_env) exps
and cop_of_op_aux var_env op_name cexps = and cop_of_op_aux var_env op_name cexps = match op_name with
match op_name with | { qual = "Pervasives"; name = op } ->
| Modname { qual = "Pervasives"; id = op } ->
begin match op,cexps with begin match op,cexps with
| "~-", [e] -> Cuop ("-", e) | "~-", [e] -> Cuop ("-", e)
| "not", [e] -> Cuop ("!", e) | "not", [e] -> Cuop ("!", e)
@ -302,9 +294,7 @@ and cop_of_op_aux var_env op_name cexps =
Cbop (copname op, el, er) Cbop (copname op, el, er)
| _ -> Cfun_call(op, cexps) | _ -> Cfun_call(op, cexps)
end end
| Modname {qual = m; id = op} -> | {qual = m; name = op} ->
Cfun_call(op,cexps)
| Name(op) ->
Cfun_call(op,cexps) Cfun_call(op,cexps)
and cop_of_op var_env op_name exps = and cop_of_op var_env op_name exps =
@ -350,7 +340,7 @@ let assoc_cn instance obj_env =
(assoc_obj (obj_call_name instance) obj_env).o_class (assoc_obj (obj_call_name instance) obj_env).o_class
let is_op = function let is_op = function
| Modname { qual = "Pervasives"; id = _ } -> true | { qual = "Pervasives"; name = _ } -> true
| _ -> false | _ -> false
let out_var_name_of_objn o = let out_var_name_of_objn o =
@ -431,8 +421,8 @@ let rec create_affect_const var_env dest c =
let rec cstm_of_act var_env obj_env act = let rec cstm_of_act var_env obj_env act =
match act with match act with
(** Case on boolean values are converted to if instead of switch! *) (** Case on boolean values are converted to if instead of switch! *)
| Acase (c, [(Name "true", te); (Name "false", fe)]) | Acase (c, [({name = "true"}, te); ({ name = "false" }, fe)])
| Acase (c, [(Name "false", fe); (Name "true", te)]) -> | Acase (c, [({name = "false"}, fe); ({ name = "true"}, te)]) ->
let cc = cexpr_of_exp var_env c in let cc = cexpr_of_exp var_env c in
let cte = cstm_of_act_list var_env obj_env te in let cte = cstm_of_act_list var_env obj_env te in
let cfe = cstm_of_act_list var_env obj_env fe in let cfe = cstm_of_act_list var_env obj_env fe in
@ -511,7 +501,7 @@ let global_name = ref "";;
(** {2 step() and reset() functions generation *) (** {2 step() and reset() functions generation *)
let mk_current_longname n = let mk_current_longname n =
Modname { qual = !global_name; id = n } { qual = !global_name; name = n }
(** Builds the argument list of step function*) (** Builds the argument list of step function*)
let step_fun_args n md = let step_fun_args n md =
@ -654,7 +644,7 @@ let decls_of_type_decl otd =
Cty_ptr Cty_char, Cty_ptr Cty_char,
[("x", Cty_id name); ("buf", Cty_ptr Cty_char)])] [("x", Cty_id name); ("buf", Cty_ptr Cty_char)])]
| Type_struct fl -> | Type_struct fl ->
let decls = List.map (fun f -> f.Signature.f_name, let decls = List.map (fun f -> shortname f.Signature.f_name,
ctype_of_otype f.Signature.f_type) fl in ctype_of_otype f.Signature.f_type) fl in
[Cdecl_struct (otd.t_name, decls)];; [Cdecl_struct (otd.t_name, decls)];;
@ -698,7 +688,7 @@ let cdefs_and_cdecls_of_type_decl otd =
[Cdecl_enum (otd.t_name, nl); cdecl_of_cfundef of_string_fun; [Cdecl_enum (otd.t_name, nl); cdecl_of_cfundef of_string_fun;
cdecl_of_cfundef to_string_fun]) cdecl_of_cfundef to_string_fun])
| Type_struct fl -> | Type_struct fl ->
let decls = List.map (fun f -> f.Signature.f_name, let decls = List.map (fun f -> shortname f.Signature.f_name,
ctype_of_otype f.Signature.f_type) fl in ctype_of_otype f.Signature.f_type) fl in
let decl = Cdecl_struct (otd.t_name, decls) in let decl = Cdecl_struct (otd.t_name, decls) in
([], [decl]) ([], [decl])

@ -87,7 +87,7 @@ let main_def_of_class_def cd =
| Types.Tid id when id = Initial.pfloat -> "%f" | Types.Tid id when id = Initial.pfloat -> "%f"
| Types.Tid id when id = Initial.pint -> "%d" | Types.Tid id when id = Initial.pint -> "%d"
| Types.Tid id when id = Initial.pbool -> "%d" | Types.Tid id when id = Initial.pbool -> "%d"
| Tid ((Name sid) | Modname { id = sid }) -> "%s" in | Tid _ -> "%s" in
(** Does reading type [ty] need a buffer? When it is the case, (** Does reading type [ty] need a buffer? When it is the case,
[need_buf_for_ty] also returns the type's name. *) [need_buf_for_ty] also returns the type's name. *)
@ -96,7 +96,7 @@ let main_def_of_class_def cd =
| Types.Tid id when id = Initial.pfloat -> None | Types.Tid id when id = Initial.pfloat -> None
| Types.Tid id when id = Initial.pint -> None | Types.Tid id when id = Initial.pint -> None
| Types.Tid id when id = Initial.pbool -> None | Types.Tid id when id = Initial.pbool -> None
| Tid (Name sid | Modname { id = sid; }) -> Some sid in | Tid { name = n } -> Some n in
let cprint_string s = Csexpr (Cfun_call ("printf", [Cconst (Cstrlit s)])) in let cprint_string s = Csexpr (Cfun_call ("printf", [Cconst (Cstrlit s)])) in

@ -16,9 +16,9 @@ open Signature
open Location open Location
type class_name = name type class_name = name
type instance_name = longname type instance_name = qualname
type obj_name = name type obj_name = name
type op_name = longname type op_name = qualname
type type_dec = type type_dec =
{ t_name : name; { t_name : name;

@ -14,7 +14,7 @@ let print_vd ff vd =
let print_obj ff o = let print_obj ff o =
fprintf ff "@[<v>"; print_name ff o.o_name; fprintf ff "@[<v>"; print_name ff o.o_name;
fprintf ff " : "; print_longname ff o.o_class; fprintf ff " : "; print_qualname ff o.o_class;
fprintf ff "@[<2>%a@]" (print_list_r print_static_exp "<<"","">>") o.o_params; fprintf ff "@[<2>%a@]" (print_list_r print_static_exp "<<"","">>") o.o_params;
(match o.o_size with (match o.o_size with
| Some se -> fprintf ff "[%a]" print_static_exp se | Some se -> fprintf ff "[%a]" print_static_exp se
@ -42,7 +42,7 @@ and print_exp ff e =
| Estruct(_,f_e_list) -> | Estruct(_,f_e_list) ->
fprintf ff "@[<v 1>"; fprintf ff "@[<v 1>";
print_list_r print_list_r
(fun ff (field, e) -> print_longname ff field;fprintf ff " = "; (fun ff (field, e) -> print_qualname ff field;fprintf ff " = ";
print_exp ff e) print_exp ff e)
"{" ";" "}" ff f_e_list; "{" ";" "}" ff f_e_list;
fprintf ff "@]" fprintf ff "@]"
@ -53,9 +53,9 @@ and print_exp ff e =
and print_op ff op e_list = match e_list with and print_op ff op e_list = match e_list with
| [l; r] -> | [l; r] ->
fprintf ff "(@[%a@ %a %a@])" print_longname op print_exp l print_exp r fprintf ff "(@[%a@ %a %a@])" print_qualname op print_exp l print_exp r
| _ -> | _ ->
print_longname ff op; print_qualname ff op;
print_list_l print_exp "(" "," ")" ff e_list print_list_l print_exp "(" "," ")" ff e_list
let print_asgn ff pref x e = let print_asgn ff pref x e =
@ -117,7 +117,7 @@ and print_tag_act_list ff tag_act_list =
print_list print_list
(fun ff (tag, a) -> (fun ff (tag, a) ->
fprintf ff "@[<v 2>case %a:@ %a@]" fprintf ff "@[<v 2>case %a:@ %a@]"
print_longname tag print_qualname tag
print_block a) print_block a)
"" "" "" ff tag_act_list "" "" "" ff tag_act_list
@ -167,7 +167,7 @@ let print_type_def ff { t_name = name; t_desc = tdesc } =
fprintf ff "@[<v 1>"; fprintf ff "@[<v 1>";
print_list print_list
(fun ff { Signature.f_name = field; Signature.f_type = ty } -> (fun ff { Signature.f_name = field; Signature.f_type = ty } ->
print_name ff field; print_qualname ff field;
fprintf ff ": "; fprintf ff ": ";
print_type ff ty) "{" ";" "}" ff f_ty_list; print_type ff ty) "{" ";" "}" ff f_ty_list;
fprintf ff "@]@.@]" fprintf ff "@]@.@]"

@ -16,9 +16,8 @@ open Global_mapfold
module Deps = module Deps =
struct struct
let deps_longname deps ln = match ln with
| Modname { qual = modn; } -> S.add modn deps let deps_longname deps { qual = modn; } = S.add modn deps
| _ -> deps
let deps_static_exp_desc funs deps sedesc = let deps_static_exp_desc funs deps sedesc =
let (sedesc, deps) = Global_mapfold.static_exp_desc funs deps sedesc in let (sedesc, deps) = Global_mapfold.static_exp_desc funs deps sedesc in

@ -21,28 +21,29 @@ let syntax_error loc =
let language_error lang = let language_error lang =
Format.eprintf "Unknown language: '%s'.@." lang Format.eprintf "Unknown language: '%s'.@." lang
let comment s = let separateur = "\n*********************************************\
if !verbose then Format.printf "** %s done **@." s *********************************\n*** "
let comment ?(sep=separateur) s =
if !verbose then Format.printf "%s%s@." sep s
let do_pass f d p pp enabled = let do_pass d f p pp =
comment (d^" ...\n");
let r = f p in
pp r;
comment ~sep:"*** " (d^" done.");
r
let do_silent_pass d f p = do_pass d f p (fun x -> ())
let pass d enabled f p pp =
if enabled if enabled
then then do_pass d f p pp
let r = f p in
if !verbose
then begin
comment d;
pp r;
end;
r
else p else p
let do_silent_pass f d p enabled = let silent_pass d enabled f p =
if enabled if enabled
then begin then do_silent_pass d f p
let r = f p in
if !verbose then comment d; r
end
else p else p
let build_path suf = let build_path suf =

@ -83,7 +83,7 @@ let tomato = ref false
let inline = ref [] let inline = ref []
let add_inlined_node s = inline := Names.mk_longname s :: !inline let add_inlined_node s = inline := s :: !inline
let flatten = ref false let flatten = ref false
@ -216,7 +216,7 @@ let rec assocd value = function
assocd value l assocd value l
(** Compiler iterators *) (** { 3 Compiler iterators } *)
exception Fallback exception Fallback
(** Mapfold *) (** Mapfold *)
@ -258,3 +258,18 @@ let mapi3 f l1 l2 l3 =
(f i v1 v2 v3)::(aux (i+1) l1 l2 l3) (f i v1 v2 v3)::(aux (i+1) l1 l2 l3)
in in
aux 0 l1 l2 l3 aux 0 l1 l2 l3
exception Cannot_find_file of string
let findfile filename =
if Sys.file_exists filename then
filename
else if not(Filename.is_implicit filename) then
raise(Cannot_find_file filename)
else
let rec find = function
| [] -> raise(Cannot_find_file filename)
| a::rest ->
let b = Filename.concat a filename in
if Sys.file_exists b then b else find rest in
find !load_path

@ -84,7 +84,7 @@ val cse : bool ref
val tomato : bool ref val tomato : bool ref
(* List of nodes to inline *) (* List of nodes to inline *)
val inline : Names.longname list ref val inline : string list ref
(* Add a new node name to the list of nodes to inline. *) (* Add a new node name to the list of nodes to inline. *)
val add_inlined_node : string -> unit val add_inlined_node : string -> unit
(* Inline every node. *) (* Inline every node. *)
@ -187,3 +187,6 @@ val mapi: (int -> 'a -> 'b) -> 'a list -> 'b list
val mapi2: (int -> 'a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list val mapi2: (int -> 'a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
val mapi3: (int -> 'a -> 'b -> 'c -> 'd) -> val mapi3: (int -> 'a -> 'b -> 'c -> 'd) ->
'a list -> 'b list -> 'c list -> 'd list 'a list -> 'b list -> 'c list -> 'd list
exception Cannot_find_file of string
val findfile : string -> string

@ -56,12 +56,12 @@ let print_type_params ff pl =
print_list_r (fun ff s -> fprintf ff "'%s" s) "("","") " ff pl print_list_r (fun ff s -> fprintf ff "'%s" s) "("","") " ff pl
let print_set print_element ff set = let print_set iter print_element ff set =
fprintf ff "@[{@ "; fprintf ff "@[{@ ";
iter (fun e -> fprintf ff "%a@ " print_element e) set; iter (fun e -> fprintf ff "%a@ " print_element e) set;
fprintf ff "}@]" fprintf ff "}@]"
let print_map print_key print_element ff map = let print_map iter print_key print_element ff map =
pfrintf ff "@[<hv 2>[@ "; fprintf ff "@[<hv 2>[@ ";
iter (fun k x -> fprintf ff "| %a -> %a@ " print_key k print_element x map; iter (fun k x -> fprintf ff "| %a -> %a@ " print_key k print_element x) map;
fprintf ff "]@]" fprintf ff "]@]"

@ -4,7 +4,7 @@
SCRIPT_DIR=`dirname $0` SCRIPT_DIR=`dirname $0`
COMPILER_DIR=compiler #relative to the script_dir COMPILER_DIR=compiler #relative to the script_dir
COMPILER=heptc.native COMPILER=heptc.d.byte
HEPTC=$COMPILER_DIR/$COMPILER HEPTC=$COMPILER_DIR/$COMPILER
RUN_DIR=`pwd` RUN_DIR=`pwd`

Loading…
Cancel
Save