wam: &mut Machine,
stream: ParsingStream<R>,
suppress_warnings: bool,
+ listing_src: ClauseName,
) -> Result<Option<ClauseName>, SessionError> {
// follow the operation of compile_user_module, but before
// compiling, check that a module is declared in the file. if not,
// throw an exception.
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
setup_indices(wam, clause_name!("builtins"), &mut indices)?;
+
+ let mut compiler = ListingCompiler::new(
+ &wam.code_repo,
+ suppress_warnings,
+ listing_src,
+ );
- let mut compiler = ListingCompiler::new(&wam.code_repo, suppress_warnings);
- let results = compiler.gather_items(wam, stream, &mut indices)?;
-
+ let results = compiler.gather_items(wam, stream, &mut indices);
+
let module_name = if let Some(ref module) = &compiler.module {
Some(module.module_decl.name.clone())
} else {
None
};
- match compile_work_impl(&mut compiler, wam, indices, results) {
- EvalSession::Error(e) => Err(e),
- _ => Ok(module_name),
- }
+ results.and_then(|results| compile_work_impl(&mut compiler, wam, indices, results))
+ .or_else(|e| {
+ compiler.print_error(&e);
+ Err(e)
+ })?;
+
+ Ok(module_name)
}
pub(super)
suppress_warnings: bool,
) -> Result<Option<ClauseName>, SessionError> {
let path = fix_filename(wam.indices.atom_tbl.clone(), filename)?;
+ let filename = clause_name!(path.to_string_lossy().to_string(), wam.indices.atom_tbl);
let file_handle = File::open(&path).or_else(|_| {
- let filename = clause_name!(path.to_string_lossy().to_string(), wam.indices.atom_tbl);
- Err(SessionError::InvalidFileName(filename))
+ Err(SessionError::InvalidFileName(filename.clone()))
})?;
- load_module(wam, parsing_stream(file_handle), suppress_warnings)
+ load_module(wam, parsing_stream(file_handle), suppress_warnings, filename)
}
pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
}
fn issue_singleton_warnings(
- module_name: ClauseName,
+ src_name: ClauseName,
terms_and_locs: Vec<(Term, usize, usize)>,
) {
for (term, line_num, _col_num) in terms_and_locs {
*entry += 1;
}
}
-
+
for (var, count) in var_count {
if count == 1 && !var.starts_with("_") && var.as_str() != "!" {
singletons.push(var);
if let Some(last_var) = singletons.pop() {
print!("Warning: {}:{}: Singleton variables: [",
- module_name, line_num);
-
+ src_name, line_num);
+
for var in singletons {
print!("{}, ", var);
}
-
+
println!("{}]", last_var);
}
}
}
}
TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => {
- let mut compiler = ListingCompiler::new(&wam.code_repo, false);
+ let mut compiler = ListingCompiler::new(&wam.code_repo, false, clause_name!("user"));
let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl));
try_eval_session!(wam.check_toplevel_code(&indices));
let mut indices = default_index_store!(wam.atom_tbl_of(&name));
try_eval_session!(setup_indices(wam, module_name.clone(), &mut indices));
- let mut compiler = ListingCompiler::new(&wam.code_repo, true);
+ let mut compiler = ListingCompiler::new(&wam.code_repo, true, module_name.clone());
match compile_into_module_impl(wam, &mut compiler, module_name, src, indices) {
Ok(()) => EvalSession::EntrySuccess,
orig_term_expansion_lens: (usize, usize),
orig_goal_expansion_lens: (usize, usize),
initialization_goals: (Vec<QueryTerm>, VecDeque<TopLevel>),
- suppress_warnings: bool
+ suppress_warnings: bool,
+ listing_src: ClauseName // a file? a module?
}
fn add_toplevel_code(wam: &mut Machine, code: Code, mut indices: IndexStore) {
) -> Result<ClauseName, SessionError> {
match LIBRARIES.borrow().get(name.as_str()) {
Some(code) => {
- let module_name = load_module(wam, parsing_stream(code.as_bytes()), suppress_warnings)?;
+ let module_name = load_module(wam, parsing_stream(code.as_bytes()),
+ suppress_warnings, name.clone())?;
module_name.ok_or(SessionError::NoModuleDeclaration(name))
}
None => Err(SessionError::ModuleNotFound)
impl ListingCompiler {
#[inline]
- pub fn new(code_repo: &CodeRepo, suppress_warnings: bool) -> Self {
+ pub fn new(
+ code_repo: &CodeRepo,
+ suppress_warnings: bool,
+ listing_src: ClauseName,
+ ) -> Self {
ListingCompiler {
non_counted_bt_preds: IndexSet::new(),
module: None,
orig_goal_expansion_lens: code_repo
.term_dir_entry_len((clause_name!("goal_expansion"), 2)),
initialization_goals: (vec![], VecDeque::from(vec![])),
- suppress_warnings
+ suppress_warnings,
+ listing_src
}
}
discard_result!(code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags));
discard_result!(code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags));
}
+
+ fn print_error(&self, e: &SessionError) {
+ if let &SessionError::ParserError(ref e) = e {
+ if let Some((line_num, _col_num)) = e.line_and_col_num() {
+ println!("{}:{}: {}", self.listing_src, line_num, e.as_str());
+ }
+ }
+ }
}
fn compile_work_impl(
wam: &mut Machine,
mut indices: IndexStore,
mut results: GatherResult,
-) -> EvalSession {
- let module_code = try_eval_session!(compiler.generate_code(
+) -> Result<(), SessionError> {
+ let module_code = compiler.generate_code(
results.worker_results,
wam,
&mut indices.code_dir,
0
- ));
- let toplvl_code = try_eval_session!(compiler.generate_code(
+ )?;
+ let toplvl_code = compiler.generate_code(
results.toplevel_results,
wam,
&mut results.toplevel_indices.code_dir,
module_code.len()
- ));
+ )?;
if let Some(ref mut module) = &mut compiler.module {
module.user_term_expansions = results.addition_results.take_term_expansions();
let flags = wam.machine_flags();
- try_eval_session!(wam
- .code_repo
- .compile_hook(CompileTimeHook::UserTermExpansion, flags));
- try_eval_session!(wam
- .code_repo
- .compile_hook(CompileTimeHook::UserGoalExpansion, flags));
+ wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags)?;
+ wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags)?;
if let Some(module) = compiler.module.take() {
let mut clause_code_generator =
ClauseCodeGenerator::new(module_code.len() + toplvl_code.len(),
module.module_decl.name.clone());
- try_eval_session!(wam.check_toplevel_code(&results.toplevel_indices));
- try_eval_session!(
- clause_code_generator.generate_clause_code(&results.dynamic_clause_map, wam)
- );
+ wam.check_toplevel_code(&results.toplevel_indices)?;
+ clause_code_generator.generate_clause_code(&results.dynamic_clause_map, wam)?;
add_module_code(wam, module, module_code, indices);
add_toplevel_code(wam, toplvl_code, results.toplevel_indices);
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
} else {
- try_eval_session!(add_non_module_code(
+ add_non_module_code(
wam,
results.dynamic_clause_map,
module_code,
indices
- ));
+ )?;
}
- let init_goal_code = try_eval_session!(compiler.generate_init_goal_code(
+ let init_goal_code = compiler.generate_init_goal_code(
wam.machine_flags()
- ));
+ )?;
if init_goal_code.len() > 0 {
wam.run_init_code(init_goal_code);
}
if !compiler.suppress_warnings {
- issue_singleton_warnings(compiler.get_module_name(), results.top_level_terms);
+ issue_singleton_warnings(
+ compiler.listing_src.clone(),
+ results.top_level_terms,
+ );
}
-
- EvalSession::EntrySuccess
+
+ Ok(())
}
fn compile_work<R: Read>(
mut indices: IndexStore,
) -> EvalSession {
let results = try_eval_session!(compiler.gather_items(wam, src, &mut indices));
- compile_work_impl(compiler, wam, indices, results)
+ try_eval_session!(compile_work_impl(compiler, wam, indices, results));
+ EvalSession::EntrySuccess
}
/* This is a truncated version of compile_user_module, used for
pub fn compile_special_form<R: Read>(
wam: &mut Machine,
src: ParsingStream<R>,
+ listing_src: ClauseName,
) -> Result<Code, SessionError> {
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
setup_indices(wam, clause_name!("builtins"), &mut indices)?;
- let mut compiler = ListingCompiler::new(&wam.code_repo, true);
+ let mut compiler = ListingCompiler::new(&wam.code_repo, true, listing_src);
let results = compiler.gather_items(wam, src, &mut indices)?;
compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)
wam: &mut Machine,
src: ParsingStream<R>,
indices: IndexStore,
- suppress_warnings: bool
+ suppress_warnings: bool,
+ listing_src: ClauseName,
) -> EvalSession {
- let mut compiler = ListingCompiler::new(&wam.code_repo, suppress_warnings);
+ let mut compiler = ListingCompiler::new(&wam.code_repo, suppress_warnings, listing_src);
match compile_work(&mut compiler, wam, src, indices) {
EvalSession::Error(e) => {
compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo);
+ compiler.print_error(&e);
+
EvalSession::Error(e)
}
result => result,
wam: &mut Machine,
src: ParsingStream<R>,
suppress_warnings: bool,
+ listing_src: ClauseName,
) -> EvalSession {
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
try_eval_session!(setup_indices(wam, clause_name!("builtins"), &mut indices));
- compile_listing(wam, src, indices, suppress_warnings)
+ compile_listing(wam, src, indices, suppress_warnings, listing_src)
}
impl Machine {
fn compile_special_forms(&mut self) {
- match compile_special_form(self, parsing_stream(VERIFY_ATTRS.as_bytes())) {
+ let verify_attrs_src = clause_name!("verify_attrs.pl");
+ let project_attrs_src = clause_name!("project_attributes.pl");
+
+ match compile_special_form(self, parsing_stream(VERIFY_ATTRS.as_bytes()), verify_attrs_src)
+ {
Ok(code) => {
self.machine_st.attr_var_init.verify_attrs_loc = self.code_repo.code.len();
self.code_repo.code.extend(code.into_iter());
Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"),
}
- match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes())) {
+ match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes()), project_attrs_src)
+ {
Ok(code) => {
self.machine_st.attr_var_init.project_attrs_loc = self.code_repo.code.len();
self.code_repo.code.extend(code.into_iter());
fn compile_top_level(&mut self) {
self.toplevel_idx = self.code_repo.code.len();
- compile_user_module(self, parsing_stream(TOPLEVEL.as_bytes()), true);
+ compile_user_module(self, parsing_stream(TOPLEVEL.as_bytes()),
+ true, clause_name!("toplevel.pl"));
}
fn compile_scryerrc(&mut self) {
Err(_) => return,
};
- compile_user_module(self, file_src, true);
+ compile_user_module(self, file_src, true,
+ clause_name!("$HOME/.scryerrc"));
}
}
pub fn run_init_code(&mut self, code: Code) {
let old_machine_st = self.machine_st.sink_to_snapshot();
self.machine_st.reset();
-
+
self.code_repo.cached_query = code;
self.run_query(&AllocVarDict::new());
&mut wam,
parsing_stream(BUILTINS.as_bytes()),
default_index_store!(atom_tbl.clone()),
- true
+ true,
+ clause_name!("builtins.pl"),
);
wam.compile_special_forms();
- compile_user_module(&mut wam, parsing_stream(ERROR.as_bytes()), true);
- compile_user_module(&mut wam, parsing_stream(LISTS.as_bytes()), true);
- compile_user_module(&mut wam, parsing_stream(NON_ISO.as_bytes()), true);
- compile_user_module(&mut wam, parsing_stream(SI.as_bytes()), true);
-
+ compile_user_module(&mut wam, parsing_stream(ERROR.as_bytes()), true,
+ clause_name!("error"));
+ compile_user_module(&mut wam, parsing_stream(LISTS.as_bytes()), true,
+ clause_name!("lists"));
+ compile_user_module(&mut wam, parsing_stream(NON_ISO.as_bytes()), true,
+ clause_name!("non_iso"));
+ compile_user_module(&mut wam, parsing_stream(SI.as_bytes()), true,
+ clause_name!("si"));
+
wam.compile_top_level();
wam.compile_scryerrc();
}
}
- pub fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
+ fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
let h = self.machine_st.heap.h;
-
+
let err = MachineError::session_error(h, err);
let stub = MachineError::functor_stub(key.0, key.1);
let err = self.machine_st.error_form(err, stub);
self.indices.remove_module(clause_name!("user"), &module);
self.indices.use_module(&mut self.code_repo, self.machine_st.flags,
&module)?;
-
+
Ok(self.indices.insert_module(module))
} else {
Ok(())
}
- );
-
+ );
+
self.code_repo.cached_query = cached_query;
if let Err(e) = result {
self.machine_st.flags,
&module,
&exports)?;
-
+
Ok(self.indices.insert_module(module))
} else {
Ok(())
fn handle_toplevel_command(&mut self, code_ptr: REPLCodePtr, p: LocalCodePtr) {
match code_ptr {
REPLCodePtr::CompileBatch => {
+ let user_src = clause_name!("user");
+
let src = readline::input_stream();
readline::set_prompt(false);
- if let EvalSession::Error(e) = compile_user_module(self, src, false) {
+ if let EvalSession::Error(e) = compile_user_module(self, src, false, user_src) {
self.throw_session_error(e, (clause_name!("repl"), 0));
}
}
raw_stdout.flush().unwrap();
next_keypress()
};
-
+
let result = match keypress {
ContinueResult::ContinueQuery => {
print!(" ;\r\n");
self.machine_st.absorb_snapshot(snapshot);
}
-
+
pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) {
self.machine_st.cp = LocalCodePtr::TopLevel(0, self.code_repo.size_of_cached_query());
let end_ptr = CodePtr::Local(self.machine_st.cp);