Add Control token type

This commit is contained in:
Jeff 2024-03-07 06:57:33 -05:00
parent c51b142130
commit 85d954181b
2 changed files with 74 additions and 29 deletions

View File

@ -12,7 +12,7 @@ pub enum Token<'src> {
String(&'src str), String(&'src str),
Identifier(&'src str), Identifier(&'src str),
Operator(Operator), Operator(Operator),
Control(&'src str), Control(Control),
Keyword(&'src str), Keyword(&'src str),
} }
@ -61,6 +61,39 @@ impl Display for Operator {
} }
} }
#[derive(Clone, Debug, PartialEq)]
pub enum Control {
CurlyOpen,
CurlyClose,
SquareOpen,
SquareClose,
ParenOpen,
ParenClose,
Comma,
DoubleColon,
Colon,
Dot,
Semicolon,
}
impl Display for Control {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Control::CurlyOpen => write!(f, "{{"),
Control::CurlyClose => write!(f, "}}"),
Control::SquareOpen => write!(f, "["),
Control::SquareClose => write!(f, "]"),
Control::ParenOpen => write!(f, "("),
Control::ParenClose => write!(f, ")"),
Control::Comma => write!(f, ","),
Control::DoubleColon => write!(f, "::"),
Control::Colon => write!(f, ":"),
Control::Dot => write!(f, "."),
Control::Semicolon => write!(f, ";"),
}
}
}
impl<'src> Display for Token<'src> { impl<'src> Display for Token<'src> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self { match self {
@ -70,7 +103,7 @@ impl<'src> Display for Token<'src> {
Token::String(string) => write!(f, "{string}"), Token::String(string) => write!(f, "{string}"),
Token::Identifier(string) => write!(f, "{string}"), Token::Identifier(string) => write!(f, "{string}"),
Token::Operator(operator) => write!(f, "{operator}"), Token::Operator(operator) => write!(f, "{operator}"),
Token::Control(string) => write!(f, "{string}"), Token::Control(control) => write!(f, "{control}"),
Token::Keyword(string) => write!(f, "{string}"), Token::Keyword(string) => write!(f, "{string}"),
} }
} }
@ -158,16 +191,17 @@ pub fn lexer<'src>() -> impl Parser<
.map(Token::Operator); .map(Token::Operator);
let control = choice(( let control = choice((
just("[").padded(), just("{").padded().to(Control::CurlyOpen),
just("]").padded(), just("}").padded().to(Control::CurlyClose),
just("(").padded(), just("[").padded().to(Control::SquareOpen),
just(")").padded(), just("]").padded().to(Control::SquareClose),
just("{").padded(), just("(").padded().to(Control::ParenOpen),
just("}").padded(), just(")").padded().to(Control::ParenClose),
just(",").padded(), just(",").padded().to(Control::Comma),
just(";").padded(), just(";").padded().to(Control::Semicolon),
just("::").padded(), just("::").padded().to(Control::DoubleColon),
just(":").padded(), just(":").padded().to(Control::Colon),
just(".").padded().to(Control::Dot),
)) ))
.map(Token::Control); .map(Token::Control);

View File

@ -5,7 +5,7 @@ use chumsky::{input::SpannedInput, pratt::*, prelude::*};
use crate::{ use crate::{
abstract_tree::*, abstract_tree::*,
error::Error, error::Error,
lexer::{Operator, Token}, lexer::{Control, Operator, Token},
}; };
pub type DustParser<'src> = Boxed< pub type DustParser<'src> = Boxed<
@ -64,16 +64,19 @@ pub fn parser<'src>() -> DustParser<'src> {
let list = expression let list = expression
.clone() .clone()
.separated_by(just(Token::Control(","))) .separated_by(just(Token::Control(Control::Comma)))
.allow_trailing() .allow_trailing()
.collect() .collect()
.delimited_by(just(Token::Control("[")), just(Token::Control("]"))) .delimited_by(
just(Token::Control(Control::SquareOpen)),
just(Token::Control(Control::SquareClose)),
)
.map(|list| Expression::Value(ValueNode::List(list))) .map(|list| Expression::Value(ValueNode::List(list)))
.boxed(); .boxed();
let r#enum = identifier let r#enum = identifier
.clone() .clone()
.then_ignore(just(Token::Control("::"))) .then_ignore(just(Token::Control(Control::DoubleColon)))
.then(identifier.clone()) .then(identifier.clone())
.map(|(name, variant)| Expression::Value(ValueNode::Enum(name, variant))) .map(|(name, variant)| Expression::Value(ValueNode::Enum(name, variant)))
.boxed(); .boxed();
@ -83,9 +86,10 @@ pub fn parser<'src>() -> DustParser<'src> {
basic_value.clone(), basic_value.clone(),
list.clone(), list.clone(),
r#enum.clone(), r#enum.clone(),
expression expression.clone().delimited_by(
.clone() just(Token::Control(Control::ParenOpen)),
.delimited_by(just(Token::Control("(")), just(Token::Control(")"))), just(Token::Control(Control::ParenClose)),
),
)); ));
use Operator::*; use Operator::*;
@ -165,16 +169,20 @@ pub fn parser<'src>() -> DustParser<'src> {
just(Token::Keyword("list")).to(Type::List), just(Token::Keyword("list")).to(Type::List),
)); ));
let type_arguments = basic_type let type_arguments = basic_type.clone().delimited_by(
.clone() just(Token::Control(Control::ParenOpen)),
.delimited_by(just(Token::Control("(")), just(Token::Control(")"))); just(Token::Control(Control::ParenClose)),
);
let type_specification = just(Token::Control(":")).ignore_then(choice(( let type_specification = just(Token::Control(Control::Colon)).ignore_then(choice((
basic_type basic_type
.clone() .clone()
.separated_by(just(Token::Control(","))) .separated_by(just(Token::Control(Control::Comma)))
.collect() .collect()
.delimited_by(just(Token::Control("[")), just(Token::Control("]"))) .delimited_by(
just(Token::Control(Control::SquareOpen)),
just(Token::Control(Control::SquareClose)),
)
.map(|types| Type::ListExact(types)), .map(|types| Type::ListExact(types)),
just(Token::Keyword("list")) just(Token::Keyword("list"))
.then(type_arguments) .then(type_arguments)
@ -198,7 +206,10 @@ pub fn parser<'src>() -> DustParser<'src> {
.clone() .clone()
.repeated() .repeated()
.collect() .collect()
.delimited_by(just(Token::Control("{")), just(Token::Control("}"))) .delimited_by(
just(Token::Control(Control::CurlyOpen)),
just(Token::Control(Control::CurlyClose)),
)
.map(|statements| Statement::Block(Block::new(statements))) .map(|statements| Statement::Block(Block::new(statements)))
.boxed(); .boxed();
@ -207,14 +218,14 @@ pub fn parser<'src>() -> DustParser<'src> {
.repeated() .repeated()
.collect() .collect()
.delimited_by( .delimited_by(
just(Token::Keyword("loop")).then(just(Token::Control("{"))), just(Token::Keyword("loop")).then(just(Token::Control(Control::CurlyOpen))),
just(Token::Control("}")), just(Token::Control(Control::CurlyClose)),
) )
.map(|statements| Statement::Loop(Loop::new(statements))) .map(|statements| Statement::Loop(Loop::new(statements)))
.boxed(); .boxed();
choice((assignment, expression_statement, block, r#loop)) choice((assignment, expression_statement, block, r#loop))
.then_ignore(just(Token::Control(";")).or_not()) .then_ignore(just(Token::Control(Control::Semicolon)).or_not())
}); });
statement statement