replaced Box<str> with SmolStr

This commit is contained in:
Moritz Gmeiner 2024-09-02 05:19:30 +02:00
commit da6a820638
21 changed files with 137 additions and 85 deletions

35
Cargo.lock generated
View file

@ -362,6 +362,7 @@ version = "0.1.0"
dependencies = [
"itertools",
"phf",
"smol_str",
"thiserror",
]
@ -373,6 +374,7 @@ dependencies = [
"itertools",
"rlox2-frontend",
"rustc-hash",
"smol_str",
"thiserror",
]
@ -417,6 +419,26 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "serde"
version = "1.0.209"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.209"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "siphasher"
version = "0.3.11"
@ -429,6 +451,15 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "smol_str"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
dependencies = [
"serde",
]
[[package]]
name = "strsim"
version = "0.11.1"
@ -437,9 +468,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.76"
version = "2.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
dependencies = [
"proc-macro2",
"quote",

View file

@ -20,6 +20,6 @@ path = "interpreter"
# path = "vm"
[dependencies]
clap = { version = "4", features = ["derive"] }
clap = { version = "4.5.16", features = ["derive"] }
colored = "2.1.0"
rustyline = "14.0.0"

View file

@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
phf = { version = "0.11", features = ["macros"] }
thiserror = "1"
itertools = "0.13"
smol_str = "0.2.2"
phf = { version = "0.11.2", features = ["macros"] }
thiserror = "1.0.63"
itertools = "0.13.0"

View file

@ -1,4 +1,5 @@
use phf::phf_map;
use smol_str::SmolStr;
use super::{CodePos, LexerError, Token, TokenType};
@ -130,8 +131,9 @@ impl Lexer {
// advance until either source is empty or newline if found
while !self.source_is_empty() && self.advance() != '\n' {}
let comment: Box<str> =
self.source[self.start + 2..self.current].iter().collect();
let comment = SmolStr::from_iter(
self.source[self.start + 2..self.current].iter().cloned(),
);
self.push_token(TokenType::Comment(comment));
} else if self.consume('*') {
@ -170,9 +172,11 @@ impl Lexer {
self.advance();
}
let comment: Box<str> = self.source[self.start + 2..self.current - 2]
let comment = SmolStr::from_iter(
self.source[self.start + 2..self.current - 2]
.iter()
.collect();
.cloned(),
);
self.push_token(TokenType::Comment(comment));
} else {
@ -289,11 +293,6 @@ impl Lexer {
}
}
// let string_literal: Box<str> = self.source[self.start + 1..self.current - 1]
// .iter()
// .collect();
// Some(TokenType::String(Box::new(string_literal)))
self.tokens.push(Token::new_string(s, self.code_pos));
}

View file

