mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 20:34:44 +00:00
Implement type spec of projection and enum types
This commit is contained in:
parent
4eae5788ca
commit
47bedf67d8
14 changed files with 282 additions and 128 deletions
|
@ -1079,7 +1079,7 @@ pub struct ConstLocal {
|
|||
|
||||
impl NestedDisplay for ConstLocal {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||
write!(f, "{}", self.symbol)
|
||||
write!(f, "{}", self.symbol.content)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1514,7 +1514,7 @@ impl fmt::Display for SimpleTypeSpec {
|
|||
if self.args.is_empty() {
|
||||
write!(f, "{}", self.ident)
|
||||
} else {
|
||||
write!(f, "{}{}", self.ident, self.args)
|
||||
write!(f, "{}({})", self.ident, self.args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1728,20 +1728,20 @@ impl ArrayTypeSpec {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct SetTypeSpec {
|
||||
pub struct SetWithLenTypeSpec {
|
||||
pub ty: Box<TypeSpec>,
|
||||
pub len: ConstExpr,
|
||||
}
|
||||
|
||||
impl fmt::Display for SetTypeSpec {
|
||||
impl fmt::Display for SetWithLenTypeSpec {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{{{}; {}}}", self.ty, self.len)
|
||||
}
|
||||
}
|
||||
|
||||
impl_locational!(SetTypeSpec, ty, len);
|
||||
impl_locational!(SetWithLenTypeSpec, ty, len);
|
||||
|
||||
impl SetTypeSpec {
|
||||
impl SetWithLenTypeSpec {
|
||||
pub fn new(ty: TypeSpec, len: ConstExpr) -> Self {
|
||||
Self {
|
||||
ty: Box::new(ty),
|
||||
|
@ -1765,7 +1765,7 @@ pub enum TypeSpec {
|
|||
PreDeclTy(PreDeclTypeSpec),
|
||||
/* Composite types */
|
||||
Array(ArrayTypeSpec),
|
||||
Set(SetTypeSpec),
|
||||
SetWithLen(SetWithLenTypeSpec),
|
||||
Tuple(Vec<TypeSpec>),
|
||||
Dict(Vec<(TypeSpec, TypeSpec)>),
|
||||
Record(Vec<(Identifier, TypeSpec)>),
|
||||
|
@ -1795,7 +1795,7 @@ impl fmt::Display for TypeSpec {
|
|||
Self::Not(lhs, rhs) => write!(f, "{lhs} not {rhs}"),
|
||||
Self::Or(lhs, rhs) => write!(f, "{lhs} or {rhs}"),
|
||||
Self::Array(arr) => write!(f, "{arr}"),
|
||||
Self::Set(set) => write!(f, "{set}"),
|
||||
Self::SetWithLen(set) => write!(f, "{set}"),
|
||||
Self::Tuple(tys) => write!(f, "({})", fmt_vec(tys)),
|
||||
Self::Dict(dict) => {
|
||||
write!(f, "{{")?;
|
||||
|
@ -1827,7 +1827,7 @@ impl Locational for TypeSpec {
|
|||
Location::concat(lhs.as_ref(), rhs.as_ref())
|
||||
}
|
||||
Self::Array(arr) => arr.loc(),
|
||||
Self::Set(set) => set.loc(),
|
||||
Self::SetWithLen(set) => set.loc(),
|
||||
// TODO: ユニット
|
||||
Self::Tuple(tys) => Location::concat(tys.first().unwrap(), tys.last().unwrap()),
|
||||
Self::Dict(dict) => Location::concat(&dict.first().unwrap().0, &dict.last().unwrap().1),
|
||||
|
|
|
@ -2840,7 +2840,7 @@ impl Parser {
|
|||
|
||||
// The APIs defined below are also used by `ASTLowerer` to interpret expressions as types.
|
||||
impl Parser {
|
||||
fn validate_const_expr(expr: Expr) -> Result<ConstExpr, ParseError> {
|
||||
pub fn validate_const_expr(expr: Expr) -> Result<ConstExpr, ParseError> {
|
||||
match expr {
|
||||
Expr::Lit(l) => Ok(ConstExpr::Lit(l)),
|
||||
Expr::Accessor(Accessor::Ident(local)) => {
|
||||
|
@ -3016,17 +3016,21 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_to_set_type_spec(set: Set) -> Result<SetTypeSpec, ParseError> {
|
||||
fn set_to_set_type_spec(set: Set) -> Result<TypeSpec, ParseError> {
|
||||
match set {
|
||||
Set::Normal(arr) => {
|
||||
// TODO: add hint
|
||||
let err = ParseError::simple_syntax_error(line!() as usize, arr.loc());
|
||||
Err(err)
|
||||
Set::Normal(set) => {
|
||||
let mut elem_ts = vec![];
|
||||
let (elems, .., paren) = set.elems.deconstruct();
|
||||
for elem in elems.into_iter() {
|
||||
let const_expr = Self::validate_const_expr(elem.expr)?;
|
||||
elem_ts.push(ConstPosArg::new(const_expr));
|
||||
}
|
||||
Ok(TypeSpec::Enum(ConstArgs::new(elem_ts, vec![], paren)))
|
||||
}
|
||||
Set::WithLength(set) => {
|
||||
let t_spec = Self::expr_to_type_spec(set.elem.expr)?;
|
||||
let len = Self::validate_const_expr(*set.len)?;
|
||||
Ok(SetTypeSpec::new(t_spec, len))
|
||||
Ok(TypeSpec::SetWithLen(SetWithLenTypeSpec::new(t_spec, len)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3095,7 +3099,7 @@ impl Parser {
|
|||
}
|
||||
Expr::Set(set) => {
|
||||
let set = Self::set_to_set_type_spec(set)?;
|
||||
Ok(TypeSpec::Set(set))
|
||||
Ok(set)
|
||||
}
|
||||
Expr::Dict(dict) => {
|
||||
let dict = Self::dict_to_dict_type_spec(dict)?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue