open Ast
open Static
open Misc
exception Fallback
type 'a it_funs = {
static_exp : 'a it_funs -> 'a -> static_exp -> static_exp * 'a;
static_exp_desc : 'a it_funs -> 'a -> static_exp_desc -> static_exp_desc * 'a;
ty : 'a it_funs -> 'a -> ty -> ty * 'a;
link : 'a it_funs -> 'a -> link -> link * 'a;
edesc : 'a it_funs -> 'a -> edesc -> edesc * 'a;
exp : 'a it_funs -> 'a -> exp -> exp * 'a;
pat : 'a it_funs -> 'a -> pat -> pat * 'a;
equation : 'a it_funs -> 'a -> equation -> equation * 'a;
var_dec : 'a it_funs -> 'a -> var_dec -> var_dec * 'a;
block : 'a it_funs -> 'a -> block -> block * 'a;
node_dec : 'a it_funs -> 'a -> node_dec -> node_dec * 'a;
const_dec : 'a it_funs -> 'a -> const_dec -> const_dec * 'a;
program : 'a it_funs -> 'a -> program -> program * 'a;
}
let rec exp_it funs acc e = funs.exp funs acc e
and exp funs acc e =
let e_desc, acc = edesc_it funs acc e.e_desc in
let e_ty, acc = ty_it funs acc e.e_ty in
{ e with e_desc = e_desc; e_ty = e_ty }, acc
and edesc_it funs acc ed =
try funs.edesc funs acc ed
with Fallback -> edesc funs acc ed
and edesc funs acc ed = match ed with
| Econst v -> Econst v, acc
| Evar id -> Evar id, acc
| Ereg e ->
let e, acc = exp_it funs acc e in
Ereg e, acc
| Emem(k, addr_size, word_size, s, args) ->
let addr_size, acc = static_exp_it funs acc addr_size in
let word_size, acc = static_exp_it funs acc word_size in
let args, acc = mapfold (exp_it funs) acc args in
Emem(k, addr_size, word_size, s, args), acc
| Ecall(id, params, args) ->
let params, acc = mapfold (static_exp_it funs) acc params in
let args, acc = mapfold (exp_it funs) acc args in
Ecall(id, params, args), acc
and static_exp_it funs acc sd =
try funs.static_exp funs acc sd
with Fallback -> static_exp funs acc sd
and static_exp funs acc se =
let se_desc, acc = static_exp_desc_it funs acc se.se_desc in
{ se with se_desc = se_desc }, acc
and static_exp_desc_it funs acc sed =
try funs.static_exp_desc funs acc sed
with Fallback -> static_exp_desc funs acc sed
and static_exp_desc funs acc sed = match sed with
| SInt _ | SBool _ | SVar _ -> sed, acc
| SBinOp (sop, se1, se2) ->
let se1, acc = static_exp_it funs acc se1 in
let se2, acc = static_exp_it funs acc se2 in
SBinOp(sop, se1, se2), acc
| SIf(c, se1, se2) ->
let c, acc = static_exp_it funs acc c in
let se1, acc = static_exp_it funs acc se1 in
let se2, acc = static_exp_it funs acc se2 in
SIf(c, se1, se2), acc
and ty_it funs acc t = try funs.ty funs acc t with Fallback -> ty funs acc t
and ty funs acc t = match t with
| TUnit | TBit -> t, acc
| TBitArray se ->
let se, acc = static_exp_it funs acc se in
TBitArray se, acc
| TProd t_l ->
let t_l, acc = mapfold (ty_it funs) acc t_l in
TProd t_l, acc
| TVar link ->
let link_v, acc = link_it funs acc !link in
link := link_v;
TVar link, acc
and link_it funs acc c =
try funs.link funs acc c
with Fallback -> link funs acc c
and link funs acc l = match l with
| TIndex _ -> l, acc
| TLink ty ->
let ty, acc = ty_it funs acc ty in
TLink ty, acc
and pat_it funs acc p =
try funs.pat funs acc p
with Fallback -> pat funs acc p
and pat funs acc p = p, acc
and equation_it funs acc eq = funs.equation funs acc eq
and equation funs acc (pat, e) =
let pat, acc = pat_it funs acc pat in
let e, acc = exp_it funs acc e in
(pat, e), acc
and block_it funs acc b =
try funs.block funs acc b
with Fallback -> block funs acc b
and block funs acc b = match b with
| BEqs(eqs, vds) ->
let vds, acc = mapfold (var_dec_it funs) acc vds in
let eqs, acc = mapfold (equation_it funs) acc eqs in
BEqs (eqs, vds), acc
| BIf(se, b1, b2) ->
let se, acc = static_exp_it funs acc se in
let b1, acc = block_it funs acc b1 in
let b2, acc = block_it funs acc b2 in
BIf(se, b1, b2), acc
and var_dec_it funs acc vd = funs.var_dec funs acc vd
and var_dec funs acc vd =
let v_ty, acc = ty_it funs acc vd.v_ty in
{ vd with v_ty = v_ty }, acc
and node_dec_it funs acc nd = funs.node_dec funs acc nd
and node_dec funs acc nd =
let n_inputs, acc = mapfold (var_dec_it funs) acc nd.n_inputs in
let n_outputs, acc = mapfold (var_dec_it funs) acc nd.n_outputs in
let n_constraints, acc = mapfold (static_exp_it funs) acc nd.n_constraints in
let n_body, acc = block_it funs acc nd.n_body in
{ nd with
n_inputs = n_inputs;
n_outputs = n_outputs;
n_body = n_body;
n_constraints = n_constraints }
, acc
and const_dec_it funs acc c = funs.const_dec funs acc c
and const_dec funs acc c =
let c_value, acc = static_exp_it funs acc c.c_value in
{ c with c_value = c_value }, acc
and program_it funs acc p = funs.program funs acc p
and program funs acc p =
let p_consts, acc = mapfold (const_dec_it funs) acc p.p_consts in
let p_nodes, acc = mapfold (node_dec_it funs) acc p.p_nodes in
{ p_nodes = p_nodes; p_consts = p_consts }, acc
let defaults = {
static_exp = static_exp;
static_exp_desc = static_exp_desc;
ty = ty;
link = link;
edesc = edesc;
exp = exp;
pat = pat;
equation = equation;
var_dec = var_dec;
block = block;
node_dec = node_dec;
const_dec = const_dec;
program = program;
}