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::error::{Error, Result, Source};
|
||||||
use crate::ir::{
|
use crate::ir::{
|
||||||
Arg, ArgId, Bool, Builtin, Downgrade as _, DowngradeContext, ExprId, ExprRef, Ir, Null, SymId,
|
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::runtime::{Runtime, RuntimeContext};
|
||||||
use crate::store::{StoreBackend, StoreConfig};
|
use crate::store::{StoreBackend, StoreConfig};
|
||||||
@@ -351,6 +351,34 @@ impl DowngradeContext for DowngradeCtx<'_> {
|
|||||||
ExprId(self.ctx.irs.len() + self.irs.len() - 1)
|
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 {
|
fn new_sym(&mut self, sym: String) -> SymId {
|
||||||
self.ctx.symbols.get_or_intern(sym)
|
self.ctx.symbols.get_or_intern(sym)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ pub trait DowngradeContext {
|
|||||||
|
|
||||||
fn new_expr(&mut self, expr: Ir) -> ExprId;
|
fn new_expr(&mut self, expr: Ir) -> ExprId;
|
||||||
fn new_arg(&mut self, span: TextRange) -> 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 new_sym(&mut self, sym: String) -> SymId;
|
||||||
fn get_sym(&self, id: SymId) -> &str;
|
fn get_sym(&self, id: SymId) -> &str;
|
||||||
|
|||||||
@@ -121,7 +121,8 @@ impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::Str {
|
|||||||
.map(|part| match part {
|
.map(|part| match part {
|
||||||
ast::InterpolPart::Literal(lit) => Ok(ctx.new_expr(Str { val: lit, span }.to_ir())),
|
ast::InterpolPart::Literal(lit) => Ok(ctx.new_expr(Str { val: lit, span }.to_ir())),
|
||||||
ast::InterpolPart::Interpolation(interpol) => {
|
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<_>>>()?;
|
.collect::<Result<Vec<_>>>()?;
|
||||||
@@ -210,7 +211,10 @@ impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::List {
|
|||||||
fn downgrade(self, ctx: &mut Ctx) -> Result<ExprId> {
|
fn downgrade(self, ctx: &mut Ctx) -> Result<ExprId> {
|
||||||
let items = self
|
let items = self
|
||||||
.items()
|
.items()
|
||||||
.map(|item| maybe_thunk(item, ctx))
|
.map(|item| {
|
||||||
|
let id = item.downgrade(ctx)?;
|
||||||
|
Ok(ctx.maybe_thunk(id))
|
||||||
|
})
|
||||||
.collect::<Result<_>>()?;
|
.collect::<Result<_>>()?;
|
||||||
let span = self.syntax().text_range();
|
let span = self.syntax().text_range();
|
||||||
Ok(ctx.new_expr(List { items, span }.to_ir()))
|
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 {
|
impl<Ctx: DowngradeContext> Downgrade<Ctx> for ast::Apply {
|
||||||
fn downgrade(self, ctx: &mut Ctx) -> Result<ExprId> {
|
fn downgrade(self, ctx: &mut Ctx) -> Result<ExprId> {
|
||||||
let func = self.lambda().unwrap().downgrade(ctx)?;
|
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();
|
let span = self.syntax().text_range();
|
||||||
Ok(ctx.new_expr(Call { func, arg, span }.to_ir()))
|
Ok(ctx.new_expr(Call { func, arg, span }.to_ir()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,57 +13,6 @@ use crate::value::format_symbol;
|
|||||||
|
|
||||||
use super::*;
|
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.
|
/// Downgrades the entries of an attribute set.
|
||||||
/// This handles `inherit` and `attrpath = value;` entries.
|
/// This handles `inherit` and `attrpath = value;` entries.
|
||||||
pub fn downgrade_attrs(
|
pub fn downgrade_attrs(
|
||||||
@@ -231,7 +180,8 @@ pub fn downgrade_attrpathvalue(
|
|||||||
ctx: &mut impl DowngradeContext,
|
ctx: &mut impl DowngradeContext,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let path = downgrade_attrpath(value.attrpath().unwrap(), ctx)?;
|
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)
|
attrs.insert(path, value, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user