Interning Orchid string literals

This commit is contained in:
2023-08-19 14:35:24 +01:00
parent 0b887ced70
commit 6693d93944
10 changed files with 96 additions and 29 deletions

View File

@@ -4,6 +4,7 @@ use ordered_float::NotNan;
use super::ArithmeticError;
use crate::foreign::ExternError;
use crate::interner::Interner;
use crate::interpreted::Clause;
use crate::parse::{float_parser, int_parser};
use crate::systems::cast_exprinst::with_lit;
use crate::systems::AssertionError;
@@ -43,10 +44,10 @@ define_fn! {
/// Convert a literal to a string using Rust's conversions for floats, chars and
/// uints respectively
ToString = |x| with_lit(x, |l| Ok(match l {
Literal::Uint(i) => i.to_string(),
Literal::Num(n) => n.to_string(),
Literal::Str(s) => s.clone(),
})).map(|s| Literal::Str(s).into())
Literal::Uint(i) => Literal::Str(i.to_string().into()),
Literal::Num(n) => Literal::Str(n.to_string().into()),
s@Literal::Str(_) => s.clone(),
})).map(Clause::from)
}
pub fn conv(i: &Interner) -> ConstTree {

View File

@@ -1,4 +1,5 @@
use std::fmt::Display;
use std::rc::Rc;
use crate::foreign::ExternError;
use crate::systems::cast_exprinst::with_str;
@@ -6,7 +7,7 @@ use crate::{define_fn, ConstTree, Interner};
/// An unrecoverable error in Orchid land. Because Orchid is lazy, this only
/// invalidates expressions that reference the one that generated it.
pub struct OrchidPanic(String);
pub struct OrchidPanic(Rc<String>);
impl Display for OrchidPanic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -18,7 +19,10 @@ impl ExternError for OrchidPanic {}
define_fn! {
/// Takes a message, returns an [ExternError] unconditionally.
Panic = |x| with_str(x, |s| Err(OrchidPanic(s.clone()).into_extern()))
Panic = |x| with_str(x, |s| {
let msg = Rc::new(s.get_string());
Err(OrchidPanic(msg).into_extern())
})
}
pub fn panic(i: &Interner) -> ConstTree {

View File

@@ -1,6 +1,7 @@
use unicode_segmentation::UnicodeSegmentation;
use crate::interner::Interner;
use crate::representations::OrcString;
use crate::systems::cast_exprinst::with_str;
use crate::systems::codegen::{orchid_opt, tuple};
use crate::systems::RuntimeError;
@@ -9,15 +10,16 @@ use crate::{define_fn, ConstTree, Literal};
define_fn! {expr=x in
/// Append a string to another
pub Concatenate { a: String, b: String }
=> Ok(Literal::Str(a.to_owned() + b).into())
pub Concatenate { a: OrcString, b: OrcString }
=> Ok(Literal::Str((a.get_string() + b.as_str()).into()).into())
}
define_fn! {expr=x in
pub Slice { s: String, i: u64, len: u64 } => {
let graphs = s.graphemes(true);
pub Slice { s: OrcString, i: u64, len: u64 } => {
let graphs = s.as_str().graphemes(true);
if *i == 0 {
Ok(Literal::Str(graphs.take(*len as usize).collect()).into())
let orc_str = graphs.take(*len as usize).collect::<String>().into();
Ok(Literal::Str(orc_str).into())
} else {
let mut prefix = graphs.skip(*i as usize - 1);
if prefix.next().is_none() {
@@ -27,10 +29,9 @@ define_fn! {expr=x in
)
} else {
let mut count = 0;
let ret = prefix
.take(*len as usize)
let ret = (prefix.take(*len as usize))
.map(|x| { count+=1; x })
.collect();
.collect::<String>().into();
if count == *len {
Ok(Literal::Str(ret).into())
} else {
@@ -45,15 +46,16 @@ define_fn! {expr=x in
}
define_fn! {expr=x in
pub Find { haystack: String, needle: String } => {
let found = iter_find(haystack.graphemes(true), needle.graphemes(true));
pub Find { haystack: OrcString, needle: OrcString } => {
let haystack_graphs = haystack.as_str().graphemes(true);
let found = iter_find(haystack_graphs, needle.as_str().graphemes(true));
Ok(orchid_opt(found.map(|x| Literal::Uint(x as u64).into())))
}
}
define_fn! {expr=x in
pub Split { s: String, i: u64 } => {
let mut graphs = s.graphemes(true);
pub Split { s: OrcString, i: u64 } => {
let mut graphs = s.as_str().graphemes(true);
let a = graphs.by_ref().take(*i as usize).collect::<String>();
let b = graphs.collect::<String>();
Ok(tuple(vec![a.into(), b.into()]))