Hept Scoping should be ok and documented,

Hept Parsing too,
all the reset to review carefully,
Typing to cut from all the scoping.
This commit is contained in:
Léonard Gérard 2010-09-09 00:35:06 +02:00 committed by Léonard Gérard
parent 15448fdff9
commit a54e570d0f
45 changed files with 1199 additions and 1006 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 modules = type env = {
{ current: env; (* associated symbol table *) (** Current module name *)
mutable opened: env list; (* opened tables *) mutable current_mod : module_name;
mutable modules: env NamesEnv.t; (* tables loaded in memory *) (** Modules opened and loaded into the env *)
} mutable opened_mod : module_name list;
(** Modules loaded into the env *)
mutable loaded_mod : module_name list;
(** Node definitions *)
mutable values : node QualEnv.t;
(** Type definitions *)
mutable types : type_def QualEnv.t;
(** Constants definitions *)
mutable consts : const_def QualEnv.t;
(** Constructors mapped to their corresponding type *)
mutable constrs : qualname QualEnv.t;
(** Fields mapped to their corresponding type *)
mutable fields : qualname QualEnv.t;
(** Accepted compiled interface version *)
format_version : string }
let current = (** The global environnement *)
{ name = ""; values = NamesEnv.empty; types = NamesEnv.empty; let g_env =
constr = NamesEnv.empty; structs = NamesEnv.empty; fields = NamesEnv.empty; { current_mod = "";
consts = NamesEnv.empty; format_version = interface_format_version } 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 modules =
{ current = current; opened = []; modules = NamesEnv.empty }
let findfile filename = let is_loaded m = List.mem m g_env.loaded_mod
if Sys.file_exists filename then let is_opened m = List.mem m g_env.opened_mod
filename
else if not(Filename.is_implicit filename) then
raise(Cannot_find_file filename) (** 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
[] ->
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
let load_module modname =
let name = String.uncapitalize modname in let name = String.uncapitalize modname in
let filename = Misc.findfile (name ^ ".epci") in
let ic =
try try
let filename = findfile (name ^ ".epci") in open_in_bin filename
let ic = open_in_bin filename in with
| Misc.Cannot_find_file(f) ->
Format.eprintf "Cannot find the compiled interface file %s.@." f;
raise Error in
let mo:module_object =
try try
let m:env = input_value ic in input_value ic
if m.format_version <> interface_format_version then (
Format.eprintf "The file %s was compiled with \
an older version of the compiler.@\n \
Please recompile %s.ept first.@." filename name;
raise Error
);
close_in ic;
m
with with
| End_of_file | Failure _ -> | End_of_file | Failure _ ->
close_in ic; close_in ic;
Format.eprintf "Corrupted compiled interface file %s.@\n\ Format.eprintf "Corrupted compiled interface file %s.@\n\
Please recompile %s.ept first.@." filename name; Please recompile %s.ept first.@." filename name;
raise Error raise Error in
with if mo.m_format_version <> interface_format_version
| Cannot_find_file(filename) -> then (
Format.eprintf "Cannot find the compiled interface file %s.@." Format.eprintf "The file %s was compiled with an older version \
filename; of the compiler.@\nPlease recompile %s.ept first.@."
raise Error filename name;
raise Error );
let find_module modname = _append_module mo
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 = (** Opens a module unless already opened
let rec findrec ident = function by loading it into the global environnement and seting it as opened *)
| [] -> 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;
current.values <- NamesEnv.add f signature current.values
let add_type f type_def =
if NamesEnv.mem f current.types then raise Already_defined;
current.types <- NamesEnv.add f type_def current.types
let add_constr f ty_res =
if NamesEnv.mem f current.constr then raise Already_defined;
current.constr <- NamesEnv.add f ty_res current.constr
let add_struct f fields =
if NamesEnv.mem f current.structs then raise Already_defined;
current.structs <- NamesEnv.add f fields current.structs
let add_field f n =
if NamesEnv.mem f current.fields then raise Already_defined;
current.fields <- NamesEnv.add f n current.fields
let add_const f n =
if NamesEnv.mem f current.consts then raise Already_defined;
current.consts <- NamesEnv.add f n current.consts
let add_value_by_longname ln signature = (** { 3 Add functions prevent redefinitions } *)
match ln with
| Modname { qual = modname; id = f } ->
let m =
if modname = current.name then
current
else
NamesEnv.find modname modules.modules in
if not (NamesEnv.mem f m.values) then
m.values <- NamesEnv.add f signature m.values
| Name _ -> raise Not_found
let find_value = find (fun ident m -> NamesEnv.find ident m.values) let _check_not_defined env f =
let find_type = find (fun ident m -> NamesEnv.find ident m.types) if QualEnv.mem f env then raise Already_defined
let find_constr = find (fun ident m -> NamesEnv.find ident m.constr)
let find_struct = find (fun ident m -> NamesEnv.find ident m.structs)
let find_field = find (fun ident m -> NamesEnv.find ident m.fields)
let find_const = find (fun ident m -> NamesEnv.find ident m.consts)
let replace_value f signature = let add_value f v =
current.values <- NamesEnv.remove f current.values; _check_not_defined g_env.values f;
current.values <- NamesEnv.add f signature current.values g_env.values <- QualEnv.add f v g_env.values
let add_type f v =
_check_not_defined g_env.types f;
g_env.types <- QualEnv.add f v g_env.types
let add_constrs f v =
_check_not_defined g_env.constrs f;
g_env.constrs <- QualEnv.add f v g_env.constrs
let add_field f v =
_check_not_defined g_env.fields f;
g_env.fields <- QualEnv.add f v g_env.fields
let add_const f v =
_check_not_defined g_env.consts f;
g_env.consts <- QualEnv.add f v g_env.consts
let write oc = output_value oc current
let longname n = Modname({ qual = current.name; id = n }) (** { 3 Find functions look in the global environnement, nothing more } *)
let currentname longname =
match longname with
| Name(n) -> longname
| Modname{ qual = q; id = id} ->
if current.name = q then Name(id) else longname
exception Undefined_type of longname let _check_loaded_module m =
(** @return the unaliased version of a type. *) if not (List.mem m g_env.loaded_mod)
let rec unalias_type = function then (
Format.eprintf "The module %s was not loaded." m;
raise Error )
let _find env x =
try QualEnv.find x env
with Not_found ->
_check_loaded_module x.qual; (* should never arrive, sanity check *)
raise Not_found
let find_value = _find g_env.values
let find_type = _find g_env.types
let find_constrs = _find g_env.constrs
let find_field = _find g_env.fields
let find_const = _find g_env.consts
(** { 3 Load_check functions }
Try to load the needed module and then to find it,
return true if in the table, return false if it can't find it. *)
let _check env q =
_load_module q.qual;
try let _ = QualEnv.find q env in true
with Not_found -> false
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
| _ -> Tid (Modname q) | _ -> t
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

View File

@ -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 type_name = longname type field_name = qualname
type constructor_name = qualname
type fun_name = longname type constant_name = qualname
type module_name = name
type field_name = longname
type constructor_name = longname
type constant_name = longname
module NamesM = struct let local_qualname = "$$%local_current_illegal_module_name%$$"
type t = name let local_qn name = { qual = local_qualname; name = name }
let compare = compare
module NamesEnv = struct
include (Map.Make(struct type t = name let compare = compare end))
let append env0 env = fold (fun key v env -> add key v env) env0 env
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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 ";

View File

@ -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
@ -86,9 +95,13 @@ and escape = {
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;
@ -98,12 +111,15 @@ and var_dec = {
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 = {
@ -112,7 +128,7 @@ type contract = {
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;
@ -123,7 +139,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 }
@ -136,15 +152,18 @@ type program = {
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;
sig_loc = loc }
(** Translates a Heptagon exp into a static size exp. *)
(*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 =

View File

@ -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;

View File

@ -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 ()

View File

@ -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:
@ -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 */
@ -572,7 +572,8 @@ _interface_decl:
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:

View File

@ -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 =
@ -152,7 +177,8 @@ type signature =
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

View File

@ -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 =
if Rename.mem x env then
Error.message loc (Error.Evariable_already_defined x)
else (* create a new id for this var and add it to the env *)
Rename.add x (ident_of_name x) env
let add_const_var loc x env = (** Function to build the defined static parameters set *)
if NamesEnv.mem x env then let build_const loc vd_list =
Error.message loc (Error.Econst_variable_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
NamesEnv.add x x env then Error.message loc (Error.Econst_variable_already_defined c)
else S.add c local_const in
let build local_const vd =
_add_const_var loc vd.v_name local_const in
List.fold_left build S.empty vd_list
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 = (** { 3 Translate the AST into Heptagon. } *)
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
| Evar n ->
if NamesEnv.mem n const_env then
Svar (Name n)
else
(try
let { qualid = q } = find_const (Name n) in
Svar (Modname q)
with Not_found -> raise Not_static)
| Econst se -> se.se_desc
| Eapp({ a_op = Earray_fill; a_params = [n] }, [e]) ->
Sarray_power (static_exp_of_exp const_env e,
static_exp_of_exp const_env n)
| Eapp({ a_op = Earray }, e_list) ->
Sarray (List.map (static_exp_of_exp const_env) e_list)
| Eapp({ a_op = Etuple }, e_list) ->
Stuple (List.map (static_exp_of_exp const_env) e_list)
| Eapp(app, e_list) ->
let op = op_from_app e.e_loc app in
Sop(op, List.map (static_exp_of_exp const_env) e_list)
| Estruct e_list ->
Srecord (List.map (fun (f,e) -> f,
static_exp_of_exp const_env e) e_list)
| _ -> raise Not_static
in
mk_static_exp ~loc:e.e_loc desc
let expect_static_exp const_env e =
try try
static_exp_of_exp const_env e let se_d = translate_static_exp_desc local_const se.se_desc in
Types.mk_static_exp ~loc:se.se_loc se_d
with with
Not_static -> Error.message e.e_loc Error.Estatic_exp_expected | ScopingError err -> message se.se_loc err
let rec translate_type const_env = function and translate_static_exp_desc local_const ed =
| Tprod ty_list -> Types.Tprod(List.map (translate_type const_env) ty_list) let t = translate_static_exp local_const in
| Tid ln -> Types.Tid ln match ed with
| Svar q -> Types.Svar (qualify_const local_const q)
| Sint i -> Types.Sint i
| Sfloat f -> Types.Sfloat f
| Sbool b -> Types.Sbool b
| Sconstructor c -> Types.Sconstructor (qualify_constrs c)
| Stuple se_list -> Types.Stuple (List.map t se_list)
| Sarray_power (se,sn) -> Types.Sarray_power (t se, t sn)
| Sarray se_list -> Types.Sarray (List.map t se_list)
| Srecord se_f_list ->
let qualf (f, se) = (qualify_field f, t se) in
Types.Srecord (List.map qualf se_f_list)
| Sop (fn, se_list) -> Types.Sop (qualify_value fn, List.map t se_list)
let rec static_exp_of_exp local_const e =
try
let t = static_exp_of_exp local_const in
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 rec translate_type loc local_const ty =
try
(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) -> | Tarray (ty, e) ->
let ty = translate_type const_env ty in let ty = translate_type loc local_const ty in
Types.Tarray (ty, expect_static_exp const_env e) Types.Tarray (ty, expect_static_exp local_const e))
with
| ScopingError err -> message loc err
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_last = translate_last local_const vd.v_last;
Heptagon.v_loc = vd.v_loc } 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
(translate_type vd.v_loc local_const vd.v_type))
let translate_node const_env env node = let translate_node node =
let const_env = build_id_list node.n_loc const_env node.n_params in (* Node's params go to local_const env *)
let env = build_vd_list env (node.n_input @ node.n_output) in let local_const = build_const node.n_loc node.n_params in
let b, env = translate_block const_env env node.n_block in (* Inputs and outputs define the initial local env *)
{ Heptagon.n_name = node.n_name; 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;
Heptagon.Type_abs
| Type_alias t ->
let t = translate_type ty.t_loc S.empty t in
add_type n (Signature.Talias t);
Heptagon.Type_alias t
| Type_enum(tag_list) ->
let tag_list = List.map current_qual tag_list in
List.iter (fun tag -> add_constrs tag n) tag_list;
add_type n (Signature.Tenum tag_list);
Heptagon.Type_enum tag_list
| Type_struct(field_ty_list) -> | Type_struct(field_ty_list) ->
let translate_field_type (f,ty) = let translate_field_type (f,t) =
Signature.mk_field f (translate_type const_env ty) in let f = current_qual f in
Heptagon.Type_struct (List.map translate_field_type field_ty_list) let t = translate_type ty.t_loc S.empty t in
in add_field f n;
{ Heptagon.t_name = ty.t_name; Signature.mk_field f t in
Heptagon.t_desc = onetype ty.t_desc; 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 } Heptagon.t_loc = ty.t_loc }
let translate_const_dec const_env cd =
{ Heptagon.c_name = cd.c_name; let translate_const_dec cd =
Heptagon.c_type = translate_type const_env cd.c_type; let c_name = current_qual cd.c_name in
Heptagon.c_value = expect_static_exp const_env cd.c_value; let c_type = translate_type cd.c_loc S.empty cd.c_type in
Heptagon.c_loc = cd.c_loc; }, build_cd const_env cd 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
add_value n (Signature.mk_node i o s.sig_statefull p);
Heptagon.mk_signature n i o s.sig_statefull p s.sig_loc
let translate_interface_desc const_env = function
| Iopen n -> Heptagon.Iopen n, const_env
| Itypedef tydec ->
Heptagon.Itypedef (translate_typedec const_env tydec), const_env
| Iconstdef const_dec ->
let const_dec, const_env = translate_const_dec const_env const_dec in
Heptagon.Iconstdef const_dec, const_env
| Isignature s -> Heptagon.Isignature (translate_signature s) , const_env
let translate_interface_decl const_env idecl = let translate_interface_desc = function
let desc, const_env = | Iopen n -> open_module n; Heptagon.Iopen n
translate_interface_desc const_env idecl.interf_desc in | Itypedef tydec -> Heptagon.Itypedef (translate_typedec tydec)
| Iconstdef const_dec -> Heptagon.Iconstdef (translate_const_dec const_dec)
| Isignature s -> Heptagon.Isignature (translate_signature s)
let translate_interface_decl idecl =
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

View File

@ -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,

View File

@ -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 }

View File

@ -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;;

View File

@ -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
@ -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 -> Type_enum tag_name_list | Minils.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 }

View File

@ -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

View File

@ -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

View File

@ -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 }

View File

@ -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 "@?"

View File

@ -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 =

View File

@ -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 }

View File

@ -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 */

View File

@ -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,13 +47,13 @@ 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;
@ -68,35 +73,36 @@ type program = {
(** {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 }

View File

@ -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;
(try
let p = NamesEnv.find q info.opened in let p = NamesEnv.find q info.opened in
List.find (fun n -> n.n_name = id) p.p_nodes List.find (fun n -> n.n_name = node) p.p_nodes
with with
Not_found -> Error.message no_location (Error.Enode_unbound ln)) Not_found -> Error.message no_location (Error.Enode_unbound node)
| _ -> 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;

View File

@ -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

View File

@ -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

View File

@ -59,12 +59,9 @@ 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
modname, find_value (Modname({qual = modname;
id = modname_name }))
with Not_found -> with Not_found ->
(* name might be of the form Module.name, remove the module name*) (* name might be of the form Module.name, remove the module name*)
(*let ind_name = (String.length modname) + 1 in (*let ind_name = (String.length modname) + 1 in
@ -76,10 +73,6 @@ let node_info classln =
with Not_found ->*) with Not_found ->*)
Error.message no_location (Error.Enode modname) Error.message no_location (Error.Enode modname)
(*end *) (*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])

View File

@ -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

View File

@ -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;

View File

@ -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 "@]@.@]"

View File

@ -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

View File

@ -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 =
if enabled comment (d^" ...\n");
then
let r = f p in let r = f p in
if !verbose
then begin
comment d;
pp r; pp r;
end; comment ~sep:"*** " (d^" done.");
r r
let do_silent_pass d f p = do_pass d f p (fun x -> ())
let pass d enabled f p pp =
if enabled
then do_pass d f p pp
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 =

View File

@ -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

View File

@ -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

View File

@ -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 "]@]"

2
heptc
View File

@ -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`