refactor: function
This commit is contained in:
243
src/ir.rs
243
src/ir.rs
@@ -3,18 +3,21 @@ use std::collections::HashMap;
|
||||
use ecow::EcoString;
|
||||
use rnix::ast::{self, Expr};
|
||||
|
||||
use crate::bytecode::{ConstIdx, Consts, ThunkIdx};
|
||||
use crate::bytecode::{Consts, ThunkIdx, FuncIdx};
|
||||
use crate::compile::*;
|
||||
#[cfg(feature = "jit")]
|
||||
use crate::jit::*;
|
||||
use crate::error::*;
|
||||
use crate::ty::internal as i;
|
||||
|
||||
pub fn downgrade(expr: Expr) -> Result<Downgraded> {
|
||||
let mut state = DowngradeState::new();
|
||||
let ir = expr.downgrade(&mut state)?;
|
||||
let mut ctx = DowngradeContext::new();
|
||||
let ir = expr.downgrade(&mut ctx)?;
|
||||
Ok(Downgraded {
|
||||
top_level: ir,
|
||||
consts: state.consts.into(),
|
||||
thunks: state.thunks.into(),
|
||||
consts: ctx.consts.into(),
|
||||
thunks: ctx.thunks.into(),
|
||||
funcs: ctx.funcs.into()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -24,7 +27,6 @@ where
|
||||
{
|
||||
fn downcast_ref(&self) -> Option<&T>;
|
||||
fn downcast_mut(&mut self) -> Option<&mut T>;
|
||||
fn downcast(self) -> core::result::Result<T, Self>;
|
||||
}
|
||||
|
||||
macro_rules! ir {
|
||||
@@ -54,9 +56,18 @@ macro_rules! ir {
|
||||
}
|
||||
|
||||
impl Compile for Ir {
|
||||
fn compile(self, state: &mut Compiler) {
|
||||
fn compile(self, ctx: &mut Compiler) {
|
||||
match self {
|
||||
$(Ir::$ty(ir) => ir.compile(state),)*
|
||||
$(Ir::$ty(ir) => ir.compile(ctx),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "jit")]
|
||||
impl CodeGen for Ir {
|
||||
fn codegen(self, ctx: &JITContext<'_>) {
|
||||
match self {
|
||||
$(Ir::$ty(ir) => ir.codegen(ctx),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,12 +102,6 @@ macro_rules! ir {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn downcast(self) -> core::result::Result<$ty, Self> {
|
||||
match self {
|
||||
Ir::$ty(value) => Ok(value),
|
||||
_ => Err(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
@@ -110,7 +115,7 @@ ir! {
|
||||
UnOp => { rhs: Box<Ir>, kind: UnOpKind },
|
||||
Select => { expr: Box<Ir>, attrpath: Vec<Attr>, default: Option<Box<Ir>> },
|
||||
If => { cond: Box<Ir>, consq: Box<Ir>, alter: Box<Ir> },
|
||||
Func => { param: Param, body: Thunk },
|
||||
LoadFunc => { idx: FuncIdx },
|
||||
Call => { func: Box<Ir>, args: Vec<Ir> },
|
||||
|
||||
Let => { attrs: Attrs, expr: Box<Ir> },
|
||||
@@ -127,25 +132,23 @@ ir! {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DynamicAttrPair(pub Ir, pub Ir);
|
||||
|
||||
pub struct DowngradeState {
|
||||
#[derive(Default)]
|
||||
pub struct DowngradeContext {
|
||||
thunks: Vec<Ir>,
|
||||
funcs: Vec<Func>,
|
||||
consts: Vec<i::Const>,
|
||||
consts_table: HashMap<i::Const, ConstIdx>,
|
||||
}
|
||||
|
||||
pub struct Downgraded {
|
||||
pub top_level: Ir,
|
||||
pub consts: Consts,
|
||||
pub thunks: Box<[Ir]>,
|
||||
pub funcs: Box<[Func]>
|
||||
}
|
||||
|
||||
impl DowngradeState {
|
||||
fn new() -> DowngradeState {
|
||||
DowngradeState {
|
||||
thunks: Vec::new(),
|
||||
consts: Vec::new(),
|
||||
consts_table: HashMap::new(),
|
||||
}
|
||||
impl DowngradeContext {
|
||||
fn new() -> DowngradeContext {
|
||||
DowngradeContext::default()
|
||||
}
|
||||
|
||||
fn new_thunk(&mut self, thunk: Ir) -> Thunk {
|
||||
@@ -154,8 +157,10 @@ impl DowngradeState {
|
||||
Thunk { idx }
|
||||
}
|
||||
|
||||
fn lookup_thunk(&self, idx: ThunkIdx) -> &Ir {
|
||||
self.thunks.get(idx).unwrap()
|
||||
fn new_func(&mut self, func: Func) -> LoadFunc {
|
||||
let idx = self.funcs.len();
|
||||
self.funcs.push(func);
|
||||
LoadFunc { idx }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +174,7 @@ impl Attrs {
|
||||
.get_mut(&ident)
|
||||
.unwrap()
|
||||
.downcast_mut()
|
||||
.ok_or(Error::DowngradeError(format!(
|
||||
.ok_or_else(|| Error::DowngradeError(format!(
|
||||
r#""{ident}" already exsists in this set"#
|
||||
)))
|
||||
.and_then(|attrs: &mut Attrs| attrs._insert(path, name, value))
|
||||
@@ -320,6 +325,11 @@ impl From<ast::UnaryOpKind> for UnOpKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Func {
|
||||
pub param: Param,
|
||||
pub body: Box<Ir>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Param {
|
||||
Ident(EcoString),
|
||||
@@ -334,41 +344,41 @@ trait Downgrade
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir>;
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir>;
|
||||
}
|
||||
|
||||
impl Downgrade for Expr {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
match self {
|
||||
Expr::Apply(apply) => apply.downgrade(state),
|
||||
Expr::Assert(assert) => assert.downgrade(state),
|
||||
Expr::Apply(apply) => apply.downgrade(ctx),
|
||||
Expr::Assert(assert) => assert.downgrade(ctx),
|
||||
Expr::Error(error) => Err(Error::DowngradeError(error.to_string())),
|
||||
Expr::IfElse(ifelse) => ifelse.downgrade(state),
|
||||
Expr::Select(select) => select.downgrade(state),
|
||||
Expr::Str(str) => str.downgrade(state),
|
||||
Expr::Path(path) => path.downgrade(state),
|
||||
Expr::Literal(lit) => lit.downgrade(state),
|
||||
Expr::Lambda(lambda) => lambda.downgrade(state),
|
||||
Expr::LegacyLet(let_) => let_.downgrade(state),
|
||||
Expr::LetIn(letin) => letin.downgrade(state),
|
||||
Expr::List(list) => list.downgrade(state),
|
||||
Expr::BinOp(op) => op.downgrade(state),
|
||||
Expr::Paren(paren) => paren.expr().unwrap().downgrade(state),
|
||||
Expr::Root(root) => root.expr().unwrap().downgrade(state),
|
||||
Expr::AttrSet(attrs) => attrs.downgrade(state),
|
||||
Expr::UnaryOp(op) => op.downgrade(state),
|
||||
Expr::Ident(ident) => ident.downgrade(state),
|
||||
Expr::With(with) => with.downgrade(state),
|
||||
Expr::HasAttr(has) => has.downgrade(state),
|
||||
Expr::IfElse(ifelse) => ifelse.downgrade(ctx),
|
||||
Expr::Select(select) => select.downgrade(ctx),
|
||||
Expr::Str(str) => str.downgrade(ctx),
|
||||
Expr::Path(path) => path.downgrade(ctx),
|
||||
Expr::Literal(lit) => lit.downgrade(ctx),
|
||||
Expr::Lambda(lambda) => lambda.downgrade(ctx),
|
||||
Expr::LegacyLet(let_) => let_.downgrade(ctx),
|
||||
Expr::LetIn(letin) => letin.downgrade(ctx),
|
||||
Expr::List(list) => list.downgrade(ctx),
|
||||
Expr::BinOp(op) => op.downgrade(ctx),
|
||||
Expr::Paren(paren) => paren.expr().unwrap().downgrade(ctx),
|
||||
Expr::Root(root) => root.expr().unwrap().downgrade(ctx),
|
||||
Expr::AttrSet(attrs) => attrs.downgrade(ctx),
|
||||
Expr::UnaryOp(op) => op.downgrade(ctx),
|
||||
Expr::Ident(ident) => ident.downgrade(ctx),
|
||||
Expr::With(with) => with.downgrade(ctx),
|
||||
Expr::HasAttr(has) => has.downgrade(ctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Assert {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
Assert {
|
||||
assertion: self.condition().unwrap().downgrade(state)?.boxed(),
|
||||
expr: self.body().unwrap().downgrade(state)?.boxed(),
|
||||
assertion: self.condition().unwrap().downgrade(ctx)?.boxed(),
|
||||
expr: self.body().unwrap().downgrade(ctx)?.boxed(),
|
||||
}
|
||||
.ir()
|
||||
.ok()
|
||||
@@ -376,11 +386,11 @@ impl Downgrade for ast::Assert {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::IfElse {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
If {
|
||||
cond: self.condition().unwrap().downgrade(state)?.boxed(),
|
||||
consq: self.body().unwrap().downgrade(state)?.boxed(),
|
||||
alter: self.else_body().unwrap().downgrade(state)?.boxed(),
|
||||
cond: self.condition().unwrap().downgrade(ctx)?.boxed(),
|
||||
consq: self.body().unwrap().downgrade(ctx)?.boxed(),
|
||||
alter: self.else_body().unwrap().downgrade(ctx)?.boxed(),
|
||||
}
|
||||
.ir()
|
||||
.ok()
|
||||
@@ -388,7 +398,7 @@ impl Downgrade for ast::IfElse {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Path {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let parts = self
|
||||
.parts()
|
||||
.map(|part| match part {
|
||||
@@ -398,7 +408,7 @@ impl Downgrade for ast::Path {
|
||||
.ir()
|
||||
.ok(),
|
||||
ast::InterpolPart::Interpolation(interpol) => {
|
||||
interpol.expr().unwrap().downgrade(state)
|
||||
interpol.expr().unwrap().downgrade(ctx)
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
@@ -417,14 +427,14 @@ impl Downgrade for ast::Path {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Str {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let parts = self
|
||||
.normalized_parts()
|
||||
.into_iter()
|
||||
.map(|part| match part {
|
||||
ast::InterpolPart::Literal(lit) => Const { value: lit.into() }.ir().ok(),
|
||||
ast::InterpolPart::Interpolation(interpol) => {
|
||||
interpol.expr().unwrap().downgrade(state)
|
||||
interpol.expr().unwrap().downgrade(ctx)
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
@@ -437,7 +447,7 @@ impl Downgrade for ast::Str {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Literal {
|
||||
fn downgrade(self, _state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, _ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
match self.kind() {
|
||||
ast::LiteralKind::Integer(int) => Const {
|
||||
value: int.value().unwrap().into(),
|
||||
@@ -455,7 +465,7 @@ impl Downgrade for ast::Literal {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Ident {
|
||||
fn downgrade(self, _state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, _ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
Var {
|
||||
sym: self.to_string().into(),
|
||||
}
|
||||
@@ -465,27 +475,27 @@ impl Downgrade for ast::Ident {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::AttrSet {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let rec = self.rec_token().is_some();
|
||||
downgrade_has_entry(self, rec, state).map(|attrs| attrs.ir())
|
||||
downgrade_has_entry(self, rec, ctx).map(|attrs| attrs.ir())
|
||||
}
|
||||
}
|
||||
|
||||
impl Downgrade for ast::List {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let mut items = Vec::with_capacity(self.items().size_hint().0);
|
||||
for item in self.items() {
|
||||
items.push(item.downgrade(state)?)
|
||||
items.push(item.downgrade(ctx)?)
|
||||
}
|
||||
List { items }.ir().ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl Downgrade for ast::BinOp {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
BinOp {
|
||||
lhs: self.lhs().unwrap().downgrade(state)?.boxed(),
|
||||
rhs: self.rhs().unwrap().downgrade(state)?.boxed(),
|
||||
lhs: self.lhs().unwrap().downgrade(ctx)?.boxed(),
|
||||
rhs: self.rhs().unwrap().downgrade(ctx)?.boxed(),
|
||||
kind: self.operator().unwrap().into(),
|
||||
}
|
||||
.ir()
|
||||
@@ -494,9 +504,9 @@ impl Downgrade for ast::BinOp {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::HasAttr {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
let attrs = self.expr().unwrap().downgrade(state)?;
|
||||
let path = downgrade_attrpath(self.attrpath().unwrap(), state)?;
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let attrs = self.expr().unwrap().downgrade(ctx)?;
|
||||
let path = downgrade_attrpath(self.attrpath().unwrap(), ctx)?;
|
||||
if let Some(attrs) = Downcast::<Attrs>::downcast_ref(&attrs) {
|
||||
if let Some(res) = attrs.has_attr(&path) {
|
||||
return Const { value: res.into() }.ir().ok();
|
||||
@@ -512,9 +522,9 @@ impl Downgrade for ast::HasAttr {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::UnaryOp {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
UnOp {
|
||||
rhs: self.expr().unwrap().downgrade(state)?.boxed(),
|
||||
rhs: self.expr().unwrap().downgrade(ctx)?.boxed(),
|
||||
kind: self.operator().unwrap().into(),
|
||||
}
|
||||
.ir()
|
||||
@@ -523,12 +533,12 @@ impl Downgrade for ast::UnaryOp {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Select {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
Select {
|
||||
expr: self.expr().unwrap().downgrade(state)?.boxed(),
|
||||
attrpath: downgrade_attrpath(self.attrpath().unwrap(), state)?,
|
||||
expr: self.expr().unwrap().downgrade(ctx)?.boxed(),
|
||||
attrpath: downgrade_attrpath(self.attrpath().unwrap(), ctx)?,
|
||||
default: match self.default_expr() {
|
||||
Some(default) => Some(default.downgrade(state)?.boxed()),
|
||||
Some(default) => Some(default.downgrade(ctx)?.boxed()),
|
||||
None => None,
|
||||
},
|
||||
}
|
||||
@@ -538,8 +548,8 @@ impl Downgrade for ast::Select {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::LegacyLet {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
let attrs = downgrade_has_entry(self, true, state)?;
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let attrs = downgrade_has_entry(self, true, ctx)?;
|
||||
Select {
|
||||
expr: attrs.ir().boxed(),
|
||||
attrpath: vec![Attr::Str("body".to_string().into())],
|
||||
@@ -551,60 +561,59 @@ impl Downgrade for ast::LegacyLet {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::LetIn {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let body = self.body().unwrap();
|
||||
let attrs = downgrade_has_entry(self, true, state)?;
|
||||
let expr = body.downgrade(state)?.boxed();
|
||||
let attrs = downgrade_has_entry(self, true, ctx)?;
|
||||
let expr = body.downgrade(ctx)?.boxed();
|
||||
Let { attrs, expr }.ir().ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl Downgrade for ast::With {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
let namespace = self.namespace().unwrap().downgrade(state)?;
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let namespace = self.namespace().unwrap().downgrade(ctx)?;
|
||||
if let Ir::Attrs(attrs) = namespace {
|
||||
let expr = self.body().unwrap().downgrade(state)?.boxed();
|
||||
let expr = self.body().unwrap().downgrade(ctx)?.boxed();
|
||||
Let { attrs, expr }.ir().ok()
|
||||
} else {
|
||||
let namespace = namespace.boxed();
|
||||
let expr = self.body().unwrap().downgrade(state)?.boxed();
|
||||
let expr = self.body().unwrap().downgrade(ctx)?.boxed();
|
||||
With { namespace, expr }.ir().ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Lambda {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let body = self.body().unwrap();
|
||||
let param = downgrade_param(self.param().unwrap(), state)?;
|
||||
let body = body.downgrade(state)?;
|
||||
let body = state.new_thunk(body);
|
||||
Func { param, body }.ir().ok()
|
||||
let param = downgrade_param(self.param().unwrap(), ctx)?;
|
||||
let body = body.downgrade(ctx)?.boxed();
|
||||
ctx.new_func(Func { param, body }).ir().ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Apply {
|
||||
fn downgrade(self, state: &mut DowngradeState) -> Result<Ir> {
|
||||
let mut args = vec![self.argument().unwrap().downgrade(state)?];
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let mut args = vec![self.argument().unwrap().downgrade(ctx)?];
|
||||
let mut func = self.lambda().unwrap();
|
||||
while let ast::Expr::Apply(call) = func {
|
||||
func = call.lambda().unwrap();
|
||||
args.push(call.argument().unwrap().downgrade(state)?);
|
||||
args.push(call.argument().unwrap().downgrade(ctx)?);
|
||||
}
|
||||
let func = func.downgrade(state)?.boxed();
|
||||
let func = func.downgrade(ctx)?.boxed();
|
||||
args.reverse();
|
||||
Call { func, args }.ir().ok()
|
||||
}
|
||||
}
|
||||
|
||||
fn downgrade_param(param: ast::Param, state: &mut DowngradeState) -> Result<Param> {
|
||||
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::Pattern(pattern) => downgrade_pattern(pattern, state),
|
||||
ast::Param::Pattern(pattern) => downgrade_pattern(pattern, ctx),
|
||||
}
|
||||
}
|
||||
|
||||
fn downgrade_pattern(pattern: ast::Pattern, state: &mut DowngradeState) -> Result<Param> {
|
||||
fn downgrade_pattern(pattern: ast::Pattern, ctx: &mut DowngradeContext) -> Result<Param> {
|
||||
let formals = pattern
|
||||
.pat_entries()
|
||||
.map(|entry| {
|
||||
@@ -615,8 +624,8 @@ fn downgrade_pattern(pattern: ast::Pattern, state: &mut DowngradeState) -> Resul
|
||||
entry
|
||||
.default()
|
||||
.unwrap()
|
||||
.downgrade(state)
|
||||
.map(|ok| (ident, Some(state.new_thunk(ok))))
|
||||
.downgrade(ctx)
|
||||
.map(|ok| (ident, Some(ctx.new_thunk(ok))))
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
@@ -634,7 +643,7 @@ fn downgrade_pattern(pattern: ast::Pattern, state: &mut DowngradeState) -> Resul
|
||||
fn downgrade_has_entry(
|
||||
has_entry: impl ast::HasEntry,
|
||||
rec: bool,
|
||||
state: &mut DowngradeState,
|
||||
ctx: &mut DowngradeContext,
|
||||
) -> Result<Attrs> {
|
||||
let entires = has_entry.entries();
|
||||
let mut attrs = Attrs {
|
||||
@@ -645,8 +654,8 @@ fn downgrade_has_entry(
|
||||
|
||||
for entry in entires {
|
||||
match entry {
|
||||
ast::Entry::Inherit(inherit) => downgrade_inherit(inherit, &mut attrs.stcs, state)?,
|
||||
ast::Entry::AttrpathValue(value) => downgrade_attrpathvalue(value, &mut attrs, state)?,
|
||||
ast::Entry::Inherit(inherit) => downgrade_inherit(inherit, &mut attrs.stcs, ctx)?,
|
||||
ast::Entry::AttrpathValue(value) => downgrade_attrpathvalue(value, &mut attrs, ctx)?,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,16 +665,16 @@ fn downgrade_has_entry(
|
||||
fn downgrade_inherit(
|
||||
inherit: ast::Inherit,
|
||||
stcs: &mut HashMap<EcoString, Ir>,
|
||||
state: &mut DowngradeState,
|
||||
ctx: &mut DowngradeContext,
|
||||
) -> Result<()> {
|
||||
let from = if let Some(from) = inherit.from() {
|
||||
let from = from.expr().unwrap().downgrade(state)?;
|
||||
Some(state.new_thunk(from))
|
||||
let from = from.expr().unwrap().downgrade(ctx)?;
|
||||
Some(ctx.new_thunk(from))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
for attr in inherit.attrs() {
|
||||
let ident: EcoString = match downgrade_attr(attr, state)? {
|
||||
let ident: EcoString = match downgrade_attr(attr, ctx)? {
|
||||
Attr::Str(ident) => ident.to_string().into(),
|
||||
_ => {
|
||||
return Err(Error::DowngradeError(
|
||||
@@ -689,7 +698,7 @@ fn downgrade_inherit(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn downgrade_attr(attr: ast::Attr, state: &mut DowngradeState) -> Result<Attr> {
|
||||
fn downgrade_attr(attr: ast::Attr, ctx: &mut DowngradeContext) -> Result<Attr> {
|
||||
use ast::Attr::*;
|
||||
use ast::InterpolPart::*;
|
||||
match attr {
|
||||
@@ -700,7 +709,7 @@ fn downgrade_attr(attr: ast::Attr, state: &mut DowngradeState) -> Result<Attr> {
|
||||
match parts.into_iter().next().unwrap() {
|
||||
Literal(ident) => Ok(Attr::Str(ident.into())),
|
||||
Interpolation(interpol) => {
|
||||
Ok(Attr::Dynamic(interpol.expr().unwrap().downgrade(state)?))
|
||||
Ok(Attr::Dynamic(interpol.expr().unwrap().downgrade(ctx)?))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -708,29 +717,29 @@ fn downgrade_attr(attr: ast::Attr, state: &mut DowngradeState) -> Result<Attr> {
|
||||
.into_iter()
|
||||
.map(|part| match part {
|
||||
Literal(lit) => Const { value: lit.into() }.ir().ok(),
|
||||
Interpolation(interpol) => interpol.expr().unwrap().downgrade(state),
|
||||
Interpolation(interpol) => interpol.expr().unwrap().downgrade(ctx),
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
Ok(Attr::Strs(ConcatStrings { parts }))
|
||||
}
|
||||
}
|
||||
Dynamic(dynamic) => Ok(Attr::Dynamic(dynamic.expr().unwrap().downgrade(state)?)),
|
||||
Dynamic(dynamic) => Ok(Attr::Dynamic(dynamic.expr().unwrap().downgrade(ctx)?)),
|
||||
}
|
||||
}
|
||||
|
||||
fn downgrade_attrpath(attrpath: ast::Attrpath, state: &mut DowngradeState) -> Result<Vec<Attr>> {
|
||||
fn downgrade_attrpath(attrpath: ast::Attrpath, ctx: &mut DowngradeContext) -> Result<Vec<Attr>> {
|
||||
attrpath
|
||||
.attrs()
|
||||
.map(|attr| downgrade_attr(attr, state))
|
||||
.map(|attr| downgrade_attr(attr, ctx))
|
||||
.collect::<Result<Vec<_>>>()
|
||||
}
|
||||
|
||||
fn downgrade_attrpathvalue(
|
||||
value: ast::AttrpathValue,
|
||||
attrs: &mut Attrs,
|
||||
state: &mut DowngradeState,
|
||||
ctx: &mut DowngradeContext,
|
||||
) -> Result<()> {
|
||||
let path = downgrade_attrpath(value.attrpath().unwrap(), state)?;
|
||||
let value = value.value().unwrap().downgrade(state)?;
|
||||
attrs.insert(path, state.new_thunk(value).ir())
|
||||
let path = downgrade_attrpath(value.attrpath().unwrap(), ctx)?;
|
||||
let value = value.value().unwrap().downgrade(ctx)?;
|
||||
attrs.insert(path, ctx.new_thunk(value).ir())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user