feat: a lot

This commit is contained in:
2025-08-06 18:30:19 +08:00
parent 32c602f21c
commit f946cb2fd1
22 changed files with 735 additions and 591 deletions

View File

@@ -24,12 +24,16 @@ ir! {
Str,
Var,
Path,
PrimOp,
ExprRef(ExprId),
FuncRef(ExprId),
ArgRef(ArgIdx),
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug)]
pub struct Builtins;
#[derive(Debug)]
pub enum LookupResult {
Expr(ExprId),
Arg(ArgIdx),
@@ -38,21 +42,17 @@ pub enum LookupResult {
}
pub trait ResolveContext {
fn new_dep(&mut self, expr: ExprId, dep: ExprId);
fn new_func(&mut self, body: ExprId, param: Param);
fn resolve(&mut self, expr: ExprId) -> Result<()>;
fn new_dep(&mut self, expr: &ExprId, dep: ExprId);
fn new_func(&mut self, body: &ExprId, param: Param);
fn resolve(&mut self, expr: &ExprId) -> Result<()>;
fn lookup(&self, name: &str) -> LookupResult;
fn with_with_env<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> (bool, T);
fn with_let_env<'a, T>(
&mut self,
bindings: impl IntoIterator<Item = (&'a String, &'a ExprId)>,
f: impl FnOnce(&mut Self) -> T,
) -> T;
fn with_param_env<'a, T>(
&mut self,
ident: Option<&'a str>,
bindings: impl Iterator<Item = (&'a String, &'a ExprId)>,
f: impl FnOnce(&mut Self) -> T,
) -> T;
fn with_param_env<T>(&mut self, ident: Option<String>, f: impl FnOnce(&mut Self) -> T) -> T;
}
pub trait Resolve<Ctx: ResolveContext> {
@@ -80,7 +80,7 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for hir::Hir {
Var(x) => x.resolve(ctx),
Path(x) => x.resolve(ctx),
Let(x) => x.resolve(ctx),
Arg(_) => todo!(),
Arg(_) => unsafe { Ok(Lir::ArgRef(ArgIdx::from(0))) },
}
}
}
@@ -90,10 +90,10 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for AttrSet {
if self.rec {
todo!()
} else {
for (_, &v) in self.stcs.iter() {
for (_, v) in self.stcs.iter() {
ctx.resolve(v)?;
}
for &(k, v) in self.dyns.iter() {
for (k, v) in self.dyns.iter() {
ctx.resolve(k)?;
ctx.resolve(v)?;
}
@@ -104,7 +104,7 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for AttrSet {
impl<Ctx: ResolveContext> Resolve<Ctx> for List {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
for &item in self.items.iter() {
for item in self.items.iter() {
ctx.resolve(item)?;
}
Ok(self.to_lir())
@@ -113,10 +113,10 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for List {
impl<Ctx: ResolveContext> Resolve<Ctx> for HasAttr {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.lhs)?;
ctx.resolve(&self.lhs)?;
for attr in self.rhs.iter() {
if let &Attr::Dynamic(expr) = attr {
ctx.resolve(expr)?;
if let Attr::Dynamic(expr) = attr {
ctx.resolve(&expr)?;
}
}
Ok(self.to_lir())
@@ -125,28 +125,28 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for HasAttr {
impl<Ctx: ResolveContext> Resolve<Ctx> for BinOp {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.lhs)?;
ctx.resolve(self.rhs)?;
ctx.resolve(&self.lhs)?;
ctx.resolve(&self.rhs)?;
Ok(self.to_lir())
}
}
impl<Ctx: ResolveContext> Resolve<Ctx> for UnOp {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.rhs)?;
ctx.resolve(&self.rhs)?;
Ok(self.to_lir())
}
}
impl<Ctx: ResolveContext> Resolve<Ctx> for Select {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.expr)?;
ctx.resolve(&self.expr)?;
for attr in self.attrpath.iter() {
if let &Attr::Dynamic(expr) = attr {
ctx.resolve(expr)?;
if let Attr::Dynamic(expr) = attr {
ctx.resolve(&expr)?;
}
}
if let Some(expr) = self.default {
if let Some(ref expr) = self.default {
ctx.resolve(expr)?;
}
Ok(self.to_lir())
@@ -155,25 +155,25 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for Select {
impl<Ctx: ResolveContext> Resolve<Ctx> for If {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.cond)?;
ctx.resolve(self.consq)?;
ctx.resolve(self.alter)?;
ctx.resolve(&self.cond)?;
ctx.resolve(&self.consq)?;
ctx.resolve(&self.alter)?;
Ok(self.to_lir())
}
}
impl<Ctx: ResolveContext> Resolve<Ctx> for Func {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.with_param_env(self.param.ident.as_deref(), |ctx| ctx.resolve(self.body))?;
ctx.new_func(self.body, self.param);
ctx.with_param_env(self.param.ident.clone(), |ctx| ctx.resolve(&self.body))?;
ctx.new_func(&self.body, self.param);
Ok(Lir::FuncRef(self.body))
}
}
impl<Ctx: ResolveContext> Resolve<Ctx> for Call {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.func)?;
for &arg in self.args.iter() {
ctx.resolve(&self.func)?;
for arg in self.args.iter() {
ctx.resolve(arg)?;
}
Ok(self.to_lir())
@@ -182,8 +182,8 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for Call {
impl<Ctx: ResolveContext> Resolve<Ctx> for With {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.namespace)?;
let (env_used, res) = ctx.with_with_env(|ctx| ctx.resolve(self.expr));
ctx.resolve(&self.namespace)?;
let (env_used, res) = ctx.with_with_env(|ctx| ctx.resolve(&self.expr));
res?;
if env_used {
Ok(self.to_lir())
@@ -195,15 +195,15 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for With {
impl<Ctx: ResolveContext> Resolve<Ctx> for Assert {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.assertion)?;
ctx.resolve(self.expr)?;
ctx.resolve(&self.assertion)?;
ctx.resolve(&self.expr)?;
Ok(self.to_lir())
}
}
impl<Ctx: ResolveContext> Resolve<Ctx> for ConcatStrings {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
for &part in self.parts.iter() {
for part in self.parts.iter() {
ctx.resolve(part)?;
}
Ok(self.to_lir())
@@ -227,7 +227,7 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for Var {
impl<Ctx: ResolveContext> Resolve<Ctx> for Path {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.resolve(self.expr)?;
ctx.resolve(&self.expr)?;
Ok(self.to_lir())
}
}
@@ -235,10 +235,10 @@ impl<Ctx: ResolveContext> Resolve<Ctx> for Path {
impl<Ctx: ResolveContext> Resolve<Ctx> for hir::Let {
fn resolve(self, ctx: &mut Ctx) -> Result<Lir> {
ctx.with_let_env(self.bindings.iter(), |ctx| {
for &id in self.bindings.values() {
for id in self.bindings.values() {
ctx.resolve(id)?;
}
ctx.resolve(self.body)
ctx.resolve(&self.body)
})?;
Ok(Lir::ExprRef(self.body))
}