Add Control token type
This commit is contained in:
parent
c51b142130
commit
85d954181b
58
src/lexer.rs
58
src/lexer.rs
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user