feat: less clone on symbol

This commit is contained in:
2025-05-15 18:19:16 +08:00
parent 3e7a8a1c05
commit 864be73e77
12 changed files with 195 additions and 183 deletions

View File

@@ -13,6 +13,8 @@ pub fn downgrade(expr: Expr) -> Result<Downgraded> {
Ok(Downgraded {
top_level: ir,
consts: ctx.consts.into(),
symbols: ctx.symbols,
symmap: ctx.symmap,
thunks: ctx.thunks.into(),
funcs: ctx.funcs.into(),
})
@@ -96,7 +98,7 @@ macro_rules! ir {
}
ir! {
Attrs => { stcs: HashMap<EcoString, Ir>, dyns: Vec<DynamicAttrPair>, rec: bool },
Attrs => { stcs: HashMap<usize, Ir>, dyns: Vec<DynamicAttrPair>, rec: bool },
List => { items: Vec<Ir> },
HasAttr => { lhs: Box<Ir>, rhs: Vec<Attr> },
BinOp => { lhs: Box<Ir>, rhs: Box<Ir>, kind: BinOpKind },
@@ -111,7 +113,7 @@ ir! {
Assert => { assertion: Box<Ir>, expr: Box<Ir> },
ConcatStrings => { parts: Vec<Ir> },
Const => { value: i::Const },
Var => { sym: EcoString },
Var => { sym: usize },
#[derive(Copy)]
Thunk => { idx: usize },
Path => { expr: Box<Ir> },
@@ -125,11 +127,15 @@ pub struct DowngradeContext {
thunks: Vec<Ir>,
funcs: Vec<Func>,
consts: Vec<i::Const>,
symbols: Vec<EcoString>,
symmap: HashMap<EcoString, usize>,
}
pub struct Downgraded {
pub top_level: Ir,
pub consts: Box<[i::Const]>,
pub symbols: Vec<EcoString>,
pub symmap: HashMap<EcoString, usize>,
pub thunks: Box<[Ir]>,
pub funcs: Box<[Func]>,
}
@@ -150,6 +156,17 @@ impl DowngradeContext {
self.funcs.push(func);
LoadFunc { idx }
}
fn new_sym(&mut self, sym: impl Into<EcoString>) -> usize {
let sym = sym.into();
if let Some(&idx) = self.symmap.get(&sym) {
idx
} else {
self.symmap.insert(sym.clone(), self.symbols.len());
self.symbols.push(sym);
self.symbols.len() - 1
}
}
}
impl Attrs {
@@ -231,7 +248,7 @@ impl Attrs {
match path.next() {
Some(Attr::Str(ident)) => self
.stcs
.get(ident.as_str())
.get(ident)
.and_then(|attrs| attrs.downcast_ref())
.map_or(Some(false), |attrs: &Attrs| attrs._has_attr(path, name)),
None => match name {
@@ -253,7 +270,7 @@ impl Attrs {
pub enum Attr {
Dynamic(Ir),
Strs(ConcatStrings),
Str(EcoString),
Str(usize),
}
#[derive(Clone, Debug)]
@@ -327,11 +344,11 @@ pub struct Func {
#[derive(Clone, Debug)]
pub enum Param {
Ident(EcoString),
Ident(usize),
Formals {
formals: Vec<(EcoString, Option<Thunk>)>,
formals: Vec<(usize, Option<Thunk>)>,
ellipsis: bool,
alias: Option<EcoString>,
alias: Option<usize>,
},
}
@@ -460,9 +477,9 @@ impl Downgrade for ast::Literal {
}
impl Downgrade for ast::Ident {
fn downgrade(self, _ctx: &mut DowngradeContext) -> Result<Ir> {
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
Var {
sym: self.to_string().into(),
sym: ctx.new_sym(self.to_string()),
}
.ir()
.ok()
@@ -547,7 +564,7 @@ impl Downgrade for ast::LegacyLet {
let attrs = downgrade_has_entry(self, true, ctx)?;
Select {
expr: attrs.ir().boxed(),
attrpath: vec![Attr::Str("body".to_string().into())],
attrpath: vec![Attr::Str(ctx.new_sym("body".to_string()))],
default: None,
}
.ir()
@@ -603,7 +620,7 @@ impl Downgrade for ast::Apply {
fn downgrade_param(param: ast::Param, ctx: &mut DowngradeContext) -> Result<Param> {
match param {
ast::Param::IdentParam(ident) => Ok(Param::Ident(ident.to_string().into())),
ast::Param::IdentParam(ident) => Ok(Param::Ident(ctx.new_sym(ident.to_string()))),
ast::Param::Pattern(pattern) => downgrade_pattern(pattern, ctx),
}
}
@@ -612,7 +629,7 @@ fn downgrade_pattern(pattern: ast::Pattern, ctx: &mut DowngradeContext) -> Resul
let formals = pattern
.pat_entries()
.map(|entry| {
let ident = entry.ident().unwrap().to_string().into();
let ident = ctx.new_sym(entry.ident().unwrap().to_string());
if entry.default().is_none() {
Ok((ident, None))
} else {
@@ -627,7 +644,7 @@ fn downgrade_pattern(pattern: ast::Pattern, ctx: &mut DowngradeContext) -> Resul
let ellipsis = pattern.ellipsis_token().is_some();
let alias = pattern
.pat_bind()
.map(|alias| alias.ident().unwrap().to_string().into());
.map(|alias| ctx.new_sym(alias.ident().unwrap().to_string()));
Ok(Param::Formals {
formals,
ellipsis,
@@ -659,7 +676,7 @@ fn downgrade_has_entry(
fn downgrade_inherit(
inherit: ast::Inherit,
stcs: &mut HashMap<EcoString, Ir>,
stcs: &mut HashMap<usize, Ir>,
ctx: &mut DowngradeContext,
) -> Result<()> {
let from = if let Some(from) = inherit.from() {
@@ -669,8 +686,8 @@ fn downgrade_inherit(
None
};
for attr in inherit.attrs() {
let ident: EcoString = match downgrade_attr(attr, ctx)? {
Attr::Str(ident) => ident.to_string().into(),
let ident = match downgrade_attr(attr, ctx)? {
Attr::Str(ident) => ctx.new_sym(ident.to_string()),
_ => {
return Err(Error::DowngradeError(
"dynamic attributes not allowed in inherit".to_string(),
@@ -678,11 +695,11 @@ fn downgrade_inherit(
}
};
let expr = from.map_or_else(
|| Var { sym: ident.clone() }.ir().ok(),
|| Var { sym: ident }.ir().ok(),
|from| {
Ok(Select {
expr: from.ir().boxed(),
attrpath: vec![Attr::Str(ident.clone())],
attrpath: vec![Attr::Str(ident)],
default: None,
}
.ir())
@@ -697,14 +714,14 @@ fn downgrade_attr(attr: ast::Attr, ctx: &mut DowngradeContext) -> Result<Attr> {
use ast::Attr::*;
use ast::InterpolPart::*;
match attr {
Ident(ident) => Ok(Attr::Str(ident.to_string().into())),
Ident(ident) => Ok(Attr::Str(ctx.new_sym(ident.to_string()))),
Str(string) => {
let parts = string.normalized_parts();
if parts.len() == 0 {
Ok(Attr::Str("".into()))
Ok(Attr::Str(ctx.new_sym("")))
} else if parts.len() == 1 {
match parts.into_iter().next().unwrap() {
Literal(ident) => Ok(Attr::Str(ident.into())),
Literal(ident) => Ok(Attr::Str(ctx.new_sym(ident))),
Interpolation(interpol) => {
Ok(Attr::Dynamic(interpol.expr().unwrap().downgrade(ctx)?))
}