self.b0 = self.b;
}
+ // Safety: the atom_tbl lives for the lifetime of the machine, as does the helper, so the ptr
+ // will always be valid.
pub fn read_term_from_user_input(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
- let atoms: Vec<_> = self.atom_tbl.table.iter().map(|a| a.as_str().to_string()).collect();
+ let atoms_ptr = (&self.atom_tbl.table) as *const indexmap::IndexSet<Atom>;
if let Stream::Readline(ptr) = stream {
unsafe {
let readline = ptr.as_ptr().as_mut().unwrap();
- readline.set_atoms_for_completion(atoms);
+ readline.set_atoms_for_completion(atoms_ptr);
let ret = self.read_term(stream, indices);
return ret
}
-use rustyline::completion::Completer;
+use indexmap::IndexSet;
+use rustyline::completion::{Completer, Candidate};
use rustyline::hint::Hinter;
use rustyline::validate::Validator;
use rustyline::highlight::{MatchingBracketHighlighter, Highlighter};
use rustyline::{Helper as RlHelper, Result, Context};
-// pub struct Atoms {
-// atoms: *const *const str,
-// len: usize,
-// }
-
-// impl Atoms {
-// pub fn new() -> Self {
-// Self {
-// atoms: std::ptr::null(),
-// len: 0,
-// }
-// }
-// }
-
-// pub struct AtomsIterator<'a> {
-// atoms: &'a Atoms,
-// idx: usize,
-// }
-
-// impl<'a> Iterator for AtomsIterator<'a> {
-// type Item = &'a str;
-
-// fn next(&mut self) -> Option<Self::Item> {
-// self.idx += 1;
-
-// if self.idx == self.atoms.len {
-// None
-// } else {
-// unsafe {
-// let next = self.atoms.atoms.offset(self.idx as isize);
-// (*next).as_ref()
-// }
-// }
-// }
-// }
-
-// impl<'a> IntoIterator for &'a Atoms {
-// type Item = &'a str;
-// type IntoIter = AtomsIterator<'a>;
-
-// fn into_iter(self) -> Self::IntoIter {
-// Self::IntoIter {
-// atoms: self,
-// idx: 0,
-// }
-// }
-// }
+use crate::machine::mock_wam::Atom;
// TODO: Maybe add validation to the helper
pub struct Helper {
highligher: MatchingBracketHighlighter,
- pub atoms: Vec<String>,
+ pub atoms: *const IndexSet<Atom>,
}
impl Helper {
pub fn new() -> Self {
Self {
highligher: MatchingBracketHighlighter::new(),
- atoms: vec![],
+ atoms: std::ptr::null(),
}
}
-
- // pub fn set_atoms(&mut self, atoms_ptr: *const *const str, len: usize) {
- // self.atoms.atoms = atoms_ptr;
- // self.atoms.len = len;
- // }
}
impl RlHelper for Helper {}
start_of_atom
}
+pub struct StrPtr(*const str);
+
+impl Candidate for StrPtr {
+ fn display(&self) -> &str {
+ unsafe {
+ self.0.as_ref().unwrap()
+ }
+ }
+
+ fn replacement(&self) -> &str {
+ unsafe {
+ self.0.as_ref().unwrap()
+ }
+ }
+}
+
impl Completer for Helper {
- type Candidate = String;
+ type Candidate = StrPtr;
fn complete(&self, line: &str, pos: usize, _ctx: &Context<'_>) -> Result<(usize, Vec<Self::Candidate>)> {
let start_of_prefix = get_prefix(line, pos);
if let Some(idx) = start_of_prefix {
let sub_str = line.get(idx..pos).unwrap();
- let matching = self.atoms.iter().filter(|a| a.starts_with(sub_str)).map(|s| s.to_string()).collect();
+ let matching = unsafe {
+ (*self.atoms).iter().filter(|a| a.as_str().starts_with(sub_str)).map(|s| StrPtr(s.as_str())).collect()
+ };
Ok((idx, matching))
} else {
Ok((0, vec![]))