type binop = | Add | Sub | Mul | Div | Eq | Ne | Lt | Le | Gt | Ge | And | Or type expr = { e : expr_desc; espan : Location.span; } and expr_desc = | EInt of int | EBool of bool | EString of string | EUnit | EVar of string | ELet of string * expr * expr | ELambda of string * expr | EApp of expr * expr | EIf of expr * expr * expr | EBinop of binop * expr * expr | ENeg of expr | ETuple of expr list | ERecord of (string * expr) list | EField of expr * string | EFilter of expr | EMap of expr | ESum | ECount type tyexpr = { ty : tyexpr_desc; tyspan : Location.span; } and tyexpr_desc = | TyName of string | TyCollection of tyexpr | TyTuple of tyexpr list type record_decl = { rd_name : string; rd_name_span : Location.span; rd_fields : (string * tyexpr) list; rd_span : Location.span; } type input_decl = { in_name : string; in_name_span : Location.span; in_ty : tyexpr; in_span : Location.span; } type helper = { h_name : string; h_name_span : Location.span; h_params : string list; h_body : expr; h_span : Location.span; } type query = { q_name : string; q_name_span : Location.span; q_body : expr; q_span : Location.span; } type declaration = | DRecord of record_decl | DInput of input_decl | DHelper of helper | DQuery of query type program = { prog_records : record_decl list; prog_input : input_decl; prog_helpers : helper list; prog_query : query; } let make e espan = { e = e; espan = espan } let make_ty ty tyspan = { ty = ty; tyspan = tyspan } let binop_name = function | Add -> "+" | Sub -> "-" | Mul -> "*" | Div -> "/" | Eq -> "=" | Ne -> "<>" | Lt -> "<" | Le -> "<=" | Gt -> ">" | Ge -> ">=" | And -> "&&" | Or -> "||" let string_of_binop = binop_name let rec string_of_tyexpr tyexpr = match tyexpr.ty with | TyName name -> name | TyCollection element -> "collection " ^ string_of_tyexpr element | TyTuple elements -> "(" ^ String.concat ", " (List.map string_of_tyexpr elements) ^ ")"