Add type aliases

This commit is contained in:
Jeff 2024-06-15 21:13:11 -04:00
parent f5bcf9511a
commit 54071eb8c0
4 changed files with 74 additions and 3 deletions

View File

@ -14,6 +14,7 @@ pub mod math;
pub mod statement;
pub mod structure_definition;
pub mod r#type;
pub mod type_alias;
pub mod value_node;
pub mod r#while;
@ -40,6 +41,7 @@ pub use self::{
r#while::While,
statement::Statement,
structure_definition::StructureDefinition,
type_alias::TypeAlias,
value_node::ValueNode,
};

View File

@ -7,7 +7,7 @@ use crate::{
use super::{
AbstractNode, Action, Assignment, AsyncBlock, Block, Expression, IfElse, Loop, SourcePosition,
StructureDefinition, Type, While, WithPosition,
StructureDefinition, Type, TypeAlias, While, WithPosition,
};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
@ -20,6 +20,7 @@ pub enum Statement {
IfElse(WithPosition<IfElse>),
Loop(WithPosition<Loop>),
StructureDefinition(WithPosition<StructureDefinition>),
TypeAlias(WithPosition<TypeAlias>),
While(WithPosition<While>),
}
@ -34,6 +35,7 @@ impl Statement {
Statement::IfElse(inner) => inner.position,
Statement::Loop(inner) => inner.position,
Statement::StructureDefinition(inner) => inner.position,
Statement::TypeAlias(inner) => inner.position,
Statement::While(inner) => inner.position,
}
}
@ -50,6 +52,7 @@ impl AbstractNode for Statement {
Statement::IfElse(if_else) => if_else.item.expected_type(_context),
Statement::Loop(r#loop) => r#loop.item.expected_type(_context),
Statement::While(r#while) => r#while.item.expected_type(_context),
Statement::TypeAlias(type_alias) => type_alias.item.expected_type(_context),
Statement::StructureDefinition(structure_definition) => {
structure_definition.item.expected_type(_context)
}
@ -71,10 +74,11 @@ impl AbstractNode for Statement {
Statement::Expression(expression) => expression.validate(_context, _manage_memory),
Statement::IfElse(if_else) => if_else.item.validate(_context, _manage_memory),
Statement::Loop(r#loop) => r#loop.item.validate(_context, _manage_memory),
Statement::While(r#while) => r#while.item.validate(_context, _manage_memory),
Statement::StructureDefinition(structure_definition) => {
structure_definition.item.validate(_context, _manage_memory)
}
Statement::TypeAlias(type_alias) => type_alias.item.validate(_context, _manage_memory),
Statement::While(r#while) => r#while.item.validate(_context, _manage_memory),
}
}
@ -87,10 +91,11 @@ impl AbstractNode for Statement {
Statement::Expression(expression) => expression.run(context, manage_memory),
Statement::IfElse(if_else) => if_else.item.run(context, manage_memory),
Statement::Loop(r#loop) => r#loop.item.run(context, manage_memory),
Statement::While(r#while) => r#while.item.run(context, manage_memory),
Statement::StructureDefinition(structure_definition) => {
structure_definition.item.run(context, manage_memory)
}
Statement::TypeAlias(type_alias) => type_alias.item.run(context, manage_memory),
Statement::While(r#while) => r#while.item.run(context, manage_memory),
};
if manage_memory {

View File

@ -0,0 +1,41 @@
use serde::{Deserialize, Serialize};
use crate::{
context::Context,
error::{RuntimeError, ValidationError},
identifier::Identifier,
};
use super::{AbstractNode, Action, Type, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct TypeAlias {
identifier: WithPosition<Identifier>,
r#type: WithPosition<Type>,
}
impl TypeAlias {
pub fn new(identifier: WithPosition<Identifier>, r#type: WithPosition<Type>) -> Self {
Self { identifier, r#type }
}
}
impl AbstractNode for TypeAlias {
fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> {
Ok(Type::None)
}
fn validate(
&self,
_context: &mut Context,
_manage_memory: bool,
) -> Result<(), ValidationError> {
Ok(())
}
fn run(self, context: &mut Context, _manage_memory: bool) -> Result<Action, RuntimeError> {
context.set_type(self.identifier.item, self.r#type.item)?;
Ok(Action::None)
}
}

View File

@ -630,6 +630,14 @@ pub fn parser<'src>(
},
);
let type_alias = just(Token::Keyword(Keyword::Type))
.ignore_then(positioned_identifier.clone())
.then_ignore(just(Token::Operator(Operator::Assign)))
.then(r#type.clone())
.map_with(|(identifier, r#type), state| {
Statement::TypeAlias(TypeAlias::new(identifier, r#type).with_position(state.span()))
});
choice((
async_block,
structure_definition,
@ -640,6 +648,7 @@ pub fn parser<'src>(
block_statement,
r#loop,
r#while,
type_alias,
))
.then_ignore(just(Token::Control(Control::Semicolon)).or_not())
});
@ -659,6 +668,20 @@ mod tests {
use super::*;
#[test]
fn type_alias() {
assert_eq!(
parse(&lex("type MyType = str").unwrap()).unwrap()[0],
Statement::TypeAlias(
TypeAlias::new(
Identifier::new("MyType").with_position((5, 11)),
Type::String.with_position((14, 17))
)
.with_position((0, 17))
)
)
}
#[test]
fn r#as() {
assert_eq!(