feat: less clone on symbol
This commit is contained in:
59
src/ir.rs
59
src/ir.rs
@@ -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)?))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user