Merge pull request #96 from mist-go/function-types

Function types
This commit is contained in:
2026-06-28 06:06:50 +02:00
committed by GitHub
6 changed files with 163 additions and 65 deletions
+32 -9
View File
@@ -176,7 +176,7 @@ impl GetMist for TypeExpr {
} }
Self::UnsafePtr { mutable, ty } => { Self::UnsafePtr { mutable, ty } => {
let mutable = if *mutable { "mut " } else { "const " }; let mutable = if *mutable { "mut " } else { "const " };
format!("*{mutable}{}", ty.get_mist()) format!("{} {mutable} unsafe&", ty.get_mist())
} }
Self::Ref { Self::Ref {
lifetime, lifetime,
@@ -185,19 +185,12 @@ impl GetMist for TypeExpr {
} => { } => {
let base = ty.get_mist(); let base = ty.get_mist();
if let Some(lifetime) = lifetime { if let Some(lifetime) = lifetime {
match lifetime {
Lifetime::Lifetime(v) => {
format!( format!(
"{} {} '{}&", "{} {} '{}&",
base, base,
if *mutable { "mut" } else { "" }, if *mutable { "mut" } else { "" },
v.get_mist() lifetime.get_mist()
) )
}
Lifetime::Unsafe => {
format!("{} {} unsafe&", base, if *mutable { "mut" } else { "const" })
}
}
} else if *mutable { } else if *mutable {
format!("{} mut&", base) format!("{} mut&", base)
} else { } else {
@@ -207,9 +200,39 @@ impl GetMist for TypeExpr {
Self::Dyn(ty) => { Self::Dyn(ty) => {
format!("dyn {}", ty.get_mist()) format!("dyn {}", ty.get_mist())
} }
Self::Void => "void".to_string(),
Self::Fn {
kind,
return_type,
params,
} => {
format!(
"{} {}({})",
return_type.get_mist(),
kind.get_mist(),
params
.iter()
.map(TypeExpr::get_mist)
.collect::<Vec<_>>()
.join(", ")
)
} }
} }
} }
}
impl GetMist for FnKind {
fn get_mist(&self) -> String {
match self {
Self::Fn => "fn",
Self::UnsafeFn => "unsafe fn",
Self::FnClosure => "Fn",
Self::FnMut => "FnMut",
Self::FnOnce => "FnOnce",
}
.to_string()
}
}
impl GetMist for ExprPath { impl GetMist for ExprPath {
fn get_mist(&self) -> String { fn get_mist(&self) -> String {
+31 -12
View File
@@ -247,23 +247,12 @@ impl GetRust for TypeExpr {
ty, ty,
} => { } => {
if let Some(lifetime) = lifetime { if let Some(lifetime) = lifetime {
match lifetime {
Lifetime::Lifetime(v) => {
format!( format!(
"&'{} {}{}", "&'{} {}{}",
v.get_rust(), lifetime.get_rust(),
if *mutable { "mut " } else { "" }, if *mutable { "mut " } else { "" },
ty.get_rust() ty.get_rust()
) )
}
Lifetime::Unsafe => {
format!(
"*{} {}",
if *mutable { "mut" } else { "const" },
ty.get_rust()
)
}
}
} else { } else {
format!("&{}{}", if *mutable { "mut " } else { "" }, ty.get_rust()) format!("&{}{}", if *mutable { "mut " } else { "" }, ty.get_rust())
} }
@@ -272,9 +261,39 @@ impl GetRust for TypeExpr {
Self::Dyn(ty) => { Self::Dyn(ty) => {
format!("dyn {}", ty.get_rust()) format!("dyn {}", ty.get_rust())
} }
Self::Void => "()".to_string(),
Self::Fn {
kind,
return_type,
params,
} => {
format!(
"{}({}) -> {}",
kind.get_rust(),
params
.iter()
.map(TypeExpr::get_rust)
.collect::<Vec<_>>()
.join(", "),
return_type.get_rust(),
)
} }
} }
} }
}
impl GetRust for FnKind {
fn get_rust(&self) -> String {
match self {
Self::Fn => "fn",
Self::UnsafeFn => "unsafe fn",
Self::FnClosure => "Fn",
Self::FnMut => "FnMut",
Self::FnOnce => "FnOnce",
}
.to_string()
}
}
impl GenRust for Pattern { impl GenRust for Pattern {
fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
+13 -4
View File
@@ -18,15 +18,18 @@ pub struct Identifier(pub String);
pub struct ParamList(pub Vec<VarDecl>); pub struct ParamList(pub Vec<VarDecl>);
#[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)]
pub enum Lifetime { pub enum FnKind {
Lifetime(Identifier), Fn,
Unsafe, UnsafeFn,
FnClosure,
FnOnce,
FnMut,
} }
#[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)]
pub enum TypeExpr { pub enum TypeExpr {
Ref { Ref {
lifetime: Option<Lifetime>, lifetime: Option<Identifier>,
mutable: bool, mutable: bool,
ty: Box<TypeExpr>, ty: Box<TypeExpr>,
}, },
@@ -39,6 +42,12 @@ pub enum TypeExpr {
StaticFn(Vec<TypeExpr>, Option<Box<TypeExpr>>), StaticFn(Vec<TypeExpr>, Option<Box<TypeExpr>>),
Tuple(Vec<TypeExpr>), Tuple(Vec<TypeExpr>),
Lifetime(Identifier), Lifetime(Identifier),
Void,
Fn {
kind: FnKind,
return_type: Box<TypeExpr>,
params: Vec<TypeExpr>,
},
} }
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
+27 -4
View File
@@ -81,7 +81,6 @@ module_program = {
visibility = { "pub" ~ ("(" ~ static_path ~ ")")? } visibility = { "pub" ~ ("(" ~ static_path ~ ")")? }
mutable = { "mut" } mutable = { "mut" }
unsafe_kw = { "unsafe" }
// ====================================================== // ======================================================
// GENERICS // GENERICS
@@ -104,18 +103,42 @@ path_type = {
static_path ~ generics? static_path ~ generics?
} }
ref_lifetime = { lifetime | unsafe_kw } unsafe_ref_type = {
mutable? ~ "unsafe" ~ "*"
}
ref_type = { ref_type = {
mutable? ~ ref_lifetime? ~ "&" mutable? ~ lifetime? ~ "&"
}
fn_kind_fn = { "fn" }
fn_kind_unsafe = { "unsafe" ~ "fn" }
fn_kind_closure = { "Fn" }
fn_kind_once = { "FnOnce" }
fn_kind_mut = { "FnMut" }
fn_kind = _{
fn_kind_fn
| fn_kind_unsafe
| fn_kind_closure
| fn_kind_once
| fn_kind_mut
}
fn_type = {
fn_kind ~ "(" ~ (type_expr ~ ("," ~ type_expr)*)? ~ ")"
} }
dyn_type = { dyn_type = {
"dyn" ~ type_expr "dyn" ~ type_expr
} }
void_type = {
"void"
}
type_expr = { type_expr = {
(path_type | tuple_type | dyn_type) ~ ref_type* (void_type | path_type | tuple_type | dyn_type) ~ (unsafe_ref_type | ref_type | fn_type)*
} }
lifetime = { lifetime = {
+42 -3
View File
@@ -21,23 +21,46 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
let mut ty = TypeExpr::try_from(inner.next().unwrap())?; let mut ty = TypeExpr::try_from(inner.next().unwrap())?;
for ref_pair in inner { for ref_pair in inner {
let mut ref_inner = ref_pair.into_inner(); let mut ref_inner = ref_pair.clone().into_inner();
match ref_pair.as_rule() {
Rule::ref_type => {
ty = TypeExpr::Ref { ty = TypeExpr::Ref {
lifetime: consume_rule(&mut ref_inner, Rule::ref_lifetime) mutable: listen_rule(&mut ref_inner, Rule::mutable),
.map(|v| v.into_inner().next().map(Lifetime::try_from)) lifetime: consume_rule(&mut ref_inner, Rule::lifetime)
.map(|v| v.into_inner().next().map(Identifier::try_from))
.unwrap_or_default() .unwrap_or_default()
.transpose()?, .transpose()?,
ty: Box::new(ty),
};
}
Rule::unsafe_ref_type => {
ty = TypeExpr::UnsafePtr {
mutable: listen_rule(&mut ref_inner, Rule::mutable), mutable: listen_rule(&mut ref_inner, Rule::mutable),
ty: Box::new(ty), ty: Box::new(ty),
}; };
} }
Rule::fn_type => {
ty = TypeExpr::Fn {
return_type: Box::new(ty),
kind: ref_inner.next().unwrap().try_into()?,
params: collect_recovered(ref_inner)?,
};
}
_ => AstError::bug_unimplemented(ref_pair)?,
}
}
Ok(ty) Ok(ty)
} }
Rule::lifetime => Ok(TypeExpr::Lifetime(inner.next().unwrap().try_into()?)), Rule::lifetime => Ok(TypeExpr::Lifetime(inner.next().unwrap().try_into()?)),
Rule::void_type => Ok(TypeExpr::Void),
Rule::tuple_type => Ok(TypeExpr::Tuple(collect_recovered(inner)?)), Rule::tuple_type => Ok(TypeExpr::Tuple(collect_recovered(inner)?)),
Rule::path_type => Ok(TypeExpr::Path( Rule::path_type => Ok(TypeExpr::Path(
Path::try_from(inner.next().unwrap())?, Path::try_from(inner.next().unwrap())?,
inner.next().map(Generics::try_from).transpose()?, inner.next().map(Generics::try_from).transpose()?,
@@ -52,6 +75,22 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FnKind {
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
match pair.as_rule() {
Rule::fn_kind_fn => Ok(FnKind::Fn),
Rule::fn_kind_unsafe => Ok(FnKind::UnsafeFn),
Rule::fn_kind_closure => Ok(FnKind::FnClosure),
Rule::fn_kind_once => Ok(FnKind::FnOnce),
Rule::fn_kind_mut => Ok(FnKind::FnMut),
_ => AstError::bug_unimplemented(pair),
}
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericsDecl { impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericsDecl {
type Error = AstError<'a>; type Error = AstError<'a>;
+1 -16
View File
@@ -2,7 +2,7 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_ensure,
error::{self, AstError, AstResult}, error::{AstError, AstResult},
parser::{consume_rule, consume_rule_map, listen_rule}, parser::{consume_rule, consume_rule_map, listen_rule},
}; };
@@ -66,18 +66,3 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Override {
}) })
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Lifetime {
type Error = AstError<'a>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
match pair.as_rule() {
Rule::ref_lifetime => inner.next().unwrap().try_into(),
Rule::lifetime => Ok(Lifetime::Lifetime(inner.next().unwrap().try_into()?)),
Rule::unsafe_kw => Ok(Lifetime::Unsafe),
_ => error::AstError::bug_unimplemented(pair),
}
}
}