Implement match!

This commit is contained in:
Shunsuke Shibayama 2022-10-23 01:21:18 +09:00
parent 7862331488
commit 329274e2cd
5 changed files with 23 additions and 5 deletions

View file

@ -17,7 +17,7 @@ use ast::VarName;
use erg_parser::ast::{self, Identifier};
use erg_parser::token::Token;
use crate::ty::constructors::{anon, free_var, func, mono, poly, proj, subr_t};
use crate::ty::constructors::{anon, free_var, func, mono, poly, proc, proj, subr_t};
use crate::ty::free::Constraint;
use crate::ty::typaram::TyParam;
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
@ -234,6 +234,7 @@ impl Context {
fn get_match_call_t(
&self,
kind: SubrKind,
pos_args: &[hir::PosArg],
kw_args: &[hir::KwArg],
) -> TyCheckResult<VarInfo> {
@ -310,7 +311,11 @@ impl Context {
}
let param_ty = ParamTy::anonymous(match_target_expr_t.clone());
let param_ts = [vec![param_ty], branch_ts.to_vec()].concat();
let t = func(param_ts, None, vec![], return_t);
let t = if kind.is_func() {
func(param_ts, None, vec![], return_t)
} else {
proc(param_ts, None, vec![], return_t)
};
Ok(VarInfo {
t,
..VarInfo::default()
@ -1162,7 +1167,10 @@ impl Context {
#[allow(clippy::single_match)]
match &local.inspect()[..] {
"match" => {
return self.get_match_call_t(pos_args, kw_args);
return self.get_match_call_t(SubrKind::Func, pos_args, kw_args);
}
"match!" => {
return self.get_match_call_t(SubrKind::Proc, pos_args, kw_args);
}
/*"import" | "pyimport" | "py" => {
return self.get_import_call_t(pos_args, kw_args);

View file

@ -590,7 +590,9 @@ impl ASTLowerer {
fn lower_ident(&self, ident: ast::Identifier) -> LowerResult<hir::Identifier> {
// `match` is an untypable special form
// `match`は型付け不可能な特殊形式
let (vi, __name__) = if ident.vis().is_private() && &ident.inspect()[..] == "match" {
let (vi, __name__) = if ident.vis().is_private()
&& (&ident.inspect()[..] == "match" || &ident.inspect()[..] == "match!")
{
(VarInfo::default(), None)
} else {
(

View file

@ -1068,6 +1068,13 @@ impl SubrKind {
Self::Proc => Str::ever("=>"),
}
}
pub fn is_func(&self) -> bool {
matches!(self, Self::Func)
}
pub fn is_proc(&self) -> bool {
matches!(self, Self::Proc)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]

View file

@ -988,7 +988,7 @@ impl Call {
pub fn is_match(&self) -> bool {
self.obj
.get_name()
.map(|s| &s[..] == "match")
.map(|s| &s[..] == "match" || &s[..] == "match!")
.unwrap_or(false)
}

View file

@ -300,6 +300,7 @@ impl Desugarer {
(call, return_t_spec)
}
// TODO: procedural match
fn gen_match_call(&self, previous: Def, def: Def) -> (Call, Option<TypeSpec>) {
let op = Token::from_str(TokenKind::FuncArrow, "->");
let sig = enum_unwrap!(previous.sig, Signature::Subr);