feat: at least it compiles, right?

This commit is contained in:
2025-06-12 20:12:31 +08:00
parent 7293cb9f75
commit 49255948ff
22 changed files with 383 additions and 251 deletions

View File

@@ -99,7 +99,7 @@ macro_rules! ir {
}
impl Evaluate for Ir {
fn eval(self, engine: &Engine, env: &VmEnv) -> Result<Value> {
fn eval(self, engine: &mut Engine, env: &mut VmEnv) -> Result<Value> {
match self {
$(Ir::$ty(ir) => ir.eval(engine, env),)*
}
@@ -182,6 +182,8 @@ pub struct DowngradeContext {
struct Env<'a, 'env> {
env: EnvNode<'a>,
prev: Option<&'env Env<'a, 'env>>,
arg_level: usize,
let_level: usize
}
enum EnvNode<'a> {
@@ -205,6 +207,8 @@ impl<'a, 'env> Env<'a, 'env> {
Self {
env: EnvNode::Builtins(base),
prev: None,
arg_level: 0,
let_level: 0
}
}
@@ -212,6 +216,8 @@ impl<'a, 'env> Env<'a, 'env> {
Self {
env: EnvNode::Let(map),
prev: Some(self),
arg_level: self.arg_level,
let_level: self.let_level + 1
}
}
@@ -219,6 +225,8 @@ impl<'a, 'env> Env<'a, 'env> {
Self {
env: EnvNode::SingleArg(ident),
prev: Some(self),
arg_level: self.arg_level + 1,
let_level: self.let_level
}
}
@@ -230,6 +238,8 @@ impl<'a, 'env> Env<'a, 'env> {
Self {
env: EnvNode::MultiArg(map, alias),
prev: Some(self),
arg_level: self.arg_level + 1,
let_level: 0
}
}
@@ -237,6 +247,8 @@ impl<'a, 'env> Env<'a, 'env> {
Self {
env: EnvNode::With,
prev: Some(self),
arg_level: self.arg_level,
let_level: self.let_level
}
}
@@ -262,30 +274,30 @@ impl<'a, 'env> Env<'a, 'env> {
Let(map) => {
if let Ok(idx) = map.binary_search(ident) {
return Ok(LookupResult::Let {
level: let_level,
level: let_level - 1,
idx,
});
} else {
let_level += 1;
let_level -= 1;
}
}
SingleArg(arg) => {
if arg == ident {
return Ok(LookupResult::SingleArg { level: arg_level });
return Ok(LookupResult::SingleArg { level: arg_level - 1 });
} else {
arg_level += 1;
arg_level -= 1;
}
}
MultiArg(set, alias) => {
if let Some(default) = set.get(ident) {
return Ok(LookupResult::MultiArg {
level: arg_level,
level: arg_level - 1,
default: default.clone(),
});
} else if alias.as_ref() == Some(ident) {
return Ok(LookupResult::SingleArg { level: arg_level });
return Ok(LookupResult::SingleArg { level: arg_level - 1 });
} else {
arg_level += 1;
arg_level -= 1;
}
}
With => has_with = true,
@@ -296,7 +308,7 @@ impl<'a, 'env> Env<'a, 'env> {
}
fn lookup(&self, ident: &EcoString) -> core::result::Result<LookupResult, ()> {
self._lookup(ident, 0, 0, false)
self._lookup(ident, self.arg_level, self.let_level, false)
}
}
@@ -367,30 +379,25 @@ impl Attrs {
) -> Result<()> {
if let Some(attr) = path.next() {
match attr {
Attr::Str(ident) => {
if self.stcs.get(&ident).is_some() {
self.stcs
.get_mut(&ident)
.unwrap()
.as_mut()
.try_unwrap_attrs()
.map_err(|_| {
Error::DowngradeError(format!(
r#"attribute '{}' already defined"#,
Symbol::from(ident)
))
})
.and_then(|attrs: &mut Attrs| attrs._insert(path, name, value, ctx))
} else {
let mut attrs = Attrs {
Attr::Str(ident) => self
.stcs
.entry(ident.clone())
.or_insert_with(|| {
Attrs {
stcs: HashMap::new(),
dyns: Vec::new(),
};
attrs._insert(path, name, value, ctx)?;
assert!(self.stcs.insert(ident, attrs.ir()).is_none());
Ok(())
}
}
}
.ir()
})
.as_mut()
.try_unwrap_attrs()
.map_err(|_| {
Error::DowngradeError(format!(
r#"attribute '{}' already defined"#,
Symbol::from(ident)
))
})
.and_then(|attrs: &mut Attrs| attrs._insert(path, name, value, ctx)),
Attr::Strs(string) => {
let mut attrs = Attrs {
stcs: HashMap::new(),
@@ -413,13 +420,12 @@ impl Attrs {
} else {
match name {
Attr::Str(ident) => {
if self.stcs.get(&ident).is_some() {
if self.stcs.insert(ident.clone(), value).is_some() {
return Err(Error::DowngradeError(format!(
r#"attribute '{}' already defined"#,
Symbol::from(ident)
)));
}
self.stcs.insert(ident, value);
}
Attr::Strs(string) => {
self.dyns.push(DynamicAttrPair(string.ir(), value));

View File

@@ -2,7 +2,6 @@ use rnix::ast;
use super::*;
pub fn downgrade_param(param: ast::Param, ctx: &mut DowngradeContext) -> Result<Param> {
match param {
ast::Param::IdentParam(ident) => Ok(Param::Ident(ident.to_string().into())),
@@ -122,7 +121,10 @@ pub fn downgrade_attr(attr: ast::Attr, ctx: &mut DowngradeContext) -> Result<Att
}
}
pub fn downgrade_attrpath(attrpath: ast::Attrpath, ctx: &mut DowngradeContext) -> Result<Vec<Attr>> {
pub fn downgrade_attrpath(
attrpath: ast::Attrpath,
ctx: &mut DowngradeContext,
) -> Result<Vec<Attr>> {
attrpath
.attrs()
.map(|attr| downgrade_attr(attr, ctx))