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

View file

@ -20,6 +20,6 @@ path = "interpreter"
# path = "vm" # path = "vm"
[dependencies] [dependencies]
clap = { version = "4", features = ["derive"] } clap = { version = "4.5.16", features = ["derive"] }
colored = "2.1.0" colored = "2.1.0"
rustyline = "14.0.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 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
phf = { version = "0.11", features = ["macros"] } smol_str = "0.2.2"
thiserror = "1" phf = { version = "0.11.2", features = ["macros"] }
itertools = "0.13" thiserror = "1.0.63"
itertools = "0.13.0"

View file

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

View file

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

View file

@ -1,3 +1,5 @@
use smol_str::SmolStr;
use crate::lexer::{Token, TokenType}; use crate::lexer::{Token, TokenType};
use crate::parser::expr::BinaryOp; use crate::parser::expr::BinaryOp;
@ -481,7 +483,7 @@ impl Parser {
Ok(Expr::function(name, param_names, body)) 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); assert_eq!(self.next_token().token_type, TokenType::LeftParen);
if self.peek_token().token_type == TokenType::RightParen { 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 { match self.peek_token().token_type {
TokenType::Identifier(_) => match self.next_token().token_type { TokenType::Identifier(_) => match self.next_token().token_type {
TokenType::Identifier(s) => Ok(s), TokenType::Identifier(s) => Ok(s),

View file

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

View file

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

View file

@ -12,6 +12,7 @@ path = "../frontend"
glob = "0.3" glob = "0.3"
[dependencies] [dependencies]
thiserror = "1" itertools = "0.13.0"
itertools = "0.13" rustc-hash = "2.0.0"
rustc-hash = "2" 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 rlox2_frontend::parser::{Expr, Stmt};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use smol_str::SmolStr;
use crate::{LoxFunction, LoxReference, Value}; use crate::{LoxFunction, LoxReference, Value};
@ -10,7 +11,7 @@ use crate::{LoxFunction, LoxReference, Value};
pub struct LoxClass { pub struct LoxClass {
superclass: Option<Rc<LoxClass>>, superclass: Option<Rc<LoxClass>>,
name: Box<str>, name: SmolStr,
methods: FxHashMap<String, Value>, 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. /// Representation of a class in Lox. Always behind an Rc to ensure uniqueness. Should never be handled raw.
impl LoxClass { impl LoxClass {
pub fn new( pub fn new(
name: impl Into<Box<str>>, name: impl Into<SmolStr>,
methods: FxHashMap<String, Value>, methods: FxHashMap<String, Value>,
superclass: Option<Rc<LoxClass>>, superclass: Option<Rc<LoxClass>>,
) -> Rc<Self> { ) -> Rc<Self> {

View file

@ -4,6 +4,7 @@ use std::io::{Read, Write};
use std::rc::Rc; use std::rc::Rc;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use smol_str::SmolStr;
use crate::error::RuntimeError; use crate::error::RuntimeError;
@ -89,8 +90,8 @@ impl Display for ScopedValue {
} }
} }
type Scope = FxHashMap<Box<str>, ScopedValue>; type Scope = FxHashMap<SmolStr, ScopedValue>;
pub type ClosureScope = FxHashMap<Box<str>, HeapedValue>; pub type ClosureScope = FxHashMap<SmolStr, HeapedValue>;
#[derive(Debug)] #[derive(Debug)]
pub struct Environment<'a> { pub struct Environment<'a> {
@ -128,7 +129,7 @@ impl<'a> Environment<'a> {
std::mem::take(&mut self.arg_stack) 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() 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() { if self.has_scope() {
let name = name.into(); let name = name.into();
self.current_scope_mut() 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(); let mut closure_scope = ClosureScope::default();
for (name, level) in closure_vars { for (name, level) in closure_vars {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,11 +1,12 @@
use smol_str::SmolStr;
use thiserror::Error; use thiserror::Error;
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum ResolverError { pub enum ResolverError {
#[error("can't read variable {name} in its own initializer.")] #[error("can't read variable {name} in its own initializer.")]
VarInOwnInitializer { name: Box<str> }, VarInOwnInitializer { name: SmolStr },
#[error("variable {name} not defined")] #[error("variable {name} not defined")]
UnresolvableVariable { name: Box<str> }, UnresolvableVariable { name: SmolStr },
#[error("return outside of function definition")] #[error("return outside of function definition")]
ReturnOutsideFunction, ReturnOutsideFunction,
#[error("this outside of method")] #[error("this outside of method")]
@ -13,5 +14,5 @@ pub enum ResolverError {
#[error("super outside of subclass method")] #[error("super outside of subclass method")]
SuperOutsideMethod, SuperOutsideMethod,
#[error("local variable {name} declares multiple times")] #[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 std::rc::Rc;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use smol_str::SmolStr;
use crate::error::RuntimeError; use crate::error::RuntimeError;
@ -11,7 +12,7 @@ use super::lox_std::init_std;
use super::Value; use super::Value;
pub struct Runtime { pub struct Runtime {
globals: FxHashMap<Box<str>, Value>, globals: FxHashMap<SmolStr, Value>,
in_stream: Rc<RefCell<dyn std::io::Read>>, in_stream: Rc<RefCell<dyn std::io::Read>>,
out_stream: Rc<RefCell<dyn std::io::Write>>, out_stream: Rc<RefCell<dyn std::io::Write>>,
@ -53,7 +54,7 @@ impl Runtime {
self.out_stream.as_ref().borrow_mut() self.out_stream.as_ref().borrow_mut()
} }
pub fn globals(&self) -> &FxHashMap<Box<str>, Value> { pub fn globals(&self) -> &FxHashMap<SmolStr, Value> {
&self.globals &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(); let name = name.into();
self.globals.insert(name, value); self.globals.insert(name, value);
} }

View file

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

View file

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