conlang: Introduce type-alias/typedef syntax

`type T;` | `type T = U;`
This commit is contained in:
John 2024-02-27 20:49:02 -06:00
parent 0c1b3bfe39
commit 978f5e40c1
6 changed files with 52 additions and 1 deletions

View File

@ -11,7 +11,7 @@ File = Item* EOI ;
Item = Visibility ItemKind ; Item = Visibility ItemKind ;
ItemKind = Const | Static | Module ItemKind = Const | Static | Module
| Function | Struct | Enum | Function | Struct | Enum
| Impl ; | Alias | Impl ;
(* item *) (* item *)
@ -36,6 +36,8 @@ VarStruct = '{' (StructMember ',')* StructMember? '}' ;
VarTuple = TyTuple ; VarTuple = TyTuple ;
VarCLike = '=' INTEGER ; VarCLike = '=' INTEGER ;
Alias = "type" Ty ('=' Ty)? ';' ;
Impl = "impl" Path '{' Item* '}' ; Impl = "impl" Path '{' Item* '}' ;
(* TODO: Impl Trait for Target*) (* TODO: Impl Trait for Target*)

View File

@ -44,6 +44,10 @@ pub struct Item {
/// Stores a concrete Item /// Stores a concrete Item
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum ItemKind { pub enum ItemKind {
// TODO: Import declaration ("use") item
// TODO: Trait declaration ("trait") item?
/// A [type alias](Alias)
Alias(Alias),
/// A [constant](Const) /// A [constant](Const)
Const(Const), Const(Const),
/// A [static](Static) variable /// A [static](Static) variable
@ -60,6 +64,12 @@ pub enum ItemKind {
Impl(Impl), Impl(Impl),
} }
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Alias {
pub to: Box<Ty>,
pub from: Option<Box<Ty>>,
}
/// Stores a `const` value /// Stores a `const` value
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Const { pub struct Const {

View File

@ -81,6 +81,7 @@ mod display {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.vis.fmt(f)?; self.vis.fmt(f)?;
match &self.kind { match &self.kind {
ItemKind::Alias(v) => v.fmt(f),
ItemKind::Const(v) => v.fmt(f), ItemKind::Const(v) => v.fmt(f),
ItemKind::Static(v) => v.fmt(f), ItemKind::Static(v) => v.fmt(f),
ItemKind::Module(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 { impl Display for Const {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, ty, init } = self; let Self { name, ty, init } = self;
@ -649,6 +659,7 @@ mod convert {
impl_from! { impl_from! {
impl From for ItemKind { impl From for ItemKind {
Alias => ItemKind::Alias,
Const => ItemKind::Const, Const => ItemKind::Const,
Static => ItemKind::Static, Static => ItemKind::Static,
Module => ItemKind::Module, Module => ItemKind::Module,

View File

@ -330,6 +330,7 @@ pub mod interpret {
impl Interpret for Item { impl Interpret for Item {
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> { fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
match &self.kind { match &self.kind {
ItemKind::Alias(item) => item.interpret(env),
ItemKind::Const(item) => item.interpret(env), ItemKind::Const(item) => item.interpret(env),
ItemKind::Static(item) => item.interpret(env), ItemKind::Static(item) => item.interpret(env),
ItemKind::Module(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 { impl Interpret for Const {
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> { fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
todo!("interpret const in {env}") todo!("interpret const in {env}")

View File

@ -72,6 +72,7 @@ pub mod error {
Visibility, Visibility,
Mutability, Mutability,
ItemKind, ItemKind,
Alias,
Const, Const,
Static, Static,
Module, Module,
@ -164,6 +165,7 @@ pub mod error {
Parsing::Visibility => "a visibility qualifier", Parsing::Visibility => "a visibility qualifier",
Parsing::Mutability => "a mutability qualifier", Parsing::Mutability => "a mutability qualifier",
Parsing::ItemKind => "an item", Parsing::ItemKind => "an item",
Parsing::Alias => "a type alias",
Parsing::Const => "a const item", Parsing::Const => "a const item",
Parsing::Static => "a static variable", Parsing::Static => "a static variable",
Parsing::Module => "a module", Parsing::Module => "a module",
@ -369,6 +371,7 @@ impl<'t> Parser<'t> {
macro item_like() { macro item_like() {
Type::Keyword( Type::Keyword(
Keyword::Pub Keyword::Pub
| Keyword::Type
| Keyword::Const | Keyword::Const
| Keyword::Static | Keyword::Static
| Keyword::Mod | Keyword::Mod
@ -466,6 +469,7 @@ impl<'t> Parser<'t> {
/// See also: [Parser::item] /// See also: [Parser::item]
pub fn itemkind(&mut self) -> PResult<ItemKind> { pub fn itemkind(&mut self) -> PResult<ItemKind> {
Ok(match self.peek_type(Parsing::Item)? { 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::Const) => self.parse_const()?.into(),
Type::Keyword(Keyword::Static) => self.parse_static()?.into(), Type::Keyword(Keyword::Static) => self.parse_static()?.into(),
Type::Keyword(Keyword::Mod) => self.parse_module()?.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> { pub fn parse_const(&mut self) -> PResult<Const> {
const PARSING: Parsing = Parsing::Const; const PARSING: Parsing = Parsing::Const;
self.match_kw(Keyword::Const, PARSING)?; self.match_kw(Keyword::Const, PARSING)?;

View File

@ -99,6 +99,7 @@ pub enum Keyword {
Struct, Struct,
Super, Super,
True, True,
Type,
While, While,
} }
@ -197,6 +198,7 @@ impl Display for Keyword {
Self::Struct => "struct".fmt(f), Self::Struct => "struct".fmt(f),
Self::Super => "super".fmt(f), Self::Super => "super".fmt(f),
Self::True => "true".fmt(f), Self::True => "true".fmt(f),
Self::Type => "type".fmt(f),
Self::While => "while".fmt(f), Self::While => "while".fmt(f),
} }
} }
@ -229,6 +231,7 @@ impl FromStr for Keyword {
"struct" => Self::Struct, "struct" => Self::Struct,
"super" => Self::Super, "super" => Self::Super,
"true" => Self::True, "true" => Self::True,
"type" => Self::Type,
"while" => Self::While, "while" => Self::While,
_ => Err(())?, _ => Err(())?,
}) })