Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Use CompactString as backing storage for Steel strings. #270

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- run: cd crates/steel-core && cargo bench --bench my_benchmark -- --output-format bencher | tee output.txt
- run: |
cd crates/steel-core
cargo bench --bench my_benchmark -- --output-format bencher | tee output.txt
- uses: actions/cache@v1
with:
path: ./cache
Expand Down
32 changes: 31 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion crates/steel-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ rand = "0.8.5"
num = "0.4.0"
radix_fmt = "1.0.0"

# For structs
# Optimized datastructures
smallvec = { version = "1.13.0" }
compact_str = { version = "0.8.0" }

# Pretty printing documentation
termimad = { version = "0.21.0", optional = true }
Expand Down
5 changes: 3 additions & 2 deletions crates/steel-core/src/compiler/code_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use crate::{
tryfrom_visitor::TryFromExprKindForSteelVal,
visitors::VisitorMut,
},
rvals::SteelString,
stop, SteelVal,
};
use smallvec::SmallVec;
Expand Down Expand Up @@ -56,7 +57,7 @@ fn try_eval_atom(t: &SyntaxObject) -> Option<SteelVal> {
match &t.ty {
TokenType::BooleanLiteral(b) => Some((*b).into()),
TokenType::Number(n) => number_literal_to_steel(n).ok(),
TokenType::StringLiteral(s) => Some(SteelVal::StringV(s.to_string().into())),
TokenType::StringLiteral(s) => Some(SteelVal::StringV(SteelString::from(s.as_str()))),
TokenType::CharacterLiteral(c) => Some(SteelVal::CharV(*c)),
// TODO: Keywords shouldn't be misused as an expression - only in function calls are keywords allowed
TokenType::Keyword(k) => Some(SteelVal::SymbolV(k.clone().into())),
Expand All @@ -70,7 +71,7 @@ fn try_eval_atom_with_context(t: &SyntaxObject) -> Result<SteelVal> {
match &t.ty {
TokenType::BooleanLiteral(b) => Ok((*b).into()),
TokenType::Number(n) => number_literal_to_steel(n).map_err(|e| e.with_span(t.span)),
TokenType::StringLiteral(s) => Ok(SteelVal::StringV(s.to_string().into())),
TokenType::StringLiteral(s) => Ok(SteelVal::StringV(SteelString::from(s.as_str()))),
TokenType::CharacterLiteral(c) => Ok(SteelVal::CharV(*c)),
TokenType::Keyword(k) => Ok(SteelVal::SymbolV(k.clone().into())),
_what => {
Expand Down
2 changes: 1 addition & 1 deletion crates/steel-core/src/compiler/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ fn eval_atom(t: &SyntaxObject) -> Result<SteelVal> {
match &t.ty {
TokenType::BooleanLiteral(b) => Ok((*b).into()),
TokenType::Number(n) => number_literal_to_steel(n),
TokenType::StringLiteral(s) => Ok(SteelVal::StringV(s.to_string().into())),
TokenType::StringLiteral(s) => Ok(SteelVal::StringV(s.as_str().into())),
TokenType::CharacterLiteral(c) => Ok(SteelVal::CharV(*c)),
// TODO: Keywords shouldn't be misused as an expression - only in function calls are keywords allowed
TokenType::Keyword(k) => Ok(SteelVal::SymbolV(k.clone().into())),
Expand Down
17 changes: 9 additions & 8 deletions crates/steel-core/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::{ffi::OsStr, fmt};
pub static OBJECT_COUNT: AtomicUsize = AtomicUsize::new(0);
pub(crate) static MAXIMUM_OBJECTS: usize = 50000;

use compact_str::CompactString;
pub use shared::{GcMut, MutContainer, ShareableMut, Shared, SharedMut};

#[cfg(feature = "sync")]
Expand Down Expand Up @@ -447,31 +448,31 @@ impl<T: ?Sized> Clone for Gc<T> {
}
}

impl AsRef<OsStr> for Gc<String> {
impl AsRef<OsStr> for Gc<CompactString> {
fn as_ref(&self) -> &OsStr {
self.0.as_ref().as_ref()
}
}

impl From<&str> for Gc<String> {
impl From<&str> for Gc<CompactString> {
fn from(val: &str) -> Self {
Gc::new(val.to_string())
Gc::new(val.into())
}
}

impl From<String> for Gc<String> {
fn from(val: String) -> Self {
impl From<CompactString> for Gc<CompactString> {
fn from(val: CompactString) -> Self {
Gc::new(val)
}
}

impl From<&String> for Gc<String> {
fn from(val: &String) -> Self {
impl From<&CompactString> for Gc<CompactString> {
fn from(val: &CompactString) -> Self {
Gc::new(val.clone())
}
}

impl AsRef<str> for Gc<String> {
impl AsRef<str> for Gc<CompactString> {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
Expand Down
8 changes: 5 additions & 3 deletions crates/steel-core/src/parser/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{
sync::{Arc, RwLock},
};

use compact_str::ToCompactString;
use fxhash::{FxBuildHasher, FxHashMap, FxHashSet};

#[cfg(feature = "sync")]
Expand Down Expand Up @@ -114,7 +115,7 @@ impl Kernel {
.map(|set| {
set.iter()
.map(|x| x.resolve().to_string())
.map(|x| SteelVal::SymbolV(x.into()))
.map(|x| SteelVal::SymbolV(x.as_str().into()))
.collect::<crate::values::lists::List<SteelVal>>()
.into()
})
Expand Down Expand Up @@ -551,8 +552,9 @@ impl Kernel {
} else {
// Check if there is anything to expand in this environment
if let Ok(SteelVal::HashMapV(map)) = self.engine.extract_value(environment) {
if let Some(func) = map.get(&SteelVal::SymbolV(ident.resolve().to_string().into()))
{
if let Some(func) = map.get(&SteelVal::SymbolV(SteelString::from(
ident.resolve().to_compact_string(),
))) {
func.clone()
} else {
self.engine.extract_value(ident.resolve())?
Expand Down
2 changes: 1 addition & 1 deletion crates/steel-core/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl TryFrom<SyntaxObject> for SteelVal {
}
.into_steelval(),
},
StringLiteral(x) => Ok(StringV((*x).into())),
StringLiteral(x) => Ok(StringV((*x).as_str().into())),
Keyword(x) => Ok(SymbolV(x.into())),
QuoteTick => {
Err(SteelErr::new(ErrorKind::UnexpectedToken, "'".to_string()).with_span(span))
Expand Down
4 changes: 2 additions & 2 deletions crates/steel-core/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ impl TryFrom<&SteelVal> for String {

impl From<String> for SteelVal {
fn from(val: String) -> SteelVal {
SteelVal::StringV(val.into())
SteelVal::StringV(val.as_str().into())
}
}

Expand Down Expand Up @@ -819,7 +819,7 @@ impl<'a> PrimitiveAsRef<'a> for &'a SteelHashMap {

impl IntoSteelVal for String {
fn into_steelval(self) -> Result<SteelVal, SteelErr> {
Ok(SteelVal::StringV(self.into()))
Ok(SteelVal::StringV(self.as_str().into()))
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/steel-core/src/primitives/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl ControlOperations {
error_message.push_str(error_val.trim_matches('\"'));
}

Ok(SteelVal::StringV(error_message.into()))
Ok(SteelVal::StringV(error_message.as_str().into()))
})
}

Expand Down
2 changes: 1 addition & 1 deletion crates/steel-core/src/primitives/lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ fn list_to_string(list: &List<SteelVal>) -> Result<SteelVal> {
x.char_or_else(throw!(TypeMismatch => "list->string expected a list of characters"))
})
.collect::<Result<String>>()
.map(|x| x.into())
.map(|x| x.as_str().into())
.map(SteelVal::StringV)
}

Expand Down
4 changes: 2 additions & 2 deletions crates/steel-core/src/primitives/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ pub fn open_input_bytevector(bytes: &SteelByteVector) -> SteelVal {
#[function(name = "read-port-to-string")]
pub fn read_port_to_string(port: &SteelPort) -> Result<SteelVal> {
let (_, result) = port.read_all_str()?;
Ok(SteelVal::StringV(result.into()))
Ok(SteelVal::StringV(result.as_str().into()))
}

/// Checks if a given value is an input port
Expand Down Expand Up @@ -225,7 +225,7 @@ pub fn read_line_to_string(port: &SteelPort) -> Result<SteelVal> {
if size == 0 {
Ok(eof())
} else {
Ok(SteelVal::StringV(result.into()))
Ok(SteelVal::StringV(result.as_str().into()))
}
} else {
// bit of a hack for now we'll see
Expand Down
19 changes: 10 additions & 9 deletions crates/steel-core/src/primitives/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::rvals::{RestArgsIter, Result, SteelByteVector, SteelString, SteelVal}
use crate::steel_vm::builtin::BuiltInModule;
use crate::{stop, Vector};

use compact_str::{CompactString, ToCompactString};
use num::{BigInt, Num};
use steel_derive::{function, native};

Expand Down Expand Up @@ -113,14 +114,14 @@ fn number_to_string_impl(value: &SteelVal, radix: Option<u32>) -> Result<SteelVa
SteelVal::IntV(v) => {
if let Some(radix) = radix {
Ok(SteelVal::StringV(
radix_fmt::radix(*v, radix as u8).to_string().into(),
radix_fmt::radix(*v, radix as u8).to_compact_string().into(),
))
} else {
Ok(SteelVal::StringV(v.to_string().into()))
Ok(SteelVal::StringV(v.to_compact_string().into()))
}
}
SteelVal::NumV(n) => Ok(SteelVal::StringV(n.to_string().into())),
SteelVal::BigNum(n) => Ok(SteelVal::StringV(n.to_string().into())),
SteelVal::NumV(n) => Ok(SteelVal::StringV(n.to_compact_string().into())),
SteelVal::BigNum(n) => Ok(SteelVal::StringV(n.to_compact_string().into())),
_ => stop!(TypeMismatch => "number->string expects a number type, found: {}", value),
}
}
Expand Down Expand Up @@ -406,7 +407,7 @@ pub fn make_string(k: usize, mut c: RestArgsIter<'_, char>) -> Result<SteelVal>
#[function(name = "string-replace")]
pub fn replace(value: &SteelString, from: &SteelString, to: &SteelString) -> Result<SteelVal> {
Ok(SteelVal::StringV(
value.replace(from.as_str(), to.as_str()).into(),
value.replace(from.as_str(), to.as_str()).as_str().into(),
))
}

Expand Down Expand Up @@ -436,7 +437,7 @@ pub fn to_string(args: &[SteelVal]) -> Result<SteelVal> {
}
}

Ok(SteelVal::StringV(error_message.into()))
Ok(SteelVal::StringV(error_message.as_str().into()))
}

/// Converts a string into a symbol.
Expand Down Expand Up @@ -529,7 +530,7 @@ pub fn string_to_list(value: &SteelString, mut rest: RestArgsIter<isize>) -> Res
/// > (string->upper "lower") ;; => "LOWER"
/// ```
#[function(name = "string->upper")]
pub fn string_to_upper(value: &SteelString) -> String {
pub fn string_to_upper(value: &SteelString) -> CompactString {
value.to_uppercase()
}

Expand All @@ -543,7 +544,7 @@ pub fn string_to_upper(value: &SteelString) -> String {
/// > (string->lower "sPonGeBoB tExT") ;; => "spongebob text"
/// ```
#[function(name = "string->lower")]
pub fn string_to_lower(value: &SteelString) -> String {
pub fn string_to_lower(value: &SteelString) -> CompactString {
value.to_lowercase()
}

Expand Down Expand Up @@ -750,7 +751,7 @@ pub fn string_length(value: &SteelString) -> usize {
pub fn string_append(mut rest: RestArgsIter<'_, &SteelString>) -> Result<SteelVal> {
rest.0
.try_fold("".to_string(), |accum, next| Ok(accum + next?.as_str()))
.map(|x| SteelVal::StringV(x.into()))
.map(|x| SteelVal::StringV(x.as_str().into()))
}

macro_rules! impl_char_comparison {
Expand Down
2 changes: 1 addition & 1 deletion crates/steel-core/src/primitives/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl SymbolOperations {
}
}

Ok(SteelVal::SymbolV(new_symbol.into()))
Ok(SteelVal::SymbolV(new_symbol.as_str().into()))
})
}

Expand Down
2 changes: 1 addition & 1 deletion crates/steel-core/src/primitives/vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn immutable_vector_to_string(
x.char_or_else(throw!(TypeMismatch => "immutable-vector->string expected a succession of characters"))
})
.collect::<Result<String>>()
.map(|x| x.into())
.map(|x| x.as_str().into())
.map(SteelVal::StringV)
}

Expand Down
Loading
Loading