Frontend.AstAbstract syntax tree for Stan. Defined with the 'two-level types' pattern, where the variant types are not directly recursive, but rather parametric in some other type.
This type ends up being substituted for the fixpoint of the recursive type itself including metadata. So instead of recursively referencing expression you would instead reference type parameter 'e, which will later be filled in with something like type expr_with_meta = metadata expression
Our type for identifiers, on which we record a location
val sexp_of_identifier : identifier -> Sexplib0.Sexp.tval compare_identifier : identifier -> identifier -> Core.intIndices for array access
val sexp_of_index : 'e. ('e -> Sexplib0.Sexp.t) -> 'e index -> Sexplib0.Sexp.tval fold_index : ('a -> 'b -> 'a) -> 'a -> 'b index -> 'atype fun_kind = | StanLib of Core.bool Middle.Fun_kind.suffix| UserDefined of Core.bool Middle.Fun_kind.suffixFront-end function kinds
val sexp_of_fun_kind : fun_kind -> Sexplib0.Sexp.ttype ('e, 'f, 'p) expression = | TernaryIf of 'e * 'e * 'e| BinOp of 'e * Middle.Operator.t * 'e| PrefixOp of Middle.Operator.t * 'e| PostfixOp of 'e * Middle.Operator.t| Variable of identifier| IntNumeral of Core.string| RealNumeral of Core.string| ImagNumeral of Core.string| FunApp of 'f * identifier * 'e Core.list| CondDistApp of 'f * identifier * 'e Core.list| Promotion of 'e * 'p| GetTarget| ArrayExpr of 'e Core.list| RowVectorExpr of 'e Core.list| Paren of 'e| Indexed of 'e * 'e index Core.list| TupleProjection of 'e * Core.int| TupleExpr of 'e Core.listExpression shapes (used for both typed and untyped expressions, where we substitute untyped_expression or typed_expression for 'e
val sexp_of_expression :
'e 'f 'p. ('e -> Sexplib0.Sexp.t) ->
('f -> Sexplib0.Sexp.t) ->
('p -> Sexplib0.Sexp.t) ->
('e, 'f, 'p) expression ->
Sexplib0.Sexp.tval compare_expression :
'e 'f 'p. ('e -> 'e -> Core.int) ->
('f -> 'f -> Core.int) ->
('p -> 'p -> Core.int) ->
('e, 'f, 'p) expression ->
('e, 'f, 'p) expression ->
Core.intval sexp_of_expr_with :
'm 'f 'p. ('m -> Sexplib0.Sexp.t) ->
('f -> Sexplib0.Sexp.t) ->
('p -> Sexplib0.Sexp.t) ->
('m, 'f, 'p) expr_with ->
Sexplib0.Sexp.tUntyped expressions, which have location_spans as meta-data
val sexp_of_located_meta : located_meta -> Sexplib0.Sexp.tval compare_located_meta : located_meta -> located_meta -> Core.inttype untyped_expression = (located_meta, Core.unit, Core.Nothing.t) expr_withval sexp_of_untyped_expression : untyped_expression -> Sexplib0.Sexp.tval compare_untyped_expression :
untyped_expression ->
untyped_expression ->
Core.inttype typed_expr_meta = {loc : Middle.Location_span.t;ad_level : Middle.UnsizedType.autodifftype;type_ : Middle.UnsizedType.t;}Typed expressions also have meta-data after type checking: a location_span, as well as a type and an origin block (lub of the origin blocks of the identifiers in it)
val sexp_of_typed_expr_meta : typed_expr_meta -> Sexplib0.Sexp.ttype typed_expression =
(typed_expr_meta,
fun_kind,
Middle.UnsizedType.t * Middle.UnsizedType.autodifftype)
expr_withval sexp_of_typed_expression : typed_expression -> Sexplib0.Sexp.tval expr_loc_lub :
(typed_expr_meta, 'a, 'b) expr_with Core.List.t ->
Middle.Location_span.tval expr_ad_lub :
(typed_expr_meta, 'a, 'b) expr_with Core.List.t ->
Middle.UnsizedType.autodifftype optionLeast upper bound of expression autodiff types
Assignment operators
val sexp_of_assignmentoperator : assignmentoperator -> Sexplib0.Sexp.tval compare_assignmentoperator :
assignmentoperator ->
assignmentoperator ->
Core.intval sexp_of_truncation :
'e. ('e -> Sexplib0.Sexp.t) ->
'e truncation ->
Sexplib0.Sexp.tval compare_truncation :
'e. ('e -> 'e -> Core.int) ->
'e truncation ->
'e truncation ->
Core.intval map_truncation : ('a -> 'b) -> 'a truncation -> 'b truncationval fold_truncation : ('a -> 'b -> 'a) -> 'a -> 'b truncation -> 'aThings that can be printed
val sexp_of_printable :
'e. ('e -> Sexplib0.Sexp.t) ->
'e printable ->
Sexplib0.Sexp.tval fold_printable : ('a -> 'b -> 'a) -> 'a -> 'b printable -> 'atype ('l, 'e) lvalue = | LVariable of identifier| LIndexed of 'l * 'e index Core.list| LTupleProjection of 'l * Core.intval sexp_of_lvalue :
'l 'e. ('l -> Sexplib0.Sexp.t) ->
('e -> Sexplib0.Sexp.t) ->
('l, 'e) lvalue ->
Sexplib0.Sexp.tval fold_lvalue :
('a -> 'b -> 'a) ->
('a -> 'c -> 'a) ->
'a ->
('b, 'c) lvalue ->
'atype 'l lvalue_pack = | LValue of 'l| LTuplePack of {lvals : 'l lvalue_pack Core.list;loc : Middle.Location_span.t;}val sexp_of_lvalue_pack :
'l. ('l -> Sexplib0.Sexp.t) ->
'l lvalue_pack ->
Sexplib0.Sexp.tval compare_lvalue_pack :
'l. ('l -> 'l -> Core.int) ->
'l lvalue_pack ->
'l lvalue_pack ->
Core.intval map_lvalue_pack : ('a -> 'b) -> 'a lvalue_pack -> 'b lvalue_packval fold_lvalue_pack : ('a -> 'b -> 'a) -> 'a -> 'b lvalue_pack -> 'aval sexp_of_lval_with :
'e 'm. ('e -> Sexplib0.Sexp.t) ->
('m -> Sexplib0.Sexp.t) ->
('e, 'm) lval_with ->
Sexplib0.Sexp.ttype untyped_lval = (untyped_expression, located_meta) lval_withval sexp_of_untyped_lval : untyped_lval -> Sexplib0.Sexp.tval compare_untyped_lval : untyped_lval -> untyped_lval -> Core.inttype untyped_lval_pack = untyped_lval lvalue_packval sexp_of_untyped_lval_pack : untyped_lval_pack -> Sexplib0.Sexp.tval compare_untyped_lval_pack :
untyped_lval_pack ->
untyped_lval_pack ->
Core.inttype typed_lval = (typed_expression, typed_expr_meta) lval_withval sexp_of_typed_lval : typed_lval -> Sexplib0.Sexp.ttype typed_lval_pack = typed_lval lvalue_packval sexp_of_typed_lval_pack : typed_lval_pack -> Sexplib0.Sexp.tval sexp_of_variable :
'e. ('e -> Sexplib0.Sexp.t) ->
'e variable ->
Sexplib0.Sexp.tval fold_variable : ('a -> 'b -> 'a) -> 'a -> 'b variable -> 'atype ('e, 's, 'l, 'f) statement = | Assignment of {assign_lhs : 'l lvalue_pack;assign_op : assignmentoperator;assign_rhs : 'e;}| NRFunApp of 'f * identifier * 'e Core.list| TargetPE of 'e| JacobianPE of 'e| Tilde of {arg : 'e;distribution : identifier;kind : 'f;args : 'e Core.list;truncation : 'e truncation;}| Break| Continue| Return of 'e| ReturnVoid| Print of 'e printable Core.list| Reject of 'e printable Core.list| FatalError of 'e printable Core.list| Skip| IfThenElse of 'e * 's * 's Core.option| While of 'e * 's| For of {loop_variable : identifier;lower_bound : 'e;upper_bound : 'e;loop_body : 's;}| ForEach of identifier * 'e * 's| Profile of Core.string * 's Core.list| Block of 's Core.list| VarDecl of {decl_type : 'e Middle.SizedType.t;transformation : 'e Middle.Transformation.t;is_global : Core.bool;variables : 'e variable Core.list;}| FunDef of {returntype : Middle.UnsizedType.returntype;funname : identifier;arguments : (Middle.UnsizedType.autodifftype
* Middle.UnsizedType.t
* identifier)
Core.list;body : 's;}Statement shapes, where we substitute untyped_expression and untyped_statement for 'e and 's respectively to get untyped_statement and typed_expression and typed_statement to get typed_statement
val sexp_of_statement :
'e 's 'l 'f. ('e -> Sexplib0.Sexp.t) ->
('s -> Sexplib0.Sexp.t) ->
('l -> Sexplib0.Sexp.t) ->
('f -> Sexplib0.Sexp.t) ->
('e, 's, 'l, 'f) statement ->
Sexplib0.Sexp.tStatement return types which we will decorate statements with during type checking:
Complete corresponds to statements that exit the function (return or error) in every branchIncomplete corresponds to statements which pass control flow to following statements in at least some branchesNonlocalControlFlow is simila to Incomplete but specifically used when breaks are present in loops. Normally, an infinite loop with Incomplete return type is fine (and considered Complete), since it either returns or diverges. However, in the presence of break statements, control flow may jump to the end of the loop.val sexp_of_statement_returntype : statement_returntype -> Sexplib0.Sexp.ttype ('e, 'm, 'l, 'f) statement_with = {stmt : ('e, ('e, 'm, 'l, 'f) statement_with, 'l, 'f) statement;smeta : 'm;}val sexp_of_statement_with :
'e 'm 'l 'f. ('e -> Sexplib0.Sexp.t) ->
('m -> Sexplib0.Sexp.t) ->
('l -> Sexplib0.Sexp.t) ->
('f -> Sexplib0.Sexp.t) ->
('e, 'm, 'l, 'f) statement_with ->
Sexplib0.Sexp.tval compare_statement_with :
'e 'm 'l 'f. ('e -> 'e -> Core.int) ->
('m -> 'm -> Core.int) ->
('l -> 'l -> Core.int) ->
('f -> 'f -> Core.int) ->
('e, 'm, 'l, 'f) statement_with ->
('e, 'm, 'l, 'f) statement_with ->
Core.inttype untyped_statement =
(untyped_expression, located_meta, untyped_lval, Core.unit) statement_withUntyped statements, which have location_spans as meta-data
val sexp_of_untyped_statement : untyped_statement -> Sexplib0.Sexp.tval compare_untyped_statement :
untyped_statement ->
untyped_statement ->
Core.intval mk_untyped_statement :
stmt:
(untyped_expression,
(untyped_expression, located_meta, untyped_lval, Core.unit)
statement_with,
untyped_lval,
Core.unit)
statement ->
loc:Middle.Location_span.t ->
untyped_statementval sexp_of_stmt_typed_located_meta :
stmt_typed_located_meta ->
Sexplib0.Sexp.ttype typed_statement =
(typed_expression, stmt_typed_located_meta, typed_lval, fun_kind)
statement_withTyped statements also have meta-data after type checking: a location_span, as well as a statement returntype to check that function bodies have the right return type
val sexp_of_typed_statement : typed_statement -> Sexplib0.Sexp.tval mk_typed_statement :
stmt:
('a, ('a, stmt_typed_located_meta, 'b, 'c) statement_with, 'b, 'c)
statement ->
loc:Middle.Location_span.t ->
return_type:statement_returntype ->
('a, stmt_typed_located_meta, 'b, 'c) statement_withProgram shapes, where we obtain types of programs if we substitute typed or untyped statements for 's
val sexp_of_block : 's. ('s -> Sexplib0.Sexp.t) -> 's block -> Sexplib0.Sexp.tval fold_block : ('a -> 'b -> 'a) -> 'a -> 'b block -> 'atype comment_type = | LineComment of Core.string * Middle.Location_span.t| Include of Core.string * Middle.Location_span.t| BlockComment of Core.string Core.list * Middle.Location_span.t| Separator of Middle.Location.tSeparator records the location of items like commas, operators, and keywords which don't have location information stored in the AST but are useful for placing comments in pretty printing
*)type 's program = {functionblock : 's block Core.option;datablock : 's block Core.option;transformeddatablock : 's block Core.option;parametersblock : 's block Core.option;transformedparametersblock : 's block Core.option;modelblock : 's block Core.option;generatedquantitiesblock : 's block Core.option;comments : comment_type Core.list;}val sexp_of_program :
's. ('s -> Sexplib0.Sexp.t) ->
's program ->
Sexplib0.Sexp.tval fold_program : ('a -> 'b -> 'a) -> 'a -> 'b program -> 'atype untyped_program = untyped_statement programUntyped programs (before type checking)
val sexp_of_untyped_program : untyped_program -> Sexplib0.Sexp.tval compare_untyped_program : untyped_program -> untyped_program -> Core.inttype typed_program = typed_statement programTyped programs (after type checking)
val sexp_of_typed_program : typed_program -> Sexplib0.Sexp.tval untyped_expression_of_typed_expression :
typed_expression ->
untyped_expressionForgetful function from typed to untyped expressions
val untyped_lvalue_of_typed_lvalue : typed_lval -> untyped_lvalval untyped_lvalue_of_typed_lvalue_pack :
typed_lval lvalue_pack ->
untyped_lval lvalue_packval untyped_statement_of_typed_statement :
(typed_expression, stmt_typed_located_meta, typed_lval, 'a) statement_with ->
(untyped_expression, located_meta, untyped_lval, unit) statement_withForgetful function from typed to untyped statements
val untyped_program_of_typed_program : typed_program -> untyped_programForgetful function from typed to untyped programs
in practice, we never want to fold over the FnKind or Promotion types so we shadow the @@derived fold_expression
val fold_expression : ('a -> 'b -> 'a) -> 'a -> ('b, 'c, 'd) expression -> 'aval fold_lval_with : ('a -> 'b -> 'a) -> 'a -> ('b, 'c) lval_with -> 'aval fold_statement :
('a -> 'b -> 'a) ->
('a -> 'c -> 'a) ->
('a -> 'd -> 'a) ->
'a ->
('b, 'c, 'd, 'e) statement ->
'asimilarly for map
val map_expression :
('a -> 'b) ->
('a, 'c, 'd) expression ->
('b, 'c, 'd) expressionval mk_typed_expression :
expr:((typed_expr_meta, 'a, 'b) expr_with, 'a, 'b) expression ->
loc:Middle.Location_span.t ->
type_:Middle.UnsizedType.t ->
ad_level:Middle.UnsizedType.autodifftype ->
(typed_expr_meta, 'a, 'b) expr_withval exprs_in_index : 'a index -> 'a listval extract_ids : ('a, 'b, 'c) expr_with -> identifier Core.List.tval lvalue_of_expr_opt :
untyped_expression ->
((located_meta, Core.unit, Core.Nothing.t) expr_with, located_meta) lval_with
lvalue_pack
Core.Option.tval type_of_arguments :
(Middle.UnsizedType.autodifftype * Middle.UnsizedType.t * 'a) Core.list ->
Middle.UnsizedType.argumentlistval get_loc_lvalue_pack : typed_lval lvalue_pack -> Middle.Location_span.tval get_loc_dt :
untyped_expression Middle.SizedType.t ->
Middle.Location.t optionval get_loc_tf :
untyped_expression Middle.Transformation.t ->
Middle.Location.t optionval get_first_loc : untyped_statement -> Middle.Location.t