Fix lexing error
This commit is contained in:
parent
a3591d19af
commit
f544bd008e
@ -63,6 +63,7 @@ impl Display for Operator {
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Control {
|
||||
Arrow,
|
||||
CurlyOpen,
|
||||
CurlyClose,
|
||||
SquareOpen,
|
||||
@ -80,6 +81,7 @@ pub enum Control {
|
||||
impl Display for Control {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Control::Arrow => write!(f, "->"),
|
||||
Control::CurlyOpen => write!(f, "{{"),
|
||||
Control::CurlyClose => write!(f, "}}"),
|
||||
Control::SquareOpen => write!(f, "["),
|
||||
@ -173,10 +175,10 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
just("&&").padded().to(Operator::And),
|
||||
just("==").padded().to(Operator::Equal),
|
||||
just("!=").padded().to(Operator::NotEqual),
|
||||
just(">").padded().to(Operator::Greater),
|
||||
just(">=").padded().to(Operator::GreaterOrEqual),
|
||||
just("<").padded().to(Operator::Less),
|
||||
just("<=").padded().to(Operator::LessOrEqual),
|
||||
just(">").padded().to(Operator::Greater),
|
||||
just("<").padded().to(Operator::Less),
|
||||
just("!").padded().to(Operator::Not),
|
||||
just("!=").padded().to(Operator::NotEqual),
|
||||
just("||").padded().to(Operator::Or),
|
||||
@ -194,6 +196,7 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
.map(Token::Operator);
|
||||
|
||||
let control = choice((
|
||||
just("->").padded().to(Control::Arrow),
|
||||
just("{").padded().to(Control::CurlyOpen),
|
||||
just("}").padded().to(Control::CurlyClose),
|
||||
just("[").padded().to(Control::SquareOpen),
|
||||
@ -227,7 +230,7 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
.map(Token::Keyword);
|
||||
|
||||
choice((
|
||||
boolean, float, integer, string, keyword, identifier, operator, control,
|
||||
boolean, float, integer, string, keyword, identifier, control, operator,
|
||||
))
|
||||
.map_with(|token, state| (token, state.span()))
|
||||
.padded()
|
||||
|
100
src/parser.rs
100
src/parser.rs
@ -66,15 +66,34 @@ pub fn parser<'src>() -> DustParser<'src> {
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
)
|
||||
.then_ignore(just(Token::Control(Control::Colon)))
|
||||
.then_ignore(just(Token::Control(Control::Arrow)))
|
||||
.then(r#type.clone())
|
||||
.map(|(parameter_types, return_type)| Type::Function {
|
||||
parameter_types,
|
||||
return_type: Box::new(return_type),
|
||||
});
|
||||
|
||||
let list_of = just(Token::Keyword("list"))
|
||||
.ignore_then(r#type.clone().delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
))
|
||||
.map(|item_type| Type::ListOf(Box::new(item_type)));
|
||||
|
||||
let list_exact = r#type
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::SquareOpen)),
|
||||
just(Token::Control(Control::SquareClose)),
|
||||
)
|
||||
.map(|types| Type::ListExact(types));
|
||||
|
||||
choice((
|
||||
function_type,
|
||||
list_of,
|
||||
list_exact,
|
||||
just(Token::Keyword("any")).to(Type::Any),
|
||||
just(Token::Keyword("bool")).to(Type::Boolean),
|
||||
just(Token::Keyword("float")).to(Type::Float),
|
||||
@ -83,32 +102,13 @@ pub fn parser<'src>() -> DustParser<'src> {
|
||||
just(Token::Keyword("range")).to(Type::Range),
|
||||
just(Token::Keyword("str")).to(Type::String),
|
||||
just(Token::Keyword("list")).to(Type::List),
|
||||
identifier
|
||||
.clone()
|
||||
.map(|identifier| Type::Custom(identifier)),
|
||||
))
|
||||
});
|
||||
|
||||
let type_arguments = r#type.clone().delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
);
|
||||
|
||||
just(Token::Control(Control::Colon)).ignore_then(choice((
|
||||
r#type
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::SquareOpen)),
|
||||
just(Token::Control(Control::SquareClose)),
|
||||
)
|
||||
.map(|types| Type::ListExact(types)),
|
||||
just(Token::Keyword("list"))
|
||||
.then(type_arguments)
|
||||
.map(|(_, item_type)| Type::ListOf(Box::new(item_type))),
|
||||
r#type.clone(),
|
||||
identifier
|
||||
.clone()
|
||||
.map(|identifier| Type::Custom(identifier)),
|
||||
)))
|
||||
just(Token::Control(Control::Colon)).ignore_then(r#type)
|
||||
});
|
||||
|
||||
let statement = recursive(|statement| {
|
||||
@ -350,12 +350,12 @@ pub fn parser<'src>() -> DustParser<'src> {
|
||||
.boxed();
|
||||
|
||||
choice((
|
||||
if_else,
|
||||
assignment,
|
||||
expression_statement,
|
||||
r#break,
|
||||
block_statement,
|
||||
r#loop,
|
||||
if_else,
|
||||
))
|
||||
.then_ignore(just(Token::Control(Control::Semicolon)).or_not())
|
||||
.boxed()
|
||||
@ -374,6 +374,54 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn types() {
|
||||
assert_eq!(
|
||||
parse(&lex("foobar : bool = true").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::Boolean),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::Boolean(true)))
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
parse(&lex("foobar : list(bool) = [true]").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListOf(Box::new(Type::Boolean))),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value(
|
||||
ValueNode::Boolean(true)
|
||||
)])))
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
parse(&lex("foobar : [bool, str] = [true, '42']").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListExact(vec![Type::Boolean, Type::String])),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||
Expression::Value(ValueNode::Boolean(true)),
|
||||
Expression::Value(ValueNode::String("42".to_string()))
|
||||
])))
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
parse(&lex("foobar : () -> any = some_function").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::Function {
|
||||
parameter_types: vec![],
|
||||
return_type: Box::new(Type::Any)
|
||||
}),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Identifier(Identifier::new("some_function")))
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_call() {
|
||||
assert_eq!(
|
||||
@ -418,7 +466,7 @@ mod tests {
|
||||
))]),
|
||||
None
|
||||
))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -38,7 +38,7 @@ fn callback() {
|
||||
foobar = (cb : () -> str) : str {
|
||||
cb()
|
||||
}
|
||||
foobar(() : str 'Hiya')
|
||||
foobar(() : str { 'Hiya' })
|
||||
",
|
||||
),
|
||||
Ok(Some(Value::string("Hiya".to_string())))
|
||||
|
Loading…
Reference in New Issue
Block a user