fix: remove unnecessary string & vec allocations
This commit is contained in:
@@ -454,13 +454,15 @@ impl MachineState {
|
|||||||
self.b0 = self.b;
|
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 {
|
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 {
|
if let Stream::Readline(ptr) = stream {
|
||||||
unsafe {
|
unsafe {
|
||||||
let readline = ptr.as_ptr().as_mut().unwrap();
|
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);
|
let ret = self.read_term(stream, indices);
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use crate::types::*;
|
|||||||
|
|
||||||
use fxhash::FxBuildHasher;
|
use fxhash::FxBuildHasher;
|
||||||
|
|
||||||
|
use indexmap::IndexSet;
|
||||||
use rustyline::error::ReadlineError;
|
use rustyline::error::ReadlineError;
|
||||||
use rustyline::{Config, Editor};
|
use rustyline::{Config, Editor};
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ impl ReadlineStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_atoms_for_completion(&mut self, atoms: Vec<String>) {
|
pub fn set_atoms_for_completion(&mut self, atoms: *const IndexSet<Atom>) {
|
||||||
let helper = self.rl.helper_mut().unwrap();
|
let helper = self.rl.helper_mut().unwrap();
|
||||||
helper.atoms = atoms;
|
helper.atoms = atoms;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +1,25 @@
|
|||||||
use rustyline::completion::Completer;
|
use indexmap::IndexSet;
|
||||||
|
use rustyline::completion::{Completer, Candidate};
|
||||||
use rustyline::hint::Hinter;
|
use rustyline::hint::Hinter;
|
||||||
use rustyline::validate::Validator;
|
use rustyline::validate::Validator;
|
||||||
use rustyline::highlight::{MatchingBracketHighlighter, Highlighter};
|
use rustyline::highlight::{MatchingBracketHighlighter, Highlighter};
|
||||||
use rustyline::{Helper as RlHelper, Result, Context};
|
use rustyline::{Helper as RlHelper, Result, Context};
|
||||||
|
|
||||||
// pub struct Atoms {
|
use crate::machine::mock_wam::Atom;
|
||||||
// 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,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// TODO: Maybe add validation to the helper
|
// TODO: Maybe add validation to the helper
|
||||||
pub struct Helper {
|
pub struct Helper {
|
||||||
highligher: MatchingBracketHighlighter,
|
highligher: MatchingBracketHighlighter,
|
||||||
pub atoms: Vec<String>,
|
pub atoms: *const IndexSet<Atom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Helper {
|
impl Helper {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
highligher: MatchingBracketHighlighter::new(),
|
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 {}
|
impl RlHelper for Helper {}
|
||||||
@@ -104,14 +54,32 @@ fn get_prefix(line: &str, pos: usize) -> Option<usize> {
|
|||||||
start_of_atom
|
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 {
|
impl Completer for Helper {
|
||||||
type Candidate = String;
|
type Candidate = StrPtr;
|
||||||
|
|
||||||
fn complete(&self, line: &str, pos: usize, _ctx: &Context<'_>) -> Result<(usize, Vec<Self::Candidate>)> {
|
fn complete(&self, line: &str, pos: usize, _ctx: &Context<'_>) -> Result<(usize, Vec<Self::Candidate>)> {
|
||||||
let start_of_prefix = get_prefix(line, pos);
|
let start_of_prefix = get_prefix(line, pos);
|
||||||
if let Some(idx) = start_of_prefix {
|
if let Some(idx) = start_of_prefix {
|
||||||
let sub_str = line.get(idx..pos).unwrap();
|
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))
|
Ok((idx, matching))
|
||||||
} else {
|
} else {
|
||||||
Ok((0, vec![]))
|
Ok((0, vec![]))
|
||||||
|
|||||||
Reference in New Issue
Block a user