Skip to content

Commit d5cc612

Browse files
committed
wip lang ext
1 parent 8394ee3 commit d5cc612

File tree

5 files changed

+125
-85
lines changed

5 files changed

+125
-85
lines changed

src/basic/FStarC.Options.fst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ let defaults = [
234234
("initial_ifuel" , Int 1);
235235
("keep_query_captions" , Bool true);
236236
("krmloutput" , Unset);
237+
("lang_extensions" , List []);
237238
("lax" , Bool false);
238239
("list_plugins" , Bool false);
239240
("load_cmxs" , List []);
@@ -500,6 +501,7 @@ let get_print_in_place () = lookup_opt "print_in_place"
500501
let get_initial_fuel () = lookup_opt "initial_fuel" as_int
501502
let get_initial_ifuel () = lookup_opt "initial_ifuel" as_int
502503
let get_keep_query_captions () = lookup_opt "keep_query_captions" as_bool
504+
let get_lang_extensions () = lookup_opt "lang_extensions" (as_list as_string)
503505
let get_lax () = lookup_opt "lax" as_bool
504506
let get_load () = lookup_opt "load" (as_list as_string)
505507
let get_load_cmxs () = lookup_opt "load_cmxs" (as_list as_string)
@@ -1117,6 +1119,11 @@ let specs_with_types warn_unsafe : list (char & string & opt_type & Pprint.docum
11171119
BoolStr,
11181120
text "Retain comments in the logged SMT queries (requires --log_queries or --log_failing_queries; default true)");
11191121
1122+
( noshort,
1123+
"lang_extensions",
1124+
Accumulated (SimpleStr "extension"),
1125+
text "Automatically enable the given language extensions based on the file extension. For example, value `pulse` allows using *.pulse and *.pulsei files.");
1126+
11201127
( noshort,
11211128
"lax",
11221129
WithSideEffect ((fun () -> if warn_unsafe then option_warning_callback "lax"), Const (Bool true)),
@@ -1762,6 +1769,7 @@ let settable = function
17621769
| "initial_ifuel"
17631770
| "ide_id_info_off"
17641771
| "keep_query_captions"
1772+
| "lang_extensions"
17651773
| "load"
17661774
| "load_cmxs"
17671775
| "log_queries"
@@ -2118,6 +2126,7 @@ let print () = get_print ()
21182126
let print_in_place () = get_print_in_place ()
21192127
let initial_fuel () = min (get_initial_fuel ()) (get_max_fuel ())
21202128
let initial_ifuel () = min (get_initial_ifuel ()) (get_max_ifuel ())
2129+
let lang_extensions () = get_lang_extensions ()
21212130
let lax () = get_lax ()
21222131
let load () = get_load ()
21232132
let load_cmxs () = get_load_cmxs ()

src/basic/FStarC.Options.fsti

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ val initial_fuel : unit -> int
161161
val initial_ifuel : unit -> int
162162
val interactive : unit -> bool
163163
val keep_query_captions : unit -> bool
164+
val lang_extensions : unit -> list string
164165
val lax : unit -> bool
165166
val load : unit -> list string
166167
val load_cmxs : unit -> list string

src/ml/FStarC_Parser_ParseIt.ml

Lines changed: 108 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,19 @@ let read_file (filename:string) =
7676
if debug then FStarC_Format.print1 "Opening file %s\n" filename;
7777
filename, read_physical_file filename
7878

79-
let fst_extensions = [".fst"; ".fsti"]
80-
let interface_extensions = [".fsti"]
79+
let extra_extensions () = List.concat_map (fun x -> ["." ^ x; "." ^ x ^ "i"]) (FStarC_Options.lang_extensions ())
80+
let fst_extensions () = [".fst"; ".fsti"] @ extra_extensions ()
81+
let extra_extensions_interface () = List.map (fun x -> "." ^ x ^ "i") (FStarC_Options.lang_extensions ())
82+
let interface_extensions () = [".fsti"] @ extra_extensions_interface ()
8183

8284
let has_extension file extensions =
8385
FStar_List.existsb (U.ends_with file) extensions
8486

87+
let take_lang_extension file =
88+
FStar_List.tryFind (fun x -> U.ends_with file ("."^x)) (extra_extensions ())
89+
8590
let check_extension fn =
86-
if (not (has_extension fn fst_extensions)) then
91+
if (not (has_extension fn (fst_extensions ()))) then
8792
let message = FStarC_Format.fmt1 "Unrecognized extension '%s'" fn in
8893
raise_error_text FStarC_Range.dummyRange Fatal_UnrecognizedExtension message
8994

@@ -523,91 +528,113 @@ let _ = FStarC_Parser_AST_Util.register_extension_lang_parser "fstar" parse_fsta
523528
type lang_opts = string option
524529

525530
let parse_lang lang fn =
526-
match fn with
527-
| Filename _ ->
528-
failwith "parse_lang: only in incremental mode"
529-
| Incremental s
530-
| Toplevel s
531-
| Fragment s ->
532-
try
533-
let frag_pos = FStarC_Range.mk_pos s.frag_line s.frag_col in
534-
let rng = FStarC_Range.mk_range s.frag_fname frag_pos frag_pos in
535-
let decls = FStarC_Parser_AST_Util.parse_extension_lang lang s.frag_text rng in
536-
let comments = FStarC_Parser_Util.flush_comments () in
537-
ASTFragment (Inr decls, comments)
538-
with
531+
let s =
532+
match fn with
533+
| Filename f ->
534+
check_extension f;
535+
let f', contents = read_file f in
536+
{
537+
frag_fname = f';
538+
frag_text = contents;
539+
frag_line = Z.one;
540+
frag_col = Z.zero;
541+
}
542+
| Incremental s
543+
| Toplevel s
544+
| Fragment s -> s
545+
in
546+
try
547+
let frag_pos = FStarC_Range.mk_pos s.frag_line s.frag_col in
548+
let rng = FStarC_Range.mk_range s.frag_fname frag_pos frag_pos in
549+
let decls = FStarC_Parser_AST_Util.parse_extension_lang lang s.frag_text rng in
550+
let comments = FStarC_Parser_Util.flush_comments () in
551+
ASTFragment (Inr decls, comments)
552+
with
553+
| FStarC_Errors.Error(e, msg, r, _ctx) ->
554+
ParseError (e, msg, r)
555+
556+
let parse_no_lang fn =
557+
let lexbuf, filename, contents =
558+
match fn with
559+
| Filename f ->
560+
check_extension f;
561+
let f', contents = read_file f in
562+
(try create contents f' 1 0, f', contents
563+
with _ -> raise_error_text FStarC_Range.dummyRange Fatal_InvalidUTF8Encoding (FStarC_Format.fmt1 "File %s has invalid UTF-8 encoding." f'))
564+
| Incremental s
565+
| Toplevel s
566+
| Fragment s ->
567+
create s.frag_text s.frag_fname (Z.to_int s.frag_line) (Z.to_int s.frag_col), "<input>", s.frag_text
568+
in
569+
570+
let lexer () =
571+
let tok = FStarC_Parser_LexFStar.token lexbuf in
572+
if !dbg_Tokens then
573+
print_string ("TOKEN: " ^ (string_of_token tok) ^ "\n");
574+
(tok, lexbuf.start_p, lexbuf.cur_p)
575+
in
576+
try
577+
match fn with
578+
| Filename _
579+
| Toplevel _ -> begin
580+
let fileOrFragment =
581+
MenhirLib.Convert.Simplified.traditional2revised FStarC_Parser_Parse.inputFragment lexer
582+
in
583+
let frags = match fileOrFragment with
584+
| FStar_Pervasives.Inl modul ->
585+
if has_extension filename (interface_extensions ())
586+
then FStar_Pervasives.Inl (FStarC_Parser_AST.as_interface modul)
587+
else FStar_Pervasives.Inl modul
588+
| _ -> fileOrFragment
589+
in ASTFragment (frags, FStarC_Parser_Util.flush_comments ())
590+
end
591+
592+
| Incremental i ->
593+
let decls, comments, err_opt =
594+
parse_incremental_fragment
595+
filename
596+
i.frag_text
597+
lexbuf
598+
lexer
599+
(fun (d:FStarC_Parser_AST.decl) -> d.drange)
600+
FStarC_Parser_Parse.oneDeclOrEOF
601+
in
602+
IncrementalFragment(decls, comments, err_opt)
603+
604+
| Fragment _ ->
605+
Term (MenhirLib.Convert.Simplified.traditional2revised FStarC_Parser_Parse.term lexer)
606+
with
607+
| FStarC_Errors.Empty_frag ->
608+
ASTFragment (FStar_Pervasives.Inr [], [])
609+
539610
| FStarC_Errors.Error(e, msg, r, _ctx) ->
540611
ParseError (e, msg, r)
541612

613+
| e ->
614+
(*
615+
| Parsing.Parse_error as _e
616+
| FStarC_Parser_Parse.MenhirBasics.Error as _e ->
617+
*)
618+
ParseError (err_of_parse_error filename lexbuf None)
619+
620+
542621
let parse (lang_opt:lang_opts) fn =
543622
FStarC_Stats.record "parse" @@ fun () ->
544623
FStarC_Parser_Util.warningHandler := (function
545624
| e -> Printf.printf "There was some warning (TODO)\n");
546-
match lang_opt with
547-
| Some lang -> parse_lang lang fn
548-
| _ ->
549-
let lexbuf, filename, contents =
550-
match fn with
551-
| Filename f ->
552-
check_extension f;
553-
let f', contents = read_file f in
554-
(try create contents f' 1 0, f', contents
555-
with _ -> raise_error_text FStarC_Range.dummyRange Fatal_InvalidUTF8Encoding (FStarC_Format.fmt1 "File %s has invalid UTF-8 encoding." f'))
556-
| Incremental s
557-
| Toplevel s
558-
| Fragment s ->
559-
create s.frag_text s.frag_fname (Z.to_int s.frag_line) (Z.to_int s.frag_col), "<input>", s.frag_text
560-
in
561-
562-
let lexer () =
563-
let tok = FStarC_Parser_LexFStar.token lexbuf in
564-
if !dbg_Tokens then
565-
print_string ("TOKEN: " ^ (string_of_token tok) ^ "\n");
566-
(tok, lexbuf.start_p, lexbuf.cur_p)
567-
in
568-
try
569-
match fn with
570-
| Filename _
571-
| Toplevel _ -> begin
572-
let fileOrFragment =
573-
MenhirLib.Convert.Simplified.traditional2revised FStarC_Parser_Parse.inputFragment lexer
574-
in
575-
let frags = match fileOrFragment with
576-
| FStar_Pervasives.Inl modul ->
577-
if has_extension filename interface_extensions
578-
then FStar_Pervasives.Inl (FStarC_Parser_AST.as_interface modul)
579-
else FStar_Pervasives.Inl modul
580-
| _ -> fileOrFragment
581-
in ASTFragment (frags, FStarC_Parser_Util.flush_comments ())
582-
end
583-
584-
| Incremental i ->
585-
let decls, comments, err_opt =
586-
parse_incremental_fragment
587-
filename
588-
i.frag_text
589-
lexbuf
590-
lexer
591-
(fun (d:FStarC_Parser_AST.decl) -> d.drange)
592-
FStarC_Parser_Parse.oneDeclOrEOF
593-
in
594-
IncrementalFragment(decls, comments, err_opt)
595-
596-
| Fragment _ ->
597-
Term (MenhirLib.Convert.Simplified.traditional2revised FStarC_Parser_Parse.term lexer)
598-
with
599-
| FStarC_Errors.Empty_frag ->
600-
ASTFragment (FStar_Pervasives.Inr [], [])
601-
602-
| FStarC_Errors.Error(e, msg, r, _ctx) ->
603-
ParseError (e, msg, r)
604-
605-
| e ->
606-
(*
607-
| Parsing.Parse_error as _e
608-
| FStarC_Parser_Parse.MenhirBasics.Error as _e ->
609-
*)
610-
ParseError (err_of_parse_error filename lexbuf None)
625+
match lang_opt, fn with
626+
| Some lang, _ -> parse_lang lang fn
627+
| None, Filename fn' -> begin
628+
match take_lang_extension fn' with
629+
| Some lang -> parse_lang lang fn
630+
| None -> parse_no_lang fn
631+
end
632+
| None, Toplevel fn' -> begin
633+
match take_lang_extension fn'.frag_fname with
634+
| Some lang -> parse_lang lang fn
635+
| None -> parse_no_lang fn
636+
end
637+
| _, _ -> parse_no_lang fn
611638

612639

613640
(** Parsing of command-line error/warning/silent flags. *)

src/parser/FStarC.Parser.Dep.fst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,20 @@ let files_for_module_name_to_string (m:files_for_module_name) =
8787

8888
type color = | White | Gray | Black
8989

90+
let all_file_suffixes () =
91+
let lang_exts = List.map (fun ext -> "." ^ ext) (FStarC.Options.lang_extensions ()) in
92+
let base = ".fst" :: lang_exts in
93+
base @ List.map (fun ext -> ext ^ "i") base
94+
9095
let check_and_strip_suffix (f: string): option string =
91-
let suffixes = [ ".fsti"; ".fst" ] in
9296
let matches = List.map (fun ext ->
9397
let lext = String.length ext in
9498
let l = String.length f in
9599
if l > lext && String.substring f (l - lext) lext = ext then
96100
Some (String.substring f 0 (l - lext))
97101
else
98102
None
99-
) suffixes in
103+
) (all_file_suffixes ()) in
100104
match List.filter Some? matches with
101105
| Some m :: _ ->
102106
Some m
@@ -1442,7 +1446,7 @@ let all_files_in_include_paths () =
14421446
List.collect
14431447
(fun path ->
14441448
let files = safe_readdir_for_include path in
1445-
let files = List.filter (fun f -> Util.ends_with f ".fst" || Util.ends_with f ".fsti") files in
1449+
let files = List.filter (fun f -> List.existsb (fun ext -> Util.ends_with f ext) (all_file_suffixes ())) files in
14461450
List.map (fun file -> Filepath.join_paths path file) files)
14471451
paths
14481452

src/syntax/FStarC.Syntax.DsEnv.fst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,6 @@ let inclusion_info env (l:lident) =
16141614

16151615
let prepare_module_or_interface intf admitted env mname (mii:module_inclusion_info) = (* AR: open the pervasives namespace *)
16161616
let prep env =
1617-
let filename = BU.strcat (string_of_lid mname) ".fst" in
16181617
let auto_open = if mii.mii_no_prelude then [] else FStarC.Parser.Dep.prelude in
16191618
let auto_open =
16201619
let convert_kind = function

0 commit comments

Comments
 (0)