Framework for writing nanopass-style compilers
val typeck_pass : Pass.np_pass -> Pass.np_pass

perform "typechecking" on the clauses in each processor of the pass. this checks the patterns against the production signatures, to make sure that they are well formed. additionally, it elaborates patterns in the following ways: 1) infers catamorphism expressions 2) elaborates catamorphisms that aren't applied directly to a nonterminal

for instance, given the nonterm type stmt = `Def of (string, expr) list | ... it expands the pattern `Def (defs @r) into `Def ( (_, _ @r expr) @l as defs )

this way, NPpat_cata is only applied directly to nonterminals (in this case, 'expr'), which simplifies the generation of code.

non-exhaustive patterns are not allowed within @l or @r forms. This is because they expand to let definitions that match the inner pattern. e.g. `Def () ok `Var ((x,i) @r) ok

`Def ( @r) bad would expand into roughly `Def (defs_) -> let = List.map (fun (x,e) -> ...) defs_ in ^ if this pattern fails, we are fucked

`Expr (e' @r, ) ok NOTE: if the match fails, the cata for e' will not be called! expands into `Expr (e_, ) -> let e' = expr_of_expr e_ in *

val typeck_err : loc:Ast.Location.t -> Lang.np_type -> exn

returns an exn for type errors. *

val cross_off : Lang.np_production list -> Pass.clause list -> Lang.np_production list

Find all missing productions for a pass

val gen_missing : pass:Pass.np_pass -> loc:Ast.Location.t -> Lang.np_production list -> Pass.clause list
val typeck_pat : pass:Pass.np_pass -> Lang.np_type -> Pass.np_pat -> Pass.np_pat

typecheck a single pattern, with the given expected type. if it succeeds, returns a pattern that is the same as the given pattern, with all empty @r patterns filled in with an inferred catamorphism function. *

val typeck_nonterm : pass:Pass.np_pass -> loc:Ast.Location.t -> string -> string -> Pass.np_pat option -> Pass.np_pat option

typecheck the (optional) argument to a nontermal given pr_name, the name of the production it is associated with. nt_name must be a valid nonterminal in the input language.

val typeck_cata : pass:Pass.np_pass -> loc:Ast.Location.t -> Ast.expression option -> Lang.np_type -> Pass.np_pat -> [ `Infer of Ast.expression | `Rewrite of Pass.np_pat ]

typechecks a catamorphism pattern, which either infers the catamorphism, or rewrites the pattern by moving the catamorphism to deeper sub-patterns. *

val pat_is_conditional : Pass.np_pat -> bool

determines if a pattern is conditional, e.g. it can fail for certain values. *

val catamorphism : pass:Pass.np_pass -> loc:Ast.Location.t -> Lang.np_nonterm -> Ast.expression

generate an appropriate catamorphism function expression for the given nonterminal. *