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 ;
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*)

View File

@ -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 {

View File

@ -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,

View File

@ -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}")

View File

@ -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)?;

View File

@ -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(())?,
})