fix: maybe_thunk
This commit is contained in:
@@ -11,7 +11,7 @@ use crate::codegen::{CodegenContext, compile};
|
||||
use crate::error::{Error, Result, Source};
|
||||
use crate::ir::{
|
||||
Arg, ArgId, Bool, Builtin, Downgrade as _, DowngradeContext, ExprId, ExprRef, Ir, Null, SymId,
|
||||
ToIr as _, synthetic_span,
|
||||
Thunk, ToIr as _, synthetic_span,
|
||||
};
|
||||
use crate::runtime::{Runtime, RuntimeContext};
|
||||
use crate::store::{StoreBackend, StoreConfig};
|
||||
@@ -351,6 +351,34 @@ impl DowngradeContext for DowngradeCtx<'_> {
|
||||
ExprId(self.ctx.irs.len() + self.irs.len() - 1)
|
||||
}
|
||||
|
||||
fn maybe_thunk(&mut self, id: ExprId) -> ExprId {
|
||||
let ir = if id.0 < self.ctx.irs.len() {
|
||||
self.ctx.irs.get(id.0).expect("unreachable")
|
||||
} else {
|
||||
self.irs
|
||||
.get(id.0 - self.ctx.irs.len())
|
||||
.expect("ExprId out of bounds")
|
||||
.as_ref()
|
||||
.expect("maybe_thunk called on an extracted expr")
|
||||
};
|
||||
match ir {
|
||||
Ir::Builtin(_)
|
||||
| Ir::Builtins(_)
|
||||
| Ir::Int(_)
|
||||
| Ir::Float(_)
|
||||
| Ir::Bool(_)
|
||||
| Ir::Null(_)
|
||||
| Ir::Str(_) => id,
|
||||
_ => self.new_expr(
|
||||
Thunk {
|
||||
inner: id,
|
||||
span: ir.span(),
|
||||
}
|
||||
.to_ir(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_sym(&mut self, sym: String) -> SymId {
|
||||
self.ctx.symbols.get_or_intern(sym)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ pub trait DowngradeContext {
|
||||
|
||||
fn new_expr(&mut self, expr: Ir) -> ExprId;
|
||||
fn new_arg(&mut self, span: TextRange) -> ExprId;
|
||||
fn maybe_thunk(&mut self, id: ExprId) -> ExprId;
|
||||
|
||||
fn new_sym(&mut self, sym: String) -> SymId;
|
||||
fn get_sym(&self, id: SymId) -> &str;
|
||||
|
||||
@@ -121,7 +121,8 @@ impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::Str {
|
||||
.map(|part| match part {
|
||||
ast::InterpolPart::Literal(lit) => Ok(ctx.new_expr(Str { val: lit, span }.to_ir())),
|
||||
ast::InterpolPart::Interpolation(interpol) => {
|
||||
interpol.expr().unwrap().downgrade(ctx)
|
||||
let inner = interpol.expr().unwrap().downgrade(ctx)?;
|
||||
Ok(ctx.new_expr(Thunk { inner, span }.to_ir()))
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
@@ -210,7 +211,10 @@ impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::List {
|
||||
fn downgrade(self, ctx: &mut Ctx) -> Result<ExprId> {
|
||||
let items = self
|
||||
.items()
|
||||
.map(|item| maybe_thunk(item, ctx))
|
||||
.map(|item| {
|
||||
let id = item.downgrade(ctx)?;
|
||||
Ok(ctx.maybe_thunk(id))
|
||||
})
|
||||
.collect::<Result<_>>()?;
|
||||
let span = self.syntax().text_range();
|
||||
Ok(ctx.new_expr(List { items, span }.to_ir()))
|
||||
@@ -439,7 +443,8 @@ impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::Lambda {
|
||||
impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::Apply {
|
||||
fn downgrade(self, ctx: &mut Ctx) -> Result<ExprId> {
|
||||
let func = self.lambda().unwrap().downgrade(ctx)?;
|
||||
let arg = maybe_thunk(self.argument().unwrap(), ctx)?;
|
||||
let arg = self.argument().unwrap().downgrade(ctx)?;
|
||||
let arg = ctx.maybe_thunk(arg);
|
||||
let span = self.syntax().text_range();
|
||||
Ok(ctx.new_expr(Call { func, arg, span }.to_ir()))
|
||||
}
|
||||
|
||||
@@ -13,57 +13,6 @@ use crate::value::format_symbol;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn maybe_thunk(mut expr: ast::Expr, ctx: &mut impl DowngradeContext) -> Result<ExprId> {
|
||||
use ast::Expr::*;
|
||||
let expr = loop {
|
||||
expr = match expr {
|
||||
Paren(paren) => paren.expr().unwrap(),
|
||||
Root(root) => root.expr().unwrap(),
|
||||
expr => break expr,
|
||||
}
|
||||
};
|
||||
match expr {
|
||||
Error(error) => {
|
||||
let span = error.syntax().text_range();
|
||||
return Err(self::Error::downgrade_error(error.to_string())
|
||||
.with_span(span)
|
||||
.with_source(ctx.get_current_source()));
|
||||
}
|
||||
Ident(ident) => return ident.downgrade(ctx),
|
||||
Literal(lit) => return lit.downgrade(ctx),
|
||||
Str(str) => return str.downgrade(ctx),
|
||||
Path(path) => return path.downgrade(ctx),
|
||||
|
||||
_ => (),
|
||||
}
|
||||
let id = match expr {
|
||||
Apply(apply) => apply.downgrade(ctx),
|
||||
Assert(assert) => assert.downgrade(ctx),
|
||||
IfElse(ifelse) => ifelse.downgrade(ctx),
|
||||
Select(select) => select.downgrade(ctx),
|
||||
Lambda(lambda) => lambda.downgrade(ctx),
|
||||
LegacyLet(let_) => let_.downgrade(ctx),
|
||||
LetIn(letin) => letin.downgrade(ctx),
|
||||
List(list) => list.downgrade(ctx),
|
||||
BinOp(op) => op.downgrade(ctx),
|
||||
AttrSet(attrs) => attrs.downgrade(ctx),
|
||||
UnaryOp(op) => op.downgrade(ctx),
|
||||
With(with) => with.downgrade(ctx),
|
||||
HasAttr(has) => has.downgrade(ctx),
|
||||
|
||||
_ => unreachable!(),
|
||||
}?;
|
||||
Ok(ctx.new_expr(
|
||||
Thunk {
|
||||
inner: id,
|
||||
// span: ctx.get_span(id),
|
||||
// FIXME: span
|
||||
span: synthetic_span(),
|
||||
}
|
||||
.to_ir(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Downgrades the entries of an attribute set.
|
||||
/// This handles `inherit` and `attrpath = value;` entries.
|
||||
pub fn downgrade_attrs(
|
||||
@@ -231,7 +180,8 @@ pub fn downgrade_attrpathvalue(
|
||||
ctx: &mut impl DowngradeContext,
|
||||
) -> Result<()> {
|
||||
let path = downgrade_attrpath(value.attrpath().unwrap(), ctx)?;
|
||||
let value = maybe_thunk(value.value().unwrap(), ctx)?;
|
||||
let value = value.value().unwrap().downgrade(ctx)?;
|
||||
let value = ctx.maybe_thunk(value);
|
||||
attrs.insert(path, value, ctx)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user