package catala

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

Abstract syntax tree of the default calculus intermediate representation

module StructMap : Map.S with type key = StructName.t
module EnumMap : Map.S with type key = EnumName.t

Abstract syntax tree for the default calculus

Abstract syntax tree

type typ_lit =
  1. | TBool
  2. | TUnit
  3. | TInt
  4. | TRat
  5. | TMoney
  6. | TDate
  7. | TDuration
type typ =
  1. | TLit of typ_lit
  2. | TTuple of typ Utils.Pos.marked list * StructName.t option
  3. | TEnum of typ Utils.Pos.marked list * EnumName.t
  4. | TArrow of typ Utils.Pos.marked * typ Utils.Pos.marked
  5. | TArray of typ Utils.Pos.marked
  6. | TAny
type date = Runtime.date
type duration = Runtime.duration
type lit =
  1. | LBool of bool
  2. | LEmptyError
  3. | LInt of Runtime.integer
  4. | LRat of Runtime.decimal
  5. | LMoney of Runtime.money
  6. | LUnit
  7. | LDate of date
  8. | LDuration of duration
type op_kind =
  1. | KInt
  2. | KRat
  3. | KMoney
  4. | KDate
  5. | KDuration
    (*

    All ops don't have a KDate and KDuration.

    *)
type ternop =
  1. | Fold
type binop =
  1. | And
  2. | Or
  3. | Xor
  4. | Add of op_kind
  5. | Sub of op_kind
  6. | Mult of op_kind
  7. | Div of op_kind
  8. | Lt of op_kind
  9. | Lte of op_kind
  10. | Gt of op_kind
  11. | Gte of op_kind
  12. | Eq
  13. | Neq
  14. | Map
  15. | Concat
  16. | Filter
type log_entry =
  1. | VarDef of typ
    (*

    During code generation, we need to know the type of the variable being logged for embedding

    *)
  2. | BeginCall
  3. | EndCall
  4. | PosRecordIfTrueBool
type unop =
  1. | Not
  2. | Minus of op_kind
  3. | Log of log_entry * Utils.Uid.MarkedString.info list
  4. | Length
  5. | IntToRat
  6. | GetDay
  7. | GetMonth
  8. | GetYear
type operator =
  1. | Ternop of ternop
  2. | Binop of binop
  3. | Unop of unop
type expr =
  1. | EVar of expr Bindlib.var Utils.Pos.marked
  2. | ETuple of expr Utils.Pos.marked list * StructName.t option
    (*

    The MarkedString.info is the former struct field name

    *)
  3. | ETupleAccess of expr Utils.Pos.marked * int * StructName.t option * typ Utils.Pos.marked list
    (*

    The MarkedString.info is the former struct field name

    *)
  4. | EInj of expr Utils.Pos.marked * int * EnumName.t * typ Utils.Pos.marked list
    (*

    The MarkedString.info is the former enum case name

    *)
  5. | EMatch of expr Utils.Pos.marked * expr Utils.Pos.marked list * EnumName.t
    (*

    The MarkedString.info is the former enum case name

    *)
  6. | EArray of expr Utils.Pos.marked list
  7. | ELit of lit
  8. | EAbs of (expr, expr Utils.Pos.marked) Bindlib.mbinder Utils.Pos.marked * typ Utils.Pos.marked list
  9. | EApp of expr Utils.Pos.marked * expr Utils.Pos.marked list
  10. | EAssert of expr Utils.Pos.marked
  11. | EOp of operator
  12. | EDefault of expr Utils.Pos.marked list * expr Utils.Pos.marked * expr Utils.Pos.marked
  13. | EIfThenElse of expr Utils.Pos.marked * expr Utils.Pos.marked * expr Utils.Pos.marked
  14. | ErrorOnEmpty of expr Utils.Pos.marked

The expressions use the Bindlib library, based on higher-order abstract syntax

type decl_ctx = {
  1. ctx_enums : enum_ctx;
  2. ctx_structs : struct_ctx;
}
type scope_let_kind =
  1. | DestructuringInputStruct
    (*

    let x = input.field

    *)
  2. | ScopeVarDefinition
    (*

    let x = error_on_empty e

    *)
  3. | SubScopeVarDefinition
    (*

    let s.x = fun _ -> e or let s.x = error_on_empty e for input-only subscope variables.

    *)
  4. | CallingSubScope
    (*

    let result = s ({ x = s.x; y = s.x; ...})

    *)
  5. | DestructuringSubScopeResults
    (*

    let s.x = result.x *

    *)
  6. | Assertion
    (*

    let _ = assert e

    *)

This kind annotation signals that the let-binding respects a structural invariant. These invariants concern the shape of the expression in the let-binding, and are documented below.

type scope_let = {
  1. scope_let_var : expr Bindlib.var Utils.Pos.marked;
  2. scope_let_kind : scope_let_kind;
  3. scope_let_typ : typ Utils.Pos.marked;
  4. scope_let_expr : expr Utils.Pos.marked Bindlib.box;
}

A scope let-binding has all the information necessary to make a proper let-binding expression, plus an annotation for the kind of the let-binding that comes from the compilation of a Scopelang.Ast statement.

type scope_body = {
  1. scope_body_lets : scope_let list;
  2. scope_body_result : expr Utils.Pos.marked Bindlib.box;
  3. scope_body_arg : expr Bindlib.var;
  4. scope_body_input_struct : StructName.t;
  5. scope_body_output_struct : StructName.t;
}

Instead of being a single expression, we give a little more ad-hoc structure to the scope body by decomposing it in an ordered list of let-bindings, and a result expression that uses the let-binded variables.

type program = {
  1. decl_ctx : decl_ctx;
  2. scopes : (ScopeName.t * expr Bindlib.var * scope_body) list;
}

Helpers

Variables

module Var : sig ... end
module VarMap : Map.S with type key = Var.t
val free_vars_set : expr Utils.Pos.marked -> unit VarMap.t
val free_vars_list : expr Utils.Pos.marked -> Var.t list
type vars = expr Bindlib.mvar

Other

val empty_thunked_term : expr Utils.Pos.marked
val is_value : expr Utils.Pos.marked -> bool

AST manipulation helpers

val build_whole_scope_expr : decl_ctx -> scope_body -> Utils.Pos.t -> expr Utils.Pos.marked Bindlib.box

Usage: build_whole_scope_expr ctx body scope_position where scope_position corresponds to the line of the scope declaration for instance.

val build_whole_program_expr : program -> ScopeName.t -> expr Utils.Pos.marked Bindlib.box

Usage: build_whole_program_expr program main_scope builds an expression corresponding to the main program and returning the main scope as a function.

val expr_size : expr Utils.Pos.marked -> int

Used by the optimizer to know when to stop

val variable_types : program -> typ Utils.Pos.marked VarMap.t

Traverses all the scopes and retrieves all the types for the variables that may appear in scope or subscope variable definitions, giving them as a big map.