Skip to content

Commit 80f7916

Browse files
committed
Allow other formats for singleton input (tweag#1901)
Guess input format based on extension similarly like in multiple input case.
1 parent efbe86b commit 80f7916

File tree

13 files changed

+39
-55
lines changed

13 files changed

+39
-55
lines changed

core/benches/arrays.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::rc::Rc;
22

33
use criterion::{criterion_main, Criterion};
4+
use nickel_lang_core::cache::InputFormat;
45
use nickel_lang_core::term::{
56
array::{Array, ArrayAttrs},
67
Number, RichTerm, Term,

core/benches/functions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use criterion::{criterion_main, Criterion};
2+
use nickel_lang_core::cache::InputFormat;
23
use nickel_lang_utils::ncl_bench_group;
34
use pprof::criterion::{Output, PProfProfiler};
45

core/benches/mantis.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use criterion::{criterion_main, Criterion};
2+
use nickel_lang_core::cache::InputFormat;
23
use nickel_lang_utils::{bench::EvalMode, ncl_bench_group};
34
use pprof::criterion::{Output, PProfProfiler};
45

core/benches/numeric.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use criterion::{criterion_main, Criterion};
2+
use nickel_lang_core::cache::InputFormat;
23
use nickel_lang_utils::ncl_bench_group;
34
use pprof::criterion::{Output, PProfProfiler};
45

core/benches/records.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use criterion::{criterion_main, Criterion};
2+
use nickel_lang_core::cache::InputFormat;
23
use nickel_lang_utils::{bench::EvalMode, ncl_bench_group};
34
use pprof::criterion::{Output, PProfProfiler};
45

core/benches/serialization.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use criterion::{criterion_main, Criterion};
2+
use nickel_lang_core::cache::InputFormat;
23
use nickel_lang_utils::ncl_bench_group;
34
use pprof::criterion::{Output, PProfProfiler};
45

core/benches/typecheck-nixpkgs-lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use criterion::{criterion_main, Criterion};
2+
use nickel_lang_core::cache::InputFormat;
23
use nickel_lang_utils::{bench::EvalMode, ncl_bench_group};
34
use pprof::criterion::{Output, PProfProfiler};
45

core/src/cache.rs

Lines changed: 19 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ impl InputFormat {
5858
_ => None,
5959
}
6060
}
61+
/// Renturns an [InputFormat] based on the extension of a source path.
62+
pub fn from_source_path(source_path: &SourcePath) -> Option<InputFormat> {
63+
if let SourcePath::Path(p) = source_path {
64+
Self::from_path(p)
65+
} else {
66+
None
67+
}
68+
}
6169
}
6270

6371
/// File and terms cache.
@@ -456,50 +464,10 @@ impl Cache {
456464
}
457465
}
458466

