mirror of
https://github.com/CatalaLang/catala.git
synced 2024-11-08 07:51:43 +03:00
Add a --no-typing option
it is useful e.g. to be able to print intermediate ASTs when they don't type, to debug the typing errors. This is better than commenting the typing line each time. Note that the option is not available on all targets (esp. not for ocaml and python outputs ; it's allowed on the interpreters for debugging purposes but I'm not sure if that's a good idea)
This commit is contained in:
parent
9425753eca
commit
b98bad8c33
@ -346,6 +346,10 @@ module Flags = struct
|
|||||||
& flag
|
& flag
|
||||||
& info ["check_invariants"] ~doc:"Check structural invariants on the AST."
|
& info ["check_invariants"] ~doc:"Check structural invariants on the AST."
|
||||||
|
|
||||||
|
let no_typing =
|
||||||
|
value & flag & info ["no-typing"] ~doc:
|
||||||
|
"Don't check the consistency of types"
|
||||||
|
|
||||||
let wrap_weaved_output =
|
let wrap_weaved_output =
|
||||||
value
|
value
|
||||||
& flag
|
& flag
|
||||||
|
@ -113,6 +113,7 @@ module Flags : sig
|
|||||||
(** Parsers for all flags and options that commands can use *)
|
(** Parsers for all flags and options that commands can use *)
|
||||||
|
|
||||||
val check_invariants : bool Term.t
|
val check_invariants : bool Term.t
|
||||||
|
val no_typing : bool Term.t
|
||||||
val wrap_weaved_output : bool Term.t
|
val wrap_weaved_output : bool Term.t
|
||||||
val print_only_law : bool Term.t
|
val print_only_law : bool Term.t
|
||||||
val ex_scope : string Term.t
|
val ex_scope : string Term.t
|
||||||
|
@ -141,20 +141,32 @@ module Passes = struct
|
|||||||
in
|
in
|
||||||
prg, ctx, exceptions_graphs
|
prg, ctx, exceptions_graphs
|
||||||
|
|
||||||
let dcalc options ~includes ~optimize ~check_invariants :
|
let dcalc:
|
||||||
typed Dcalc.Ast.program
|
type ty.
|
||||||
* Desugared.Name_resolution.context
|
Cli.options -> includes:Cli.raw_file list -> optimize:bool -> check_invariants:bool ->
|
||||||
* Scopelang.Dependency.TVertex.t list =
|
typed: ty mark ->
|
||||||
|
ty Dcalc.Ast.program
|
||||||
|
* Desugared.Name_resolution.context
|
||||||
|
* Scopelang.Dependency.TVertex.t list =
|
||||||
|
fun options ~includes ~optimize ~check_invariants ~typed ->
|
||||||
let prg, ctx, _ = scopelang options ~includes in
|
let prg, ctx, _ = scopelang options ~includes in
|
||||||
debug_pass_name "dcalc";
|
debug_pass_name "dcalc";
|
||||||
let type_ordering =
|
let type_ordering =
|
||||||
Scopelang.Dependency.check_type_cycles prg.program_ctx.ctx_structs
|
Scopelang.Dependency.check_type_cycles prg.program_ctx.ctx_structs
|
||||||
prg.program_ctx.ctx_enums
|
prg.program_ctx.ctx_enums
|
||||||
in
|
in
|
||||||
Message.emit_debug "Typechecking...";
|
let (prg: ty Scopelang.Ast.program) =
|
||||||
let prg = Scopelang.Ast.type_program prg in
|
match typed with
|
||||||
|
| Typed _ ->
|
||||||
|
Message.emit_debug "Typechecking...";
|
||||||
|
Scopelang.Ast.type_program prg
|
||||||
|
| Untyped _ -> prg
|
||||||
|
| Custom _ -> invalid_arg "Driver.Passes.dcalc"
|
||||||
|
in
|
||||||
Message.emit_debug "Translating to default calculus...";
|
Message.emit_debug "Translating to default calculus...";
|
||||||
let prg = Dcalc.From_scopelang.translate_program prg in
|
let prg =
|
||||||
|
Dcalc.From_scopelang.translate_program prg
|
||||||
|
in
|
||||||
let prg =
|
let prg =
|
||||||
if optimize then begin
|
if optimize then begin
|
||||||
Message.emit_debug "Optimizing default calculus...";
|
Message.emit_debug "Optimizing default calculus...";
|
||||||
@ -162,47 +174,64 @@ module Passes = struct
|
|||||||
end
|
end
|
||||||
else prg
|
else prg
|
||||||
in
|
in
|
||||||
Message.emit_debug "Typechecking again...";
|
let (prg: ty Dcalc.Ast.program) =
|
||||||
let prg =
|
match typed with
|
||||||
try Typing.program ~leave_unresolved:false prg
|
| Typed _ ->
|
||||||
with Message.CompilerError error_content ->
|
Message.emit_debug "Typechecking again...";
|
||||||
let bt = Printexc.get_raw_backtrace () in
|
(try Typing.program ~leave_unresolved:false prg
|
||||||
Printexc.raise_with_backtrace
|
with Message.CompilerError error_content ->
|
||||||
(Message.CompilerError
|
let bt = Printexc.get_raw_backtrace () in
|
||||||
(Message.Content.to_internal_error error_content))
|
Printexc.raise_with_backtrace
|
||||||
bt
|
(Message.CompilerError
|
||||||
|
(Message.Content.to_internal_error error_content))
|
||||||
|
bt)
|
||||||
|
| Untyped _ -> prg
|
||||||
|
| Custom _ -> assert false
|
||||||
in
|
in
|
||||||
if check_invariants then (
|
if check_invariants then (
|
||||||
Message.emit_debug "Checking invariants...";
|
Message.emit_debug "Checking invariants...";
|
||||||
let result = Dcalc.Invariants.check_all_invariants prg in
|
match typed with
|
||||||
if not result then
|
| Typed _ ->
|
||||||
raise (Message.raise_internal_error "Some Dcalc invariants are invalid"));
|
let result = Dcalc.Invariants.check_all_invariants prg in
|
||||||
|
if not result then
|
||||||
|
raise (Message.raise_internal_error "Some Dcalc invariants are invalid")
|
||||||
|
| _ ->
|
||||||
|
Message.raise_error "--check_invariants cannot be used with --no-typing");
|
||||||
prg, ctx, type_ordering
|
prg, ctx, type_ordering
|
||||||
|
|
||||||
let lcalc
|
let lcalc (type ty)
|
||||||
options
|
options
|
||||||
~includes
|
~includes
|
||||||
~optimize
|
~optimize
|
||||||
~check_invariants
|
~check_invariants
|
||||||
|
~(typed: ty mark)
|
||||||
~avoid_exceptions
|
~avoid_exceptions
|
||||||
~closure_conversion :
|
~closure_conversion :
|
||||||
untyped Lcalc.Ast.program
|
untyped Lcalc.Ast.program
|
||||||
* Desugared.Name_resolution.context
|
* Desugared.Name_resolution.context
|
||||||
* Scopelang.Dependency.TVertex.t list =
|
* Scopelang.Dependency.TVertex.t list =
|
||||||
let prg, ctx, type_ordering =
|
let prg, ctx, type_ordering =
|
||||||
dcalc options ~includes ~optimize ~check_invariants
|
dcalc options ~includes ~optimize ~check_invariants ~typed
|
||||||
in
|
in
|
||||||
debug_pass_name "lcalc";
|
debug_pass_name "lcalc";
|
||||||
let avoid_exceptions = avoid_exceptions || closure_conversion in
|
let avoid_exceptions = avoid_exceptions || closure_conversion in
|
||||||
let optimize = optimize || closure_conversion in
|
let optimize = optimize || closure_conversion in
|
||||||
(* --closure_conversion implies --avoid_exceptions and --optimize *)
|
(* --closure_conversion implies --avoid_exceptions and --optimize *)
|
||||||
let prg =
|
let prg =
|
||||||
if avoid_exceptions then (
|
match avoid_exceptions, options.trace, typed with
|
||||||
if options.trace then
|
| true, true, _ ->
|
||||||
Message.raise_error
|
Message.raise_error
|
||||||
"Option --avoid_exceptions is not compatible with option --trace";
|
"Option --avoid_exceptions is not compatible with option --trace"
|
||||||
Lcalc.Compile_without_exceptions.translate_program prg)
|
| true, _, Untyped _ ->
|
||||||
else Program.untype (Lcalc.Compile_with_exceptions.translate_program prg)
|
Message.raise_error
|
||||||
|
"Option --avoid_exceptions is not compatible with option --no-typing"
|
||||||
|
| true, _, Typed _ ->
|
||||||
|
Lcalc.Compile_without_exceptions.translate_program prg
|
||||||
|
| false, _, Typed _ ->
|
||||||
|
Program.untype (Lcalc.Compile_with_exceptions.translate_program prg)
|
||||||
|
| false, _, Untyped _ ->
|
||||||
|
Lcalc.Compile_with_exceptions.translate_program prg
|
||||||
|
| _, _, Custom _ -> invalid_arg "Driver.Passes.lcalc"
|
||||||
in
|
in
|
||||||
let prg =
|
let prg =
|
||||||
if optimize then begin
|
if optimize then begin
|
||||||
@ -240,7 +269,7 @@ module Passes = struct
|
|||||||
* Desugared.Name_resolution.context
|
* Desugared.Name_resolution.context
|
||||||
* Scopelang.Dependency.TVertex.t list =
|
* Scopelang.Dependency.TVertex.t list =
|
||||||
let prg, ctx, type_ordering =
|
let prg, ctx, type_ordering =
|
||||||
lcalc options ~includes ~optimize ~check_invariants ~avoid_exceptions
|
lcalc options ~includes ~optimize ~check_invariants ~typed:Expr.typed ~avoid_exceptions
|
||||||
~closure_conversion
|
~closure_conversion
|
||||||
in
|
in
|
||||||
debug_pass_name "scalc";
|
debug_pass_name "scalc";
|
||||||
@ -507,9 +536,10 @@ module Commands = struct
|
|||||||
~doc:"Parses and typechecks a Catala program, without interpreting it.")
|
~doc:"Parses and typechecks a Catala program, without interpreting it.")
|
||||||
Term.(const typecheck $ Cli.Flags.Global.options $ Cli.Flags.include_dirs)
|
Term.(const typecheck $ Cli.Flags.Global.options $ Cli.Flags.include_dirs)
|
||||||
|
|
||||||
let dcalc options includes output optimize ex_scope_opt check_invariants =
|
let dcalc typed options includes output optimize ex_scope_opt check_invariants
|
||||||
|
=
|
||||||
let prg, ctx, _ =
|
let prg, ctx, _ =
|
||||||
Passes.dcalc options ~includes ~optimize ~check_invariants
|
Passes.dcalc options ~includes ~optimize ~check_invariants ~typed
|
||||||
in
|
in
|
||||||
let _output_file, with_output = get_output_format options output in
|
let _output_file, with_output = get_output_format options output in
|
||||||
with_output
|
with_output
|
||||||
@ -537,6 +567,9 @@ module Commands = struct
|
|||||||
prg_dcalc_expr
|
prg_dcalc_expr
|
||||||
|
|
||||||
let dcalc_cmd =
|
let dcalc_cmd =
|
||||||
|
let f no_typing =
|
||||||
|
if no_typing then dcalc Expr.untyped else dcalc Expr.typed
|
||||||
|
in
|
||||||
Cmd.v
|
Cmd.v
|
||||||
(Cmd.info "dcalc"
|
(Cmd.info "dcalc"
|
||||||
~doc:
|
~doc:
|
||||||
@ -544,7 +577,8 @@ module Commands = struct
|
|||||||
representation of the Catala program. Use the $(b,-s) option to \
|
representation of the Catala program. Use the $(b,-s) option to \
|
||||||
restrict the output to a particular scope.")
|
restrict the output to a particular scope.")
|
||||||
Term.(
|
Term.(
|
||||||
const dcalc
|
const f
|
||||||
|
$ Cli.Flags.no_typing
|
||||||
$ Cli.Flags.Global.options
|
$ Cli.Flags.Global.options
|
||||||
$ Cli.Flags.include_dirs
|
$ Cli.Flags.include_dirs
|
||||||
$ Cli.Flags.output
|
$ Cli.Flags.output
|
||||||
@ -560,7 +594,7 @@ module Commands = struct
|
|||||||
check_invariants
|
check_invariants
|
||||||
disable_counterexamples =
|
disable_counterexamples =
|
||||||
let prg, ctx, _ =
|
let prg, ctx, _ =
|
||||||
Passes.dcalc options ~includes ~optimize ~check_invariants
|
Passes.dcalc options ~includes ~optimize ~check_invariants ~typed:Expr.typed
|
||||||
in
|
in
|
||||||
Verification.Globals.setup ~optimize ~disable_counterexamples;
|
Verification.Globals.setup ~optimize ~disable_counterexamples;
|
||||||
let vcs =
|
let vcs =
|
||||||
@ -608,15 +642,16 @@ module Commands = struct
|
|||||||
result)
|
result)
|
||||||
results
|
results
|
||||||
|
|
||||||
let interpret_dcalc options includes optimize check_invariants ex_scope =
|
let interpret_dcalc typed options includes optimize check_invariants ex_scope =
|
||||||
let prg, ctx, _ =
|
let prg, ctx, _ =
|
||||||
Passes.dcalc options ~includes ~optimize ~check_invariants
|
Passes.dcalc options ~includes ~optimize ~check_invariants ~typed
|
||||||
in
|
in
|
||||||
Interpreter.load_runtime_modules prg;
|
Interpreter.load_runtime_modules prg;
|
||||||
print_interpretation_results options Interpreter.interpret_program_dcalc prg
|
print_interpretation_results options Interpreter.interpret_program_dcalc prg
|
||||||
(get_scope_uid ctx ex_scope)
|
(get_scope_uid ctx ex_scope)
|
||||||
|
|
||||||
let interpret_cmd =
|
let interpret_cmd =
|
||||||
|
let f no_typing = if no_typing then interpret_dcalc Expr.untyped else interpret_dcalc Expr.typed in
|
||||||
Cmd.v
|
Cmd.v
|
||||||
(Cmd.info "interpret"
|
(Cmd.info "interpret"
|
||||||
~doc:
|
~doc:
|
||||||
@ -624,7 +659,8 @@ module Commands = struct
|
|||||||
specified by the $(b,-s) option assuming no additional external \
|
specified by the $(b,-s) option assuming no additional external \
|
||||||
inputs.")
|
inputs.")
|
||||||
Term.(
|
Term.(
|
||||||
const interpret_dcalc
|
const f
|
||||||
|
$ Cli.Flags.no_typing
|
||||||
$ Cli.Flags.Global.options
|
$ Cli.Flags.Global.options
|
||||||
$ Cli.Flags.include_dirs
|
$ Cli.Flags.include_dirs
|
||||||
$ Cli.Flags.optimize
|
$ Cli.Flags.optimize
|
||||||
@ -632,6 +668,7 @@ module Commands = struct
|
|||||||
$ Cli.Flags.ex_scope)
|
$ Cli.Flags.ex_scope)
|
||||||
|
|
||||||
let lcalc
|
let lcalc
|
||||||
|
typed
|
||||||
options
|
options
|
||||||
includes
|
includes
|
||||||
output
|
output
|
||||||
@ -642,7 +679,7 @@ module Commands = struct
|
|||||||
ex_scope_opt =
|
ex_scope_opt =
|
||||||
let prg, ctx, _ =
|
let prg, ctx, _ =
|
||||||
Passes.lcalc options ~includes ~optimize ~check_invariants
|
Passes.lcalc options ~includes ~optimize ~check_invariants
|
||||||
~avoid_exceptions ~closure_conversion
|
~avoid_exceptions ~closure_conversion ~typed
|
||||||
in
|
in
|
||||||
let _output_file, with_output = get_output_format options output in
|
let _output_file, with_output = get_output_format options output in
|
||||||
with_output
|
with_output
|
||||||
@ -658,6 +695,9 @@ module Commands = struct
|
|||||||
Format.pp_print_newline fmt ()
|
Format.pp_print_newline fmt ()
|
||||||
|
|
||||||
let lcalc_cmd =
|
let lcalc_cmd =
|
||||||
|
let f no_typing =
|
||||||
|
if no_typing then lcalc Expr.untyped else lcalc Expr.typed
|
||||||
|
in
|
||||||
Cmd.v
|
Cmd.v
|
||||||
(Cmd.info "lcalc"
|
(Cmd.info "lcalc"
|
||||||
~doc:
|
~doc:
|
||||||
@ -665,7 +705,8 @@ module Commands = struct
|
|||||||
representation of the Catala program. Use the $(b,-s) option to \
|
representation of the Catala program. Use the $(b,-s) option to \
|
||||||
restrict the output to a particular scope.")
|
restrict the output to a particular scope.")
|
||||||
Term.(
|
Term.(
|
||||||
const lcalc
|
const f
|
||||||
|
$ Cli.Flags.no_typing
|
||||||
$ Cli.Flags.Global.options
|
$ Cli.Flags.Global.options
|
||||||
$ Cli.Flags.include_dirs
|
$ Cli.Flags.include_dirs
|
||||||
$ Cli.Flags.output
|
$ Cli.Flags.output
|
||||||
@ -676,6 +717,7 @@ module Commands = struct
|
|||||||
$ Cli.Flags.ex_scope_opt)
|
$ Cli.Flags.ex_scope_opt)
|
||||||
|
|
||||||
let interpret_lcalc
|
let interpret_lcalc
|
||||||
|
typed
|
||||||
options
|
options
|
||||||
includes
|
includes
|
||||||
optimize
|
optimize
|
||||||
@ -685,13 +727,16 @@ module Commands = struct
|
|||||||
ex_scope =
|
ex_scope =
|
||||||
let prg, ctx, _ =
|
let prg, ctx, _ =
|
||||||
Passes.lcalc options ~includes ~optimize ~check_invariants
|
Passes.lcalc options ~includes ~optimize ~check_invariants
|
||||||
~avoid_exceptions ~closure_conversion
|
~avoid_exceptions ~closure_conversion ~typed
|
||||||
in
|
in
|
||||||
Interpreter.load_runtime_modules prg;
|
Interpreter.load_runtime_modules prg;
|
||||||
print_interpretation_results options Interpreter.interpret_program_lcalc prg
|
print_interpretation_results options Interpreter.interpret_program_lcalc prg
|
||||||
(get_scope_uid ctx ex_scope)
|
(get_scope_uid ctx ex_scope)
|
||||||
|
|
||||||
let interpret_lcalc_cmd =
|
let interpret_lcalc_cmd =
|
||||||
|
let f no_typing =
|
||||||
|
if no_typing then interpret_lcalc Expr.untyped else interpret_lcalc Expr.typed
|
||||||
|
in
|
||||||
Cmd.v
|
Cmd.v
|
||||||
(Cmd.info "interpret_lcalc"
|
(Cmd.info "interpret_lcalc"
|
||||||
~doc:
|
~doc:
|
||||||
@ -699,7 +744,8 @@ module Commands = struct
|
|||||||
executing the scope specified by the $(b,-s) option assuming no \
|
executing the scope specified by the $(b,-s) option assuming no \
|
||||||
additional external inputs.")
|
additional external inputs.")
|
||||||
Term.(
|
Term.(
|
||||||
const interpret_lcalc
|
const f
|
||||||
|
$ Cli.Flags.no_typing
|
||||||
$ Cli.Flags.Global.options
|
$ Cli.Flags.Global.options
|
||||||
$ Cli.Flags.include_dirs
|
$ Cli.Flags.include_dirs
|
||||||
$ Cli.Flags.optimize
|
$ Cli.Flags.optimize
|
||||||
@ -718,7 +764,7 @@ module Commands = struct
|
|||||||
closure_conversion =
|
closure_conversion =
|
||||||
let prg, _, type_ordering =
|
let prg, _, type_ordering =
|
||||||
Passes.lcalc options ~includes ~optimize ~check_invariants
|
Passes.lcalc options ~includes ~optimize ~check_invariants
|
||||||
~avoid_exceptions ~closure_conversion
|
~avoid_exceptions ~closure_conversion ~typed:Expr.typed
|
||||||
in
|
in
|
||||||
let output_file, with_output =
|
let output_file, with_output =
|
||||||
get_output_format options ~ext:".ml" output
|
get_output_format options ~ext:".ml" output
|
||||||
|
@ -44,7 +44,8 @@ module Passes : sig
|
|||||||
includes:Cli.raw_file list ->
|
includes:Cli.raw_file list ->
|
||||||
optimize:bool ->
|
optimize:bool ->
|
||||||
check_invariants:bool ->
|
check_invariants:bool ->
|
||||||
Shared_ast.typed Dcalc.Ast.program
|
typed:'m Shared_ast.mark ->
|
||||||
|
'm Dcalc.Ast.program
|
||||||
* Desugared.Name_resolution.context
|
* Desugared.Name_resolution.context
|
||||||
* Scopelang.Dependency.TVertex.t list
|
* Scopelang.Dependency.TVertex.t list
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ module Passes : sig
|
|||||||
includes:Cli.raw_file list ->
|
includes:Cli.raw_file list ->
|
||||||
optimize:bool ->
|
optimize:bool ->
|
||||||
check_invariants:bool ->
|
check_invariants:bool ->
|
||||||
|
typed:'m Shared_ast.mark ->
|
||||||
avoid_exceptions:bool ->
|
avoid_exceptions:bool ->
|
||||||
closure_conversion:bool ->
|
closure_conversion:bool ->
|
||||||
Shared_ast.untyped Lcalc.Ast.program
|
Shared_ast.untyped Lcalc.Ast.program
|
||||||
|
@ -248,6 +248,9 @@ let maybe_ty (type m) ?(typ = TAny) (m : m mark) : typ =
|
|||||||
| Untyped { pos } | Custom { pos; _ } -> Mark.add pos typ
|
| Untyped { pos } | Custom { pos; _ } -> Mark.add pos typ
|
||||||
| Typed { ty; _ } -> ty
|
| Typed { ty; _ } -> ty
|
||||||
|
|
||||||
|
let untyped = Untyped { pos = Pos.no_pos }
|
||||||
|
let typed = Typed { pos = Pos.no_pos; ty = TLit TUnit, Pos.no_pos }
|
||||||
|
|
||||||
(* - Predefined types (option) - *)
|
(* - Predefined types (option) - *)
|
||||||
|
|
||||||
let option_enum = EnumName.fresh [] ("eoption", Pos.no_pos)
|
let option_enum = EnumName.fresh [] ("eoption", Pos.no_pos)
|
||||||
|
@ -193,6 +193,9 @@ val maybe_ty : ?typ:naked_typ -> 'm mark -> typ
|
|||||||
(** Returns the corresponding type on a typed expr, or [typ] (defaulting to
|
(** Returns the corresponding type on a typed expr, or [typ] (defaulting to
|
||||||
[TAny]) at the current position on an untyped one *)
|
[TAny]) at the current position on an untyped one *)
|
||||||
|
|
||||||
|
val untyped : untyped mark (** Type witness for untyped marks *)
|
||||||
|
val typed : typed mark (** Type witness for untyped marks *)
|
||||||
|
|
||||||
(** {2 Predefined types} *)
|
(** {2 Predefined types} *)
|
||||||
|
|
||||||
val option_enum : EnumName.t
|
val option_enum : EnumName.t
|
||||||
|
Loading…
Reference in New Issue
Block a user