Big referencing refactor

- RC+RefCell pattern used... everywhere
- Ast type implemented
- unit tests for func_call
- more changes, but this commit scope has grown significantly and I
cannot list them all
This commit is contained in:
Aidan 2021-03-14 16:14:57 -07:00
parent 76b12a8214
commit 3434a49cc1
No known key found for this signature in database
GPG key ID: 327711E983899316
9 changed files with 446 additions and 391 deletions

View file

@ -15,8 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use std::boxed::Box;
use crate::cell::{Ctr, Cell};
use crate::segment::{Ctr, Ast, list_append, new_ast};
const UNMATCHED_STR_DELIM: &str = "Unmatched string delimiter in input";
const UNMATCHED_LIST_DELIM: &str = "Unmatched list delimiter in input";
@ -24,7 +23,7 @@ const UNMATCHED_LIST_DELIM: &str = "Unmatched list delimiter in input";
/* takes a line of user input
* returns an unsimplified tree of tokens.
*/
pub fn lex(document: String) -> Result<Box<Cell>, String> {
pub fn lex(document: String) -> Result<Ast, String> {
if !document.is_ascii() {
return Err("document may only contain ascii characters".to_string());
}
@ -40,10 +39,10 @@ pub fn lex(document: String) -> Result<Box<Cell>, String> {
}
/* The logic used in lex
* Returns Ok(Box<Cell>) if lexing passes
* Returns Ok(Rc<Seg>) if lexing passes
* Returns Err(String) if an error occurs
*/
fn process(document: String) -> Result<Box<Cell>, String> {
fn process(document: String) -> Result<Ast, String> {
let doc_len = document.len();
if doc_len == 0 {
@ -110,16 +109,13 @@ fn process(document: String) -> Result<Box<Cell>, String> {
// match a delimiter
if !needs_alloc {
match c {
// add a new Cell reference to the stack
// add a new Seg reference to the stack
'(' => {
if token != "" {
return Err("list started in middle of another token".to_string());
}
ref_stack.push(Box::new(Cell{
car: Ctr::None,
cdr: Ctr::None
}));
ref_stack.push(new_ast(Ctr::None, Ctr::None));
delim_stack.push(')');
},
@ -151,7 +147,7 @@ fn process(document: String) -> Result<Box<Cell>, String> {
return Err("Empty token".to_string());
}
let mut current_cell_ref = ref_stack.pop().unwrap();
let mut current_seg_ref = ref_stack.pop().unwrap();
let mut obj;
if token.len() > 0 {
if is_str {
@ -172,22 +168,22 @@ fn process(document: String) -> Result<Box<Cell>, String> {
}
token = String::new();
current_cell_ref.append(obj);
list_append(current_seg_ref.clone(), obj);
}
if alloc_list {
// return if we have finished the document
if ref_stack.len() == 0 {
return Ok(Box::new(*current_cell_ref));
return Ok(current_seg_ref);
}
// shortening this will lead to naught but pain
obj = Ctr::Cell(Box::new(*current_cell_ref));
current_cell_ref = ref_stack.pop().unwrap();
current_cell_ref.append(obj);
obj = Ctr::Seg(current_seg_ref.clone());
current_seg_ref = ref_stack.pop().unwrap();
list_append(current_seg_ref.clone(), obj);
}
ref_stack.push(current_cell_ref);
ref_stack.push(current_seg_ref);
}
}