459-
/// Parse a source and populate the corresponding entry in the cache, or do nothing if the
460-
/// entry has already been parsed. This function is error tolerant: parts of the source which
461-
/// result in parse errors are parsed as [`crate::term::Term::ParseError`] and the
462-
/// corresponding error messages are collected and returned.
463-
///
464-
/// The `Err` part of the result corresponds to non-recoverable errors.
465-
fn parse_lax(&mut self, file_id: FileId) -> Result<CacheOp<ParseErrors>, ParseError> {
466-
if let Some(TermEntry { parse_errs, .. }) = self.terms.get(&file_id) {
467-
Ok(CacheOp::Cached(parse_errs.clone()))
468-
} else {
469-
let (term, parse_errs) = self.parse_nocache(file_id)?;
470-
self.terms.insert(
471-
file_id,
472-
TermEntry {
473-
term,
474-
state: EntryState::Parsed,
475-
parse_errs: parse_errs.clone(),
476-
},
477-
);
478-
479-
Ok(CacheOp::Done(parse_errs))
480-
}
481-
}
482-
483-
/// Parse a source and populate the corresponding entry in the cache, or do
484-
/// nothing if the entry has already been parsed. This function is error
485-
/// tolerant if `self.error_tolerant` is `true`.
486-
pub fn parse(&mut self, file_id: FileId) -> Result<CacheOp<ParseErrors>, ParseErrors> {
487-
let result = self.parse_lax(file_id);
488-
489-
match self.error_tolerance {
490-
ErrorTolerance::Tolerant => result.map_err(|err| err.into()),
491-
ErrorTolerance::Strict => match result? {
492-
CacheOp::Done(e) | CacheOp::Cached(e) if !e.no_errors() => Err(e),
493-
CacheOp::Done(_) => Ok(CacheOp::Done(ParseErrors::none())),
494-
CacheOp::Cached(_) => Ok(CacheOp::Cached(ParseErrors::none())),
495-
},
496-
}
497-
}
498-
499467
/// Parse a source and populate the corresponding entry in the cache, or do
500468
/// nothing if the entry has already been parsed. Support multiple formats.
501469
/// This function is always error tolerant, independently from `self.error_tolerant`.
502-
fn parse_multi_lax(
470+
fn parse_lax(
503471
&mut self,
504472
file_id: FileId,
505473
format: InputFormat,
@@ -523,12 +491,12 @@ impl Cache {
523491
/// Parse a source and populate the corresponding entry in the cache, or do
524492
/// nothing if the entry has already been parsed. Support multiple formats.
525493
/// This function is error tolerant if `self.error_tolerant` is `true`.
526-
pub fn parse_multi(
494+
pub fn parse(
527495
&mut self,
528496
file_id: FileId,
529497
format: InputFormat,
530498
) -> Result<CacheOp<ParseErrors>, ParseErrors> {
531-
let result = self.parse_multi_lax(file_id, format);
499+
let result = self.parse_lax(file_id, format);
532500

533501
match self.error_tolerance {
534502
ErrorTolerance::Tolerant => result.map_err(|err| err.into()),
@@ -902,7 +870,12 @@ impl Cache {
902870
) -> Result<CacheOp<()>, Error> {
903871
let mut result = CacheOp::Cached(());
904872

905-
if let CacheOp::Done(_) = self.parse(file_id)? {
873+
let format = self
874+
.file_paths
875+
.get(&file_id)
876+
.and_then(|source_path| InputFormat::from_source_path(source_path))
877+
.unwrap_or_default();
878+
if let CacheOp::Done(_) = self.parse(file_id, format)? {
906879
result = CacheOp::Done(());
907880
}
908881

@@ -1134,7 +1107,7 @@ impl Cache {
11341107
.collect();
11351108

11361109
for (_, file_id) in file_ids.iter() {
1137-
self.parse(*file_id)?;
1110+
self.parse(*file_id, InputFormat::Nickel)?;
11381111
}
11391112
self.stdlib_ids.replace(file_ids);
11401113
Ok(CacheOp::Done(()))
@@ -1371,7 +1344,7 @@ impl ImportResolver for Cache {
13711344
self.rev_imports.entry(file_id).or_default().insert(parent);
13721345
}
13731346

1374-
self.parse_multi(file_id, format)
1347+
self.parse(file_id, format)
13751348
.map_err(|err| ImportError::ParseErrors(err, *pos))?;
13761349

13771350
Ok((result, file_id))

core/src/program.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ impl<EC: EvalCache> Program<EC> {
312312
pub fn parse(&mut self) -> Result<RichTerm, Error> {
313313
self.vm
314314
.import_resolver_mut()
315-
.parse(self.main_id)
315+
.parse(self.main_id, InputFormat::Nickel)
316316
.map_err(Error::ParseErrors)?;
317317
Ok(self
318318
.vm
@@ -437,7 +437,9 @@ impl<EC: EvalCache> Program<EC> {
437437

438438
/// Load, parse, and typecheck the program and the standard library, if not already done.
439439
pub fn typecheck(&mut self) -> Result<(), Error> {
440-
self.vm.import_resolver_mut().parse(self.main_id)?;
440+
self.vm
441+
.import_resolver_mut()
442+
.parse(self.main_id, InputFormat::Nickel)?;
441443
self.vm.import_resolver_mut().load_stdlib()?;
442444
let initial_env = self.vm.import_resolver().mk_type_ctxt().expect(
443445
"program::typecheck(): \

core/src/repl/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//! Dually, the frontend is the user-facing part, which may be a CLI, a web application, a
77
//! jupyter-kernel (which is not exactly user-facing, but still manages input/output and
88
//! formatting), etc.
9-
use crate::cache::{Cache, Envs, ErrorTolerance, SourcePath};
9+
use crate::cache::{Cache, Envs, ErrorTolerance, InputFormat, SourcePath};
1010
use crate::error::{
1111
report::{self, ColorOpt, ErrorFormat},
1212
Error, EvalError, IOError, IntoDiagnostics, ParseError, ParseErrors, ReplError,
@@ -232,7 +232,9 @@ impl<EC: EvalCache> Repl for ReplImpl<EC> {
232232
.import_resolver_mut()
233233
.add_file(OsString::from(path.as_ref()))
234234
.map_err(IOError::from)?;
235-
self.vm.import_resolver_mut().parse(file_id)?;
235+
self.vm
236+
.import_resolver_mut()
237+
.parse(file_id, InputFormat::Nickel)?;
236238

237239
let term = self.vm.import_resolver().get_owned(file_id).unwrap();
238240
let pos = term.pos;

0 commit comments

Comments
 (0)