-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7381b91
commit 87a02a8
Showing
7 changed files
with
321 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
use crate::ir; | ||
use crate::result::BackendError; | ||
|
||
use super::traits::ToIR; | ||
|
||
impl ToIR for ast::Module { | ||
type Target = ir::Module; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::Module { uri, use_decls, decls, meta_vars: _ } = self; | ||
|
||
let IRDecls { def_decls, codef_decls, let_decls } = to_ir_decls(decls)?; | ||
|
||
Ok(ir::Module { | ||
uri: uri.clone(), | ||
use_decls: use_decls.clone(), | ||
def_decls, | ||
codef_decls, | ||
let_decls, | ||
}) | ||
} | ||
} | ||
|
||
struct IRDecls { | ||
def_decls: Vec<ir::Def>, | ||
codef_decls: Vec<ir::Codef>, | ||
let_decls: Vec<ir::Let>, | ||
} | ||
|
||
fn to_ir_decls(decls: &[ast::Decl]) -> Result<IRDecls, BackendError> { | ||
let mut def_decls = Vec::new(); | ||
let mut codef_decls = Vec::new(); | ||
let mut let_decls = Vec::new(); | ||
|
||
for decl in decls { | ||
match decl { | ||
ast::Decl::Def(def) => { | ||
if let Some(def) = def.to_ir()? { | ||
def_decls.push(def); | ||
} | ||
} | ||
ast::Decl::Codef(codef) => codef_decls.push(codef.to_ir()?), | ||
ast::Decl::Let(tl_let) => { | ||
if let Some(tl_let) = tl_let.to_ir()? { | ||
let_decls.push(tl_let); | ||
} | ||
} | ||
ast::Decl::Data(_) => {} | ||
ast::Decl::Codata(_) => {} | ||
} | ||
} | ||
|
||
Ok(IRDecls { def_decls, codef_decls, let_decls }) | ||
} | ||
|
||
impl ToIR for ast::Def { | ||
type Target = Option<ir::Def>; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::Def { name, params, self_param, cases, .. } = self; | ||
|
||
let params = params | ||
.params | ||
.iter() | ||
.filter(|param| !param.erased) | ||
.map(|param| param.name.to_string()) | ||
.collect(); | ||
|
||
let cases = cases.to_ir()?; | ||
|
||
Ok(Some(ir::Def { | ||
name: name.to_string(), | ||
self_param: self_param.name.as_ref().map(|nm| nm.to_string()).unwrap_or_default(), | ||
params, | ||
cases, | ||
})) | ||
} | ||
} | ||
|
||
impl ToIR for ast::Codef { | ||
type Target = ir::Codef; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::Codef { name, params, cases, .. } = self; | ||
|
||
let params = params | ||
.params | ||
.iter() | ||
.filter(|param| !param.erased) | ||
.map(|param| param.name.to_string()) | ||
.collect(); | ||
|
||
let cases = cases.to_ir()?; | ||
|
||
Ok(ir::Codef { name: name.to_string(), params, cases }) | ||
} | ||
} | ||
|
||
impl ToIR for ast::Let { | ||
type Target = Option<ir::Let>; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::Let { name, params, body, .. } = self; | ||
|
||
let params = params | ||
.params | ||
.iter() | ||
.filter(|param| !param.erased) | ||
.map(|param| param.name.to_string()) | ||
.collect(); | ||
|
||
let body = Box::new(body.to_ir()?); | ||
|
||
Ok(Some(ir::Let { name: name.to_string(), params, body })) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
use ast::LocalComatch; | ||
|
||
use crate::ir; | ||
use crate::result::BackendError; | ||
|
||
use super::traits::ToIR; | ||
|
||
impl ToIR for ast::Exp { | ||
type Target = ir::Exp; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let out = match self { | ||
ast::Exp::Variable(variable) => ir::Exp::Variable(variable.to_ir()?), | ||
ast::Exp::TypCtor(_) => ir::Exp::ZST, | ||
ast::Exp::Call(call) => match call.kind { | ||
ast::CallKind::Constructor => ir::Exp::CtorCall(call.to_ir()?), | ||
ast::CallKind::Codefinition => ir::Exp::CodefCall(call.to_ir()?), | ||
ast::CallKind::LetBound => ir::Exp::LetCall(call.to_ir()?), | ||
}, | ||
ast::Exp::DotCall(dot_call) => match dot_call.kind { | ||
ast::DotCallKind::Destructor => ir::Exp::DtorCall(dot_call.to_ir()?), | ||
ast::DotCallKind::Definition => ir::Exp::DefCall(dot_call.to_ir()?), | ||
}, | ||
ast::Exp::Anno(anno) => anno.exp.to_ir()?, | ||
ast::Exp::TypeUniv(_) => ir::Exp::ZST, | ||
ast::Exp::LocalMatch(local_match) => ir::Exp::LocalMatch(local_match.to_ir()?), | ||
ast::Exp::LocalComatch(local_comatch) => ir::Exp::LocalComatch(local_comatch.to_ir()?), | ||
ast::Exp::Hole(hole) => hole.to_ir()?, | ||
}; | ||
|
||
Ok(out) | ||
} | ||
} | ||
|
||
impl ToIR for ast::Variable { | ||
type Target = ir::Variable; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::Variable { name, .. } = self; | ||
|
||
Ok(ir::Variable { name: name.to_string() }) | ||
} | ||
} | ||
|
||
impl ToIR for ast::Call { | ||
type Target = ir::Call; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::Call { name, args, .. } = self; | ||
|
||
let args = args | ||
.args | ||
.iter() | ||
.filter(|arg| !arg.erased()) | ||
.map(|arg| arg.exp()) | ||
.map(|arg| arg.to_ir()) | ||
.collect::<Result<_, _>>()?; | ||
|
||
Ok(ir::Call { name: name.to_string(), module_uri: name.uri.clone(), args }) | ||
} | ||
} | ||
|
||
impl ToIR for ast::DotCall { | ||
type Target = ir::DotCall; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::DotCall { exp, name, args, .. } = self; | ||
|
||
let args = args | ||
.args | ||
.iter() | ||
.filter(|arg| !arg.erased()) | ||
.map(|arg| arg.exp()) | ||
.map(|arg| arg.to_ir()) | ||
.collect::<Result<_, _>>()?; | ||
|
||
let exp = Box::new(exp.to_ir()?); | ||
|
||
Ok(ir::DotCall { exp, module_uri: name.uri.clone(), name: name.to_string(), args }) | ||
} | ||
} | ||
|
||
impl ToIR for ast::LocalMatch { | ||
type Target = ir::LocalMatch; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::LocalMatch { on_exp, cases, .. } = self; | ||
|
||
let on_exp = Box::new(on_exp.to_ir()?); | ||
let cases = cases.to_ir()?; | ||
|
||
Ok(ir::LocalMatch { on_exp, cases }) | ||
} | ||
} | ||
|
||
impl ToIR for ast::LocalComatch { | ||
type Target = ir::LocalComatch; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let LocalComatch { cases, .. } = self; | ||
|
||
let cases = cases.to_ir()?; | ||
|
||
Ok(ir::LocalComatch { cases }) | ||
} | ||
} | ||
|
||
impl ToIR for ast::Hole { | ||
type Target = ir::Exp; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::Hole { kind, solution, .. } = self; | ||
|
||
let res = | ||
match kind { | ||
ast::MetaVarKind::MustSolve | ast::MetaVarKind::Inserted => match solution { | ||
Some(solution) => solution.to_ir()?, | ||
None => return Err(BackendError::Impossible( | ||
"Encountered hole without solution that must be solved during typechecking" | ||
.to_owned(), | ||
)), | ||
}, | ||
ast::MetaVarKind::CanSolve => { | ||
ir::Exp::Panic(ir::Panic { message: "not yet implemented".to_owned() }) | ||
} | ||
}; | ||
|
||
Ok(res) | ||
} | ||
} | ||
|
||
impl ToIR for ast::Case { | ||
type Target = ir::Case; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
let ast::Case { pattern, body, .. } = self; | ||
let ast::Pattern { is_copattern, params, name } = pattern; | ||
|
||
let params = params | ||
.params | ||
.iter() | ||
.filter(|param| !param.erased) | ||
.map(|param| param.name.to_string()) | ||
.collect::<Vec<_>>(); | ||
|
||
let pattern = ir::Pattern { | ||
is_copattern: *is_copattern, | ||
name: name.to_string(), | ||
module_uri: name.uri.clone(), | ||
params, | ||
}; | ||
|
||
let body = match body { | ||
Some(body) => Some(Box::new(body.to_ir()?)), | ||
None => None, | ||
}; | ||
|
||
Ok(ir::Case { pattern, body }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod decls; | ||
pub mod exprs; | ||
pub mod traits; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use crate::result::BackendError; | ||
|
||
pub trait ToIR { | ||
type Target; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError>; | ||
} | ||
|
||
impl<T: ToIR> ToIR for Vec<T> { | ||
type Target = Vec<T::Target>; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
self.iter().map(|x| x.to_ir()).collect() | ||
} | ||
} | ||
|
||
impl<T: ToIR> ToIR for Option<T> { | ||
type Target = Option<T::Target>; | ||
|
||
fn to_ir(&self) -> Result<Self::Target, BackendError> { | ||
match self { | ||
Some(x) => Ok(Some(x.to_ir()?)), | ||
None => Ok(None), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
pub mod ast2ir; | ||
pub mod ir; | ||
pub mod result; |