Skip to content

Commit

Permalink
feat(compiler)!: Require extension for included local files
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-snezhko committed Feb 24, 2024
1 parent 5f44d4e commit 3c65bbd
Show file tree
Hide file tree
Showing 380 changed files with 2,025 additions and 1,988 deletions.
8 changes: 4 additions & 4 deletions compiler/src/codegen/compcore.re
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,26 @@ let reloc_base = Ident.create_persistent("relocBase");
let table_size = Ident.create_persistent("GRAIN$TABLE_SIZE");

/* Memory allocation */
let malloc_mod = "GRAIN$MODULE$runtime/malloc";
let malloc_mod = "GRAIN$MODULE$runtime/malloc.gr";
let malloc_ident = Ident.create_persistent("malloc");
let malloc_closure_ident = Ident.create_persistent("GRAIN$EXPORT$malloc");

/* Garbage collection */
let gc_mod = "GRAIN$MODULE$runtime/gc";
let gc_mod = "GRAIN$MODULE$runtime/gc.gr";
let incref_ident = Ident.create_persistent("incRef");
let incref_closure_ident = Ident.create_persistent("GRAIN$EXPORT$incRef");
let decref_ident = Ident.create_persistent("decRef");
let decref_closure_ident = Ident.create_persistent("GRAIN$EXPORT$decRef");

/* Exceptions */
let exception_mod = "GRAIN$MODULE$runtime/exception";
let exception_mod = "GRAIN$MODULE$runtime/exception.gr";
let panic_with_exception_ident =
Ident.create_persistent("panicWithException");
let panic_with_exception_closure_ident =
Ident.create_persistent("GRAIN$EXPORT$panicWithException");

/* Equality checking */
let equal_mod = "GRAIN$MODULE$runtime/equal";
let equal_mod = "GRAIN$MODULE$runtime/equal.gr";
let equal_ident = Ident.create_persistent("equal");
let equal_closure_ident = Ident.create_persistent("GRAIN$EXPORT$equal");

Expand Down
3 changes: 1 addition & 2 deletions compiler/src/compile.re
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ type error =

exception InlineFlagsError(Location.t, error);

let default_output_filename = name =>
Filepath.String.remove_extension(name) ++ ".gr.wasm";
let default_output_filename = name => name ++ ".wasm";

let default_mashtree_filename = name =>
Filepath.String.remove_extension(name) ++ ".mashtree";
Expand Down
9 changes: 8 additions & 1 deletion compiler/src/formatting/fmt.re
Original file line number Diff line number Diff line change
Expand Up @@ -3214,6 +3214,13 @@ let print_primitive_description = (fmt, {pprim_ident, pprim_name, pprim_loc}) =>