@ -1,5 +1,7 @@
use std::fmt::{Debug, Display};
use smol_str::SmolStr;
use super::CodePos;
#[repr(u8)]
@ -17,13 +19,13 @@ pub enum TokenType {
Less, LessEqual,
// Identifier and literals
Identifier(Box<str>), String(Box<str>), Number(f64),
Identifier(SmolStr), String(SmolStr), Number(f64),
// Keywords
And, Break, Class, Else, False, Fun, For, If, Nil, Or,
Print, Return, Super, This, True, Var, While,
Comment(Box<str>),
Comment(SmolStr),
#[allow(clippy::upper_case_acronyms)]
EOF
@ -42,14 +44,14 @@ impl Token {
}
}
pub fn new_string(s: impl Into<Box<str>>, code_pos: CodePos) -> Self {
pub fn new_string(s: impl Into<SmolStr>, code_pos: CodePos) -> Self {
Token {
token_type: TokenType::String(s.into()),
code_pos,
}
}
pub fn new_identifier(name: impl Into<Box<str>>, code_pos: CodePos) -> Self {
pub fn new_identifier(name: impl Into<SmolStr>, code_pos: CodePos) -> Self {
Token {
token_type: TokenType::Identifier(name.into()),
code_pos,

View file

@ -1,3 +1,5 @@
use smol_str::SmolStr;
use crate::lexer::{Token, TokenType};
use crate::parser::expr::BinaryOp;
@ -481,7 +483,7 @@ impl Parser {
Ok(Expr::function(name, param_names, body))
}
fn collect_params(&mut self) -> ParserResult<Vec<Box<str>>> {
fn collect_params(&mut self) -> ParserResult<Vec<SmolStr>> {
assert_eq!(self.next_token().token_type, TokenType::LeftParen);
if self.peek_token().token_type == TokenType::RightParen {
@ -825,7 +827,7 @@ impl Parser {
})
}
fn identifier(&mut self, msg: &str) -> ParserResult<Box<str>> {
fn identifier(&mut self, msg: &str) -> ParserResult<SmolStr> {
match self.peek_token().token_type {
TokenType::Identifier(_) => match self.next_token().token_type {
TokenType::Identifier(s) => Ok(s),

View file

@ -1,6 +1,7 @@
use std::fmt::Display;
use itertools::Itertools;
use smol_str::SmolStr;
use super::Stmt;
@ -27,14 +28,14 @@ pub enum Expr {
expr: Box<Expr>,
},
Variable {
name: Box<str>,
name: SmolStr,
},
LocalVariable {
name: Box<str>,
name: SmolStr,
level: usize,
},
GlobalVariable {
name: Box<str>,
name: SmolStr,
},
Assignment {
target: Box<Expr>,
@ -46,21 +47,21 @@ pub enum Expr {
},
Get {
target: Box<Expr>,
name: Box<str>,
name: SmolStr,
},
Set {
target: Box<Expr>,
name: Box<str>,
name: SmolStr,
value: Box<Expr>,
},
Function {
name: Box<str>,
param_names: Vec<Box<str>>,
closure_vars: Vec<(Box<str>, usize)>,
name: SmolStr,
param_names: Vec<SmolStr>,
closure_vars: Vec<(SmolStr, usize)>,
body: Box<Stmt>,
},
Class {
name: Box<str>,
name: SmolStr,
superclass: Option<Box<Expr>>,
methods: Box<Vec<Expr>>,
},
@ -68,12 +69,12 @@ pub enum Expr {
Super {
super_var: Box<Expr>,
this_var: Box<Expr>,
method: Box<str>,
method: SmolStr,
},
}
impl Expr {
pub fn string(s: impl Into<Box<str>>) -> Self {
pub fn string(s: impl Into<SmolStr>) -> Self {
let s = s.into();
Expr::Literal {
literal: Literal::String(s),
@ -120,17 +121,17 @@ impl Expr {
Expr::Grouping { expr }
}
pub fn variable(name: impl Into<Box<str>>) -> Self {
pub fn variable(name: impl Into<SmolStr>) -> Self {
let name = name.into();
Expr::Variable { name }
}
pub fn local_variable(name: impl Into<Box<str>>, level: usize) -> Self {
pub fn local_variable(name: impl Into<SmolStr>, level: usize) -> Self {
let name = name.into();
Expr::LocalVariable { name, level }
}
pub fn global_variable(name: impl Into<Box<str>>) -> Self {
pub fn global_variable(name: impl Into<SmolStr>) -> Self {
let name = name.into();
Expr::GlobalVariable { name }
}
@ -146,13 +147,13 @@ impl Expr {
Expr::Call { callee, args }
}
pub fn get(target: Expr, name: impl Into<Box<str>>) -> Self {
pub fn get(target: Expr, name: impl Into<SmolStr>) -> Self {
let target = Box::new(target);
let name = name.into();
Expr::Get { target, name }
}
pub fn function(name: impl Into<Box<str>>, param_names: Vec<Box<str>>, body: Stmt) -> Self {
pub fn function(name: impl Into<SmolStr>, param_names: Vec<SmolStr>, body: Stmt) -> Self {
let name = name.into();
#[allow(clippy::box_default)]
// let closure_vars = Box::new(Vec::new());
@ -166,7 +167,7 @@ impl Expr {
}
}
pub fn class(name: impl Into<Box<str>>, methods: Vec<Expr>, superclass: Option<Expr>) -> Self {
pub fn class(name: impl Into<SmolStr>, methods: Vec<Expr>, superclass: Option<Expr>) -> Self {
let superclass = superclass.map(Box::new);
let name = name.into();
let methods = Box::new(methods);
@ -181,7 +182,7 @@ impl Expr {
pub fn super_(
super_var: impl Into<Box<Expr>>,
this_var: impl Into<Box<Expr>>,
method: impl Into<Box<str>>,
method: impl Into<SmolStr>,
) -> Self {
let super_var = super_var.into();
let this_var = this_var.into();
@ -267,7 +268,7 @@ impl Display for Expr {
#[derive(Debug, Clone)]
pub enum Literal {
String(Box<str>),
String(SmolStr),
Number(f64),
Bool(bool),
Nil,

View file

@ -1,5 +1,7 @@
use std::fmt::Display;
use smol_str::SmolStr;
use super::misc::indent;
use super::Expr;
@ -18,7 +20,7 @@ pub enum Stmt {
body: Box<Stmt>,
},
VarDecl {
name: Box<str>,
name: SmolStr,
initializer: Box<Expr>,
},
Block {
@ -62,7 +64,7 @@ impl Stmt {
Stmt::While { condition, body }
}
pub fn var_decl(name: impl Into<Box<str>>, initializer: impl Into<Box<Expr>>) -> Self {
pub fn var_decl(name: impl Into<SmolStr>, initializer: impl Into<Box<Expr>>) -> Self {
let name = name.into();
let initializer = initializer.into();

View file

@ -12,6 +12,7 @@ path = "../frontend"
glob = "0.3"
[dependencies]
thiserror = "1"
itertools = "0.13"
rustc-hash = "2"
itertools = "0.13.0"
rustc-hash = "2.0.0"
smol_str = "0.2.2"
thiserror = "1.0.63"

View file

@ -3,6 +3,7 @@ use std::rc::Rc;
use rlox2_frontend::parser::{Expr, Stmt};
use rustc_hash::FxHashMap;
use smol_str::SmolStr;
use crate::{LoxFunction, LoxReference, Value};
@ -10,7 +11,7 @@ use crate::{LoxFunction, LoxReference, Value};
pub struct LoxClass {
superclass: Option<Rc<LoxClass>>,
name: Box<str>,
name: SmolStr,
methods: FxHashMap<String, Value>,
}
@ -18,7 +19,7 @@ pub struct LoxClass {
/// Representation of a class in Lox. Always behind an Rc to ensure uniqueness. Should never be handled raw.
impl LoxClass {
pub fn new(
name: impl Into<Box<str>>,
name: impl Into<SmolStr>,
methods: FxHashMap<String, Value>,
superclass: Option<Rc<LoxClass>>,
) -> Rc<Self> {

View file

@ -4,6 +4,7 @@ use std::io::{Read, Write};
use std::rc::Rc;
use rustc_hash::FxHashMap;
use smol_str::SmolStr;
use crate::error::RuntimeError;
@ -89,8 +90,8 @@ impl Display for ScopedValue {
}
}
type Scope = FxHashMap<Box<str>, ScopedValue>;
pub type ClosureScope = FxHashMap<Box<str>, HeapedValue>;
type Scope = FxHashMap<SmolStr, ScopedValue>;
pub type ClosureScope = FxHashMap<SmolStr, HeapedValue>;
#[derive(Debug)]
pub struct Environment<'a> {
@ -128,7 +129,7 @@ impl<'a> Environment<'a> {
std::mem::take(&mut self.arg_stack)
}
pub fn globals(&self) -> &FxHashMap<Box<str>, Value> {
pub fn globals(&self) -> &FxHashMap<SmolStr, Value> {
self.runtime.globals()
}
@ -219,7 +220,7 @@ impl<'a> Environment<'a> {
}) */
}
pub fn define(&mut self, name: impl Into<Box<str>>, value: Value) {
pub fn define(&mut self, name: impl Into<SmolStr>, value: Value) {
if self.has_scope() {
let name = name.into();
self.current_scope_mut()
@ -246,7 +247,7 @@ impl<'a> Environment<'a> {
})
}
pub fn collect_closure(&mut self, closure_vars: &[(Box<str>, usize)]) -> ClosureScope {
pub fn collect_closure(&mut self, closure_vars: &[(SmolStr, usize)]) -> ClosureScope {
let mut closure_scope = ClosureScope::default();
for (name, level) in closure_vars {

View file

@ -3,6 +3,7 @@ use std::rc::Rc;
use rlox2_frontend::lexer::LexerError;
use rlox2_frontend::parser::{BinaryOp, ParserError, UnaryOp};
use smol_str::SmolStr;
use thiserror::Error;
use crate::Value;
@ -45,7 +46,7 @@ pub enum RuntimeError {
#[error("only objects have attributes")]
InvalidSetTarget,
#[error("class {0} has no property {name}", class.name())]
UndefinedAttribute { class: Rc<LoxClass>, name: Box<str> },
UndefinedAttribute { class: Rc<LoxClass>, name: SmolStr },
#[error("{value} is not a valid superclass")]
InvalidSuperclass { value: Value },
#[error("stack overflow")]

View file

@ -2,6 +2,7 @@ use std::fmt::{Debug, Display};
use std::rc::Rc;
use rlox2_frontend::parser::Stmt;
use smol_str::SmolStr;
use crate::environment::{ClosureScope, HeapedValue};
@ -11,17 +12,17 @@ use super::{Runtime, Value};
#[derive(Debug, Clone)]
pub struct LoxFunction {
name: Box<str>,
name: SmolStr,
closure: ClosureScope,
param_names: Vec<Box<str>>,
param_names: Vec<SmolStr>,
body: Box<Stmt>,
}
impl LoxFunction {
pub fn new(
name: impl Into<Box<str>>,
name: impl Into<SmolStr>,
closure: ClosureScope,
param_names: Vec<Box<str>>,
param_names: Vec<SmolStr>,
body: Stmt,
) -> Rc<Self> {
let name = name.into();
@ -43,7 +44,7 @@ impl LoxFunction {
&self.closure
}
pub fn param_names(&self) -> &[Box<str>] {
pub fn param_names(&self) -> &[SmolStr] {
&self.param_names
}
@ -55,7 +56,7 @@ impl LoxFunction {
self.param_names().len()
}
pub fn inject_closed_var(&mut self, name: impl Into<Box<str>>, value: Value) {
pub fn inject_closed_var(&mut self, name: impl Into<SmolStr>, value: Value) {
let name = name.into();
let heaped_value = HeapedValue::new(value);
self.closure.insert(name, heaped_value);

View file

@ -154,7 +154,8 @@ impl Eval for Expr {
if let Value::Object(object) = target {
object.get(name).ok_or_else(|| {
let class = object.class();
let name = name.to_owned();
let name = name.clone();
RuntimeError::UndefinedAttribute { class, name }
})
} else {

View file

@ -1,3 +1,5 @@
use smol_str::SmolStr;
use crate::error::RuntimeError;
use super::function::{ExternFunClosure, LoxExternFunction};
@ -47,7 +49,7 @@ fn clock() -> LoxExternFunction {
fn print_globals() -> LoxExternFunction {
let closure: ExternFunClosure = |args, env| {
assert_eq!(args.len(), 0);
let mut globals: Vec<(&Box<str>, &Value)> = env.globals().iter().collect();
let mut globals: Vec<(&SmolStr, &Value)> = env.globals().iter().collect();
globals.sort_by_key(|&(name, _value)| name);

View file

@ -3,6 +3,7 @@ use std::fmt::Display;
use std::rc::Rc;
use rustc_hash::FxHashMap;
use smol_str::SmolStr;
use crate::{LoxClass, Value};
@ -12,7 +13,7 @@ use crate::{LoxClass, Value};
struct LoxObject {
class: Rc<LoxClass>,
attrs: FxHashMap<Box<str>, Value>,
attrs: FxHashMap<SmolStr, Value>,
}
impl LoxObject {
@ -35,7 +36,7 @@ impl LoxObject {
self.class.get_method(name, this)
}
fn set(&mut self, name: impl Into<Box<str>>, value: Value) {
fn set(&mut self, name: impl Into<SmolStr>, value: Value) {
let name = name.into();
self.attrs.insert(name, value);
}
@ -75,7 +76,7 @@ impl LoxReference {
}
}
pub fn set(&mut self, name: impl Into<Box<str>>, value: Value) {
pub fn set(&mut self, name: impl Into<SmolStr>, value: Value) {
unsafe {
let ptr = self.inner.get();
let object = &mut *ptr;

View file

@ -1,12 +1,13 @@
use rlox2_frontend::parser::{Expr, Stmt};
use rustc_hash::FxHashMap;
use smol_str::SmolStr;
use crate::Runtime;
use crate::{LoxError, ResolverError};
/*====================================================================================================================*/
type ResolverScope = FxHashMap<Box<str>, ResolveStatus>;
type ResolverScope = FxHashMap<SmolStr, ResolveStatus>;
type ResolverFrame = Vec<ResolverScope>;
type ResolverResult<T> = Result<T, ResolverError>;
@ -37,11 +38,11 @@ struct Resolver {
// local_scopes: Vec<ResolverScope>,
frames: Vec<ResolverFrame>,
closure_vars: FxHashMap<Box<str>, usize>,
closure_vars: FxHashMap<SmolStr, usize>,
}
impl Resolver {
fn new(global_names: impl Iterator<Item = Box<str>>) -> Self {
fn new(global_names: impl Iterator<Item = SmolStr>) -> Self {
let mut global_scope = ResolverScope::default();
for name in global_names {
@ -83,7 +84,7 @@ impl Resolver {
.expect("Tried to pop non-existant ResolverFrame");
}
fn declare(&mut self, name: impl Into<Box<str>>) -> ResolverResult<()> {
fn declare(&mut self, name: impl Into<SmolStr>) -> ResolverResult<()> {
let name = name.into();
if let Some(local_scope) = self.local_scopes_mut().last_mut() {
@ -100,7 +101,7 @@ impl Resolver {
Ok(())
}
fn define(&mut self, name: impl Into<Box<str>>) {
fn define(&mut self, name: impl Into<SmolStr>) {
let name = name.into();
if let Some(local_scope) = self.local_scopes_mut().last_mut() {

View file

@ -1,11 +1,12 @@
use smol_str::SmolStr;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ResolverError {
#[error("can't read variable {name} in its own initializer.")]
VarInOwnInitializer { name: Box<str> },
VarInOwnInitializer { name: SmolStr },
#[error("variable {name} not defined")]
UnresolvableVariable { name: Box<str> },
UnresolvableVariable { name: SmolStr },
#[error("return outside of function definition")]
ReturnOutsideFunction,
#[error("this outside of method")]
@ -13,5 +14,5 @@ pub enum ResolverError {
#[error("super outside of subclass method")]
SuperOutsideMethod,
#[error("local variable {name} declares multiple times")]
LocalMulipleDeclarations { name: Box<str> },
LocalMulipleDeclarations { name: SmolStr },
}

View file

@ -4,6 +4,7 @@ use std::io::{stdin, stdout, Read, Write};
use std::rc::Rc;
use rustc_hash::FxHashMap;
use smol_str::SmolStr;
use crate::error::RuntimeError;
@ -11,7 +12,7 @@ use super::lox_std::init_std;
use super::Value;
pub struct Runtime {
globals: FxHashMap<Box<str>, Value>,
globals: FxHashMap<SmolStr, Value>,
in_stream: Rc<RefCell<dyn std::io::Read>>,
out_stream: Rc<RefCell<dyn std::io::Write>>,
@ -53,7 +54,7 @@ impl Runtime {
self.out_stream.as_ref().borrow_mut()
}
pub fn globals(&self) -> &FxHashMap<Box<str>, Value> {
pub fn globals(&self) -> &FxHashMap<SmolStr, Value> {
&self.globals
}
@ -66,7 +67,7 @@ impl Runtime {
})
}
pub fn define_global(&mut self, name: impl Into<Box<str>>, value: Value) {
pub fn define_global(&mut self, name: impl Into<SmolStr>, value: Value) {
let name = name.into();
self.globals.insert(name, value);
}

View file

@ -1,6 +1,8 @@
use std::fmt::{Debug, Display};
use std::rc::Rc;
use smol_str::SmolStr;
use crate::{LoxClass, LoxReference};
use super::function::LoxExternFunction;
@ -12,7 +14,7 @@ pub enum Value {
Class(Rc<LoxClass>),
Function(Rc<LoxFunction>),
ExternFunction(Rc<LoxExternFunction>),
String(Box<str>),
String(SmolStr),
Number(f64),
Bool(bool),
#[default]
@ -34,7 +36,7 @@ impl Value {
Value::ExternFunction(fun)
}
pub fn string(s: impl Into<Box<str>>) -> Self {
pub fn string(s: impl Into<SmolStr>) -> Self {
let s = s.into();
Value::String(s)
}

View file

@ -9,10 +9,10 @@ path = "../frontend"
[dependencies]
itertools = "0.13"
lazy_static = "1"
num-derive = "0.4"
num-traits = "0.2"
regex = "1"
thiserror = "1"
static_assertions = "1"
itertools = "0.13.0"
lazy_static = "1.5.0"
num-derive = "0.4.2"
num-traits = "0.2.19"
regex = "1.10.6"
static_assertions = "1.1.0"
thiserror = "1.0.63"