WIP commit:

* Fix up project structures
* combine vars and funcs table
* make a place for old code that may be useful to reference
* singleton pattern for sym table

Commentary:
When this change is finally finished I promise to use feature branches
from here on out
This commit is contained in:
Ava Hahn 2023-02-15 23:27:00 -08:00
parent b680e3ca9a
commit ca4c557d95
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
32 changed files with 1092 additions and 616 deletions

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::segment::{list_append, Ctr, Seg};
use crate::segment::{Ctr, Seg};
const UNMATCHED_STR_DELIM: &str = "Unmatched string delimiter in input";
const UNMATCHED_LIST_DELIM: &str = "Unmatched list delimiter in input";
@ -23,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<'a>(document: String) -> Result<Box<Seg<'a>>, String> {
pub fn lex<'a>(document: &'a String) -> Result<Box<Seg>, String> {
if !document.is_ascii() {
return Err("document may only contain ascii characters".to_string());
}
@ -42,7 +42,7 @@ pub fn lex<'a>(document: String) -> Result<Box<Seg<'a>>, String> {
* Returns Ok(Rc<Seg>) if lexing passes
* Returns Err(String) if an error occurs
*/
fn process<'a>(document: &'a String) -> Result<Box<Seg<'a>>, String> {
fn process<'a>(document: &'a String) -> Result<Box<Seg>, String> {
let doc_len = document.len();
if doc_len == 0 {
@ -120,8 +120,7 @@ fn process<'a>(document: &'a String) -> Result<Box<Seg<'a>>, String> {
return Err("list started in middle of another token".to_string());
}
ref_stack.push(Box::new(Seg::new()));
ref_stack.push(Seg::new());
delim_stack.push(')');
}
// begin parsing a string
@ -152,42 +151,47 @@ fn process<'a>(document: &'a String) -> Result<Box<Seg<'a>>, String> {
return Err("Empty token".to_string());
}
let mut current_seg = ref_stack.pop();
let mut obj;
let mut current_seg = ref_stack.pop().unwrap();
let obj;
if is_str {
obj = Ctr::String(token);
obj = Box::from(Ctr::String(token));
is_str = false;
token = String::new();
current_seg.append(obj);
} else if token.len() > 0 {
if token == "true" {
obj = Ctr::Bool(true);
obj = Box::from(Ctr::Bool(true));
} else if token == "false" {
obj = Ctr::Bool(false);
obj = Box::from(Ctr::Bool(false));
} else if let Ok(i) = token.parse::<i128>() {
obj = Ctr::Integer(i);
obj = Box::from(Ctr::Integer(i));
} else if let Ok(f) = token.parse::<f64>() {
obj = Ctr::Float(f);
obj = Box::from(Ctr::Float(f));
} else if let Some(s) = tok_is_symbol(&token) {
obj = Ctr::Symbol(s);
obj = Box::from(Ctr::Symbol(s));
} else {
return Err(format!("Unparsable token: {}", token));
}
token = String::new();
current_seg.append(obj.clone());
}
list_append(current_seg, obj);
if alloc_list {
// return if we have finished the document
if ref_stack.len() == 0 {
return Ok(current_seg);
return Ok(Box::new(current_seg));
}
// shortening this will lead to naught but pain
obj = Ctr::Seg(current_seg.into_raw());
current_seg = ref_stack.pop();
list_append(current_seg, obj);
let t = current_seg;
current_seg = ref_stack.pop().unwrap();
/* TODO: is there a way to do this that doesnt
* involve needlessly copying heap data? I am
* not sure what optimizations rustc performs
* but I assume this should not end up copying
* contained segments around.
*/
current_seg.append(Box::from(Ctr::Seg(t)));
}
ref_stack.push(current_seg);