conlang: Introduce type-alias/typedef syntax
`type T;` | `type T = U;`
This commit is contained in:
		| @@ -11,7 +11,7 @@ File        = Item* EOI ; | ||||
| Item        = Visibility ItemKind ; | ||||
| ItemKind    = Const    | Static | Module  | ||||
|                 | Function | Struct | Enum  | ||||
|             | Impl ; | ||||
|             | Alias    | Impl ; | ||||
|  | ||||
|  | ||||
| (* item *) | ||||
| @@ -36,6 +36,8 @@ VarStruct   = '{' (StructMember ',')* StructMember? '}' ; | ||||
| VarTuple    = TyTuple ; | ||||
| VarCLike    = '=' INTEGER ; | ||||
|  | ||||
| Alias       = "type" Ty ('=' Ty)? ';' ; | ||||
|  | ||||
| Impl        = "impl" Path '{' Item* '}' ; | ||||
| (* TODO: Impl Trait for Target*) | ||||
|  | ||||
|   | ||||
| @@ -44,6 +44,10 @@ pub struct Item { | ||||
| /// Stores a concrete Item | ||||
| #[derive(Clone, Debug, PartialEq, Eq)] | ||||
| pub enum ItemKind { | ||||
|     // TODO: Import declaration ("use") item | ||||
|     // TODO: Trait declaration ("trait") item? | ||||
|     /// A [type alias](Alias) | ||||
|     Alias(Alias), | ||||
|     /// A [constant](Const) | ||||
|     Const(Const), | ||||
|     /// A [static](Static) variable | ||||
| @@ -60,6 +64,12 @@ pub enum ItemKind { | ||||
|     Impl(Impl), | ||||
| } | ||||
|  | ||||
| #[derive(Clone, Debug, PartialEq, Eq)] | ||||
| pub struct Alias { | ||||
|     pub to: Box<Ty>, | ||||
|     pub from: Option<Box<Ty>>, | ||||
| } | ||||
|  | ||||
| /// Stores a `const` value | ||||
| #[derive(Clone, Debug, PartialEq, Eq)] | ||||
| pub struct Const { | ||||
|   | ||||
| @@ -81,6 +81,7 @@ mod display { | ||||
|         fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|             self.vis.fmt(f)?; | ||||
|             match &self.kind { | ||||
|                 ItemKind::Alias(v) => v.fmt(f), | ||||
|                 ItemKind::Const(v) => v.fmt(f), | ||||
|                 ItemKind::Static(v) => v.fmt(f), | ||||
|                 ItemKind::Module(v) => v.fmt(f), | ||||
| @@ -91,6 +92,15 @@ mod display { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     impl Display for Alias { | ||||
|         fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|             let Self { to, from } = self; | ||||
|             match from { | ||||
|                 Some(from) => write!(f, "type {to} = {from};"), | ||||
|                 None => write!(f, "type {to};"), | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     impl Display for Const { | ||||
|         fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|             let Self { name, ty, init } = self; | ||||
| @@ -649,6 +659,7 @@ mod convert { | ||||
|  | ||||
|     impl_from! { | ||||
|         impl From for ItemKind { | ||||
|             Alias => ItemKind::Alias, | ||||
|             Const => ItemKind::Const, | ||||
|             Static => ItemKind::Static, | ||||
|             Module => ItemKind::Module, | ||||
|   | ||||
| @@ -330,6 +330,7 @@ pub mod interpret { | ||||
|     impl Interpret for Item { | ||||
|         fn interpret(&self, env: &mut Environment) -> IResult<ConValue> { | ||||
|             match &self.kind { | ||||
|                 ItemKind::Alias(item) => item.interpret(env), | ||||
|                 ItemKind::Const(item) => item.interpret(env), | ||||
|                 ItemKind::Static(item) => item.interpret(env), | ||||
|                 ItemKind::Module(item) => item.interpret(env), | ||||
| @@ -340,6 +341,11 @@ pub mod interpret { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     impl Interpret for Alias { | ||||
|         fn interpret(&self, env: &mut Environment) -> IResult<ConValue> { | ||||
|             todo!("Interpret type alias in {env}") | ||||
|         } | ||||
|     } | ||||
|     impl Interpret for Const { | ||||
|         fn interpret(&self, env: &mut Environment) -> IResult<ConValue> { | ||||
|             todo!("interpret const in {env}") | ||||
|   | ||||
| @@ -72,6 +72,7 @@ pub mod error { | ||||
|         Visibility, | ||||
|         Mutability, | ||||
|         ItemKind, | ||||
|         Alias, | ||||
|         Const, | ||||
|         Static, | ||||
|         Module, | ||||
| @@ -164,6 +165,7 @@ pub mod error { | ||||
|                 Parsing::Visibility => "a visibility qualifier", | ||||
|                 Parsing::Mutability => "a mutability qualifier", | ||||
|                 Parsing::ItemKind => "an item", | ||||
|                 Parsing::Alias => "a type alias", | ||||
|                 Parsing::Const => "a const item", | ||||
|                 Parsing::Static => "a static variable", | ||||
|                 Parsing::Module => "a module", | ||||
| @@ -369,6 +371,7 @@ impl<'t> Parser<'t> { | ||||
| macro item_like() { | ||||
|     Type::Keyword( | ||||
|         Keyword::Pub | ||||
|             | Keyword::Type | ||||
|             | Keyword::Const | ||||
|             | Keyword::Static | ||||
|             | Keyword::Mod | ||||
| @@ -466,6 +469,7 @@ impl<'t> Parser<'t> { | ||||
|     /// See also: [Parser::item] | ||||
|     pub fn itemkind(&mut self) -> PResult<ItemKind> { | ||||
|         Ok(match self.peek_type(Parsing::Item)? { | ||||
|             Type::Keyword(Keyword::Type) => self.parse_alias()?.into(), | ||||
|             Type::Keyword(Keyword::Const) => self.parse_const()?.into(), | ||||
|             Type::Keyword(Keyword::Static) => self.parse_static()?.into(), | ||||
|             Type::Keyword(Keyword::Mod) => self.parse_module()?.into(), | ||||
| @@ -477,6 +481,21 @@ impl<'t> Parser<'t> { | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn parse_alias(&mut self) -> PResult<Alias> { | ||||
|         const PARSING: Parsing = Parsing::Alias; | ||||
|         self.match_kw(Keyword::Type, PARSING)?; | ||||
|         let out = Ok(Alias { | ||||
|             to: self.ty()?.into(), | ||||
|             from: if self.match_type(Type::Eq, PARSING).is_ok() { | ||||
|                 Some(self.ty()?.into()) | ||||
|             } else { | ||||
|                 None | ||||
|             }, | ||||
|         }); | ||||
|         self.match_type(Type::Semi, PARSING)?; | ||||
|         out | ||||
|     } | ||||
|  | ||||
|     pub fn parse_const(&mut self) -> PResult<Const> { | ||||
|         const PARSING: Parsing = Parsing::Const; | ||||
|         self.match_kw(Keyword::Const, PARSING)?; | ||||
|   | ||||
| @@ -99,6 +99,7 @@ pub enum Keyword { | ||||
|     Struct, | ||||
|     Super, | ||||
|     True, | ||||
|     Type, | ||||
|     While, | ||||
| } | ||||
|  | ||||
| @@ -197,6 +198,7 @@ impl Display for Keyword { | ||||
|             Self::Struct => "struct".fmt(f), | ||||
|             Self::Super => "super".fmt(f), | ||||
|             Self::True => "true".fmt(f), | ||||
|             Self::Type => "type".fmt(f), | ||||
|             Self::While => "while".fmt(f), | ||||
|         } | ||||
|     } | ||||
| @@ -229,6 +231,7 @@ impl FromStr for Keyword { | ||||
|             "struct" => Self::Struct, | ||||
|             "super" => Self::Super, | ||||
|             "true" => Self::True, | ||||
|             "type" => Self::Type, | ||||
|             "while" => Self::While, | ||||
|             _ => Err(())?, | ||||
|         }) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user