]> Repositorios git - scryer-prolog.git/commitdiff
fix: remove unnecessary string & vec allocations
authorEuan Lacy <[email protected]>
Tue, 10 May 2022 16:54:15 +0000 (17:54 +0100)
committerEuan Lacy <[email protected]>
Tue, 10 May 2022 17:10:18 +0000 (18:10 +0100)
src/machine/machine_state.rs
src/read.rs
src/repl_helper.rs

index f33f09014832f451fa33144330e4062f32a7c680..d19242f2491531ff33c9291f737c32a4c96d58cc 100644 (file)
@@ -454,13 +454,15 @@ impl MachineState {
         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
             }
index 399d9280019a7bc84ad23c87ef02ef76850f0579..5ef89d04330031470b09c403418dcc0f01b63118 100644 (file)
@@ -14,6 +14,7 @@ use crate::types::*;
 
 use fxhash::FxBuildHasher;
 
+use indexmap::IndexSet;
 use rustyline::error::ReadlineError;
 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();
         helper.atoms = atoms;
     }
index 96f63efa26b5a94815f57ff9b17c993a97e3d0cd..913470201c368d540808c3935a8507037f4d840d 100644 (file)
@@ -1,75 +1,25 @@
-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 {}
@@ -104,14 +54,32 @@ fn get_prefix(line: &str, pos: usize) -> Option<usize> {
     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![]))