let print_include_declaration =
(fmt, {pinc_path, pinc_module, pinc_alias, pinc_loc}) => {
open Filepath.String;
let path =
if (!is_relpath(pinc_path.txt) && check_suffix(pinc_path.txt, ".gr")) {
chop_suffix(pinc_path.txt, ".gr");
} else {
pinc_path.txt;
};
string("from")
++ fmt.print_comment_range(
fmt,
Expand All @@ -3224,7 +3231,7 @@ let print_include_declaration =
enclosing_start_location(pinc_loc),
pinc_path.loc,
)
++ double_quotes(string(pinc_path.txt))
++ double_quotes(string(path))
++ fmt.print_comment_range(
fmt,
~allow_breaks=false,
Expand Down
6 changes: 2 additions & 4 deletions compiler/src/linking/link.re
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ let is_grain_module = mod_name => {
Str.string_match(Str.regexp_string("GRAIN$MODULE$"), mod_name, 0);
};

let wasi_polyfill_module = () => {
Filepath.String.remove_extension(Option.get(Config.wasi_polyfill_path()))
++ ".gr.wasm";
};
let wasi_polyfill_module = () =>
Option.get(Config.wasi_polyfill_path()) ++ ".wasm";

let is_wasi_module = mod_name => {
mod_name == "wasi_snapshot_preview1";
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/middle_end/analyze_inline_wasm.re
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ let analyze = ({imports, body, analyses}) => {
mod_has_inlineable_wasm := false;
let process_import = ({imp_use_id, imp_desc}) => {
switch (imp_desc) {
| GrainValue("runtime/unsafe/memory", name) =>
| GrainValue("runtime/unsafe/memory.gr", name) =>
mod_has_inlineable_wasm := true;
switch (get_primitive_memory(name)) {
| Some(prim) => set_inlineable_wasm(imp_use_id, prim)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ let analyze = ({imports, body, analyses}) => {
mod_has_manual_memory_management := false;
let process_import = ({imp_use_id, imp_desc}) => {
switch (imp_desc) {
| GrainValue("runtime/unsafe/memory", "incRef" | "decRef") =>
| GrainValue("runtime/unsafe/memory.gr", "incRef" | "decRef") =>
mod_has_manual_memory_management := true;
set_manual_call(imp_use_id);
| GrainValue(_)
Expand Down
15 changes: 9 additions & 6 deletions compiler/src/parsing/ast_helper.re
Original file line number Diff line number Diff line change
Expand Up @@ -473,12 +473,15 @@ module MatchBranch = {

module IncludeDeclaration = {
let mk = (~loc, path, module_, alias) => {
{
pinc_alias: alias,
pinc_module: module_,
pinc_path: normalize_string(~loc, path),
pinc_loc: loc,
};
let path = normalize_string(~loc, path);
let filename =
if (!Grain_utils.Filepath.String.is_relpath(path.txt)) {
path.txt ++ ".gr";
} else {
path.txt;
};
let path = {txt: filename, loc: path.loc};
{pinc_alias: alias, pinc_module: module_, pinc_path: path, pinc_loc: loc};
};
};

Expand Down
5 changes: 3 additions & 2 deletions compiler/src/parsing/driver.re
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,9 @@ let read_imports = (program: Parsetree.parsed_program) => {
List.map(
o => {
switch (o) {
| Grain_utils.Config.Pervasives_mod => Location.mknoloc("pervasives")
| Grain_utils.Config.Gc_mod => Location.mknoloc("runtime/gc")
| Grain_utils.Config.Pervasives_mod =>
Location.mknoloc("pervasives.gr")
| Grain_utils.Config.Gc_mod => Location.mknoloc("runtime/gc.gr")
}
},
switch (program.comments) {
Expand Down
7 changes: 6 additions & 1 deletion compiler/src/typed/env.re
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,12 @@ let check_consistency = ps =>
~base_dir=Filepath.String.dirname(ps.ps_filename),
name,
);
Consistbl.check(crc_units, resolved_file_name, crc, ps.ps_filename);
Consistbl.check(
crc_units,
Filepath.String.chop_suffix(resolved_file_name, ".gr"),
crc,
ps.ps_filename,
);
},
ps.ps_crcs,
)
Expand Down
128 changes: 72 additions & 56 deletions compiler/src/typed/module_resolution.re
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@ let read_file_cmi = f => {
};
};

let get_output_name = name => {
Filepath.String.remove_extension(name) ++ ".gr.wasm";
};
let get_output_name = name => name ++ ".wasm";

let find_ext_in_dir = (dir, name) => {
let fullname = Filepath.String.concat(dir, name);
let rec process_ext =
fun
| [] => None
| [ext, ..._] when file_exists(fullname ++ ext) =>
Some((fullname ++ ext, dir, name, ext))
Some((fullname ++ ext, dir, name))
| [_, ...tl] => process_ext(tl);
process_ext;
};

let find_in_path_uncap = (~exts=[], base_dir, path, name) => {
let find_in_path_uncap =
(~check_src=false, ~check_wasm=false, base_dir, path, name) => {
let exts = (check_src ? [""] : []) @ (check_wasm ? [".wasm"] : []);
let rec try_dir =
fun
| [] => raise(Not_found)
Expand All @@ -75,12 +75,7 @@ let find_in_path_uncap = (~exts=[], base_dir, path, name) => {
};
};
if (!Filepath.String.is_relative(name) && Fs_access.file_exists(name)) {
(
name,
Filepath.String.dirname(name),
Filepath.String.(remove_extension(basename(name))),
Filepath.String.extension(name),
);
(name, Filepath.String.dirname(name), Filepath.String.basename(name));
} else if (Filepath.String.is_relpath(name)) {
try_dir([base_dir]);
} else {
Expand Down Expand Up @@ -177,9 +172,14 @@ let resolve_unit = (~search_path=?, ~cache=true, ~base_dir=?, unit_name) => {
) {
| (true, Some(res)) => res
| _ =>
let exts = [".gr", ".gr.wasm"];
let (_, dir, basename, _) =
find_in_path_uncap(~exts, base_dir, path, unit_name);
let (_, dir, basename) =
find_in_path_uncap(
~check_src=true,
~check_wasm=true,
base_dir,
path,
unit_name,
);
if (cache) {
log_resolution(unit_name, dir, basename);
} else {
Expand All @@ -202,30 +202,65 @@ let locate_module = (~disable_relpath=false, base_dir, path, unit_name) => {
) {
| Some(m) => m
| None =>
let grain_src_exts = [".gr"];
let (dir, m) =
switch (
find_in_path_uncap(~exts=[".gr.wasm"], base_dir, path, unit_name)
) {
| (objpath, dir, basename, ext) =>
switch (find_in_path_uncap(~check_wasm=true, base_dir, path, unit_name)) {
| (objpath, dir, basename) =>
ignore(log_resolution(unit_name, dir, basename));
switch (find_ext_in_dir(dir, basename, grain_src_exts)) {
| Some((srcpath, _, _, _)) => (
let file = find_ext_in_dir(dir, basename, [""]);
switch (file) {
| Some((srcpath, _, _)) => (
dir,
GrainModule(srcpath, Some(objpath)),
)
| None => (dir, WasmModule(objpath))
};
| exception Not_found =>
let (srcpath, dir, _, _) =
find_in_path_uncap(~exts=grain_src_exts, base_dir, path, unit_name);
let (srcpath, dir, _) =
find_in_path_uncap(~check_src=true, base_dir, path, unit_name);
(dir, GrainModule(srcpath, None));
};
PathTbl.add(current_located_module_cache(), (dir, unit_name), m);
m;
};
};

let try_locate_module =
(~disable_relpath=false, base_dir, active_search_path, name, loc) => {
let locate = locate_module(~disable_relpath, base_dir, active_search_path);
Filepath.String.(
try(locate(name)) {
| Not_found =>
if (check_suffix(name, ".gr")) {
let no_extension = chop_suffix(name, ".gr");
switch (locate(no_extension)) {
| exception Not_found => error(No_module_file(loc, name, None))
| _ =>
let name = !is_relpath(name) ? no_extension : name;
error(
No_module_file(
loc,
name,
Some("did you forget to remove the .gr extension?"),
),
);
};
} else {
switch (locate(name ++ ".gr")) {
| exception Not_found => error(No_module_file(loc, name, None))
| _ =>
error(
No_module_file(
loc,
name,
Some("did you forget to add the .gr extension?"),
),
)
};
}
}
);
};

type dependency_node = {
// dn_unit_name is a hashtable because we may have a situation
// where A depends on B and C, and both B and C depend on D.
Expand Down Expand Up @@ -281,22 +316,12 @@ module Dependency_graph =
List.map(
name => {
let located =
try(
locate_module(
base_dir,
active_search_path,
name.Location.txt,
)
) {
| Not_found =>
error(
No_module_file(
name.Location.loc,
name.Location.txt,
None,
),
)
};
try_locate_module(
base_dir,
active_search_path,
name.Location.txt,
name.Location.loc,
);
let out_file_name = located_to_out_file_name(located);
let existing_dependency = lookup(out_file_name);
switch (existing_dependency) {
Expand Down Expand Up @@ -331,16 +356,12 @@ module Dependency_graph =
List.map(
((name, _)) => {
let located =
try(locate_module(base_dir, active_search_path, name)) {
| Not_found =>
error(
No_module_file(
Location.in_file(dn.dn_file_name),
name,
None,
),
)
};
try_locate_module(
base_dir,
active_search_path,
name,
Location.in_file(dn.dn_file_name),
);
let out_file_name = located_to_out_file_name(located);
let existing_dependency = lookup(out_file_name);
switch (existing_dependency) {
Expand Down Expand Up @@ -457,19 +478,14 @@ let locate_module_file = (~loc, ~disable_relpath=false, unit_name) => {
let base_dir = Filepath.String.dirname(current_filename^());
let path = Config.module_search_path();
let located =
try(locate_module(~disable_relpath, base_dir, path, unit_name)) {
| Not_found => error(No_module_file(loc, unit_name, None))
};
try_locate_module(~disable_relpath, base_dir, path, unit_name, loc);
located_to_out_file_name(located);
};

let process_dependency = (~loc, ~base_file, unit_name) => {
let base_dir = Filepath.String.dirname(base_file);
let path = Config.module_search_path();
let located =
try(locate_module(~disable_relpath=false, base_dir, path, unit_name)) {
| Not_found => error(No_module_file(loc, unit_name, None))
};
let located = try_locate_module(base_dir, path, unit_name, loc);
let out_file = located_to_out_file_name(located);
let current_dep_node = Dependency_graph.lookup_filename(base_file);
let existing_dependency = Dependency_graph.lookup_filename(out_file);
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/typed/typemod.re
Original file line number Diff line number Diff line change
Expand Up @@ -984,8 +984,8 @@ let register_implicit_modules = modules => {
m => {
let filepath =
switch (m) {
| Grain_utils.Config.Pervasives_mod => "pervasives"
| Grain_utils.Config.Gc_mod => "runtime/gc"
| Grain_utils.Config.Pervasives_mod => "pervasives.gr"
| Grain_utils.Config.Gc_mod => "runtime/gc.gr"
};
Env.add_import(filepath);
},
Expand All @@ -995,7 +995,7 @@ let register_implicit_modules = modules => {

let lookup_implicit_module_spec = m =>
switch (m) {
| Grain_utils.Config.Pervasives_mod => Some(("Pervasives", "pervasives"))
| Grain_utils.Config.Pervasives_mod => Some(("Pervasives", "pervasives.gr"))
| Grain_utils.Config.Gc_mod => None
};

Expand Down
3 changes: 3 additions & 0 deletions compiler/src/utils/filepath.re
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ module String = {
// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
let check_suffix = Filename.check_suffix;

// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
let chop_suffix = Filename.chop_suffix;

// TODO(#216): We should consider switching to type safe Fp.t where ever filepaths are used
let extension = Filename.extension;

Expand Down
Loading

0 comments on commit 3c65bbd

Please sign in to comment.