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

View File

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