Consolidate token symbols
This commit is contained in:
parent
a94251e707
commit
880fb7cd1b
@ -12,7 +12,7 @@ use super::{Block, Evaluate, Evaluation, ExpectedType, Expression, Type, WithPos
|
||||
pub struct IfElse {
|
||||
if_expression: Expression,
|
||||
if_block: WithPosition<Block>,
|
||||
else_ifs: Vec<(Expression, WithPosition<Block>)>,
|
||||
else_ifs: Option<Vec<(Expression, WithPosition<Block>)>>,
|
||||
else_block: Option<WithPosition<Block>>,
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ impl IfElse {
|
||||
pub fn new(
|
||||
if_expression: Expression,
|
||||
if_block: WithPosition<Block>,
|
||||
else_ifs: Vec<(Expression, WithPosition<Block>)>,
|
||||
else_ifs: Option<Vec<(Expression, WithPosition<Block>)>>,
|
||||
else_block: Option<WithPosition<Block>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -61,26 +61,28 @@ impl Evaluate for IfElse {
|
||||
});
|
||||
}
|
||||
|
||||
for (expression, block) in &self.else_ifs {
|
||||
let expression_type = expression.expected_type(context)?;
|
||||
if let Some(else_ifs) = &self.else_ifs {
|
||||
for (expression, block) in else_ifs {
|
||||
let expression_type = expression.expected_type(context)?;
|
||||
|
||||
if let Type::Boolean = expression_type {
|
||||
block.node.validate(context, manage_memory)?;
|
||||
if let Type::Boolean = expression_type {
|
||||
block.node.validate(context, manage_memory)?;
|
||||
|
||||
let actual = block.node.expected_type(context)?;
|
||||
let actual = block.node.expected_type(context)?;
|
||||
|
||||
expected_type
|
||||
.check(&actual)
|
||||
.map_err(|conflict| ValidationError::TypeCheck {
|
||||
conflict,
|
||||
actual_position: self.if_block.node.last_statement().position(),
|
||||
expected_position: Some(self.if_expression.position()),
|
||||
expected_type.check(&actual).map_err(|conflict| {
|
||||
ValidationError::TypeCheck {
|
||||
conflict,
|
||||
actual_position: self.if_block.node.last_statement().position(),
|
||||
expected_position: Some(self.if_expression.position()),
|
||||
}
|
||||
})?;
|
||||
} else {
|
||||
return Err(ValidationError::ExpectedBoolean {
|
||||
actual: if_expression_type,
|
||||
position: self.if_expression.position(),
|
||||
});
|
||||
} else {
|
||||
return Err(ValidationError::ExpectedBoolean {
|
||||
actual: if_expression_type,
|
||||
position: self.if_expression.position(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,9 +106,11 @@ impl Evaluate for IfElse {
|
||||
|
||||
if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() {
|
||||
if *if_boolean {
|
||||
self.if_block.node.evaluate(context, _manage_memory)
|
||||
} else {
|
||||
for (expression, block) in self.else_ifs {
|
||||
return self.if_block.node.evaluate(context, _manage_memory);
|
||||
}
|
||||
|
||||
if let Some(else_ifs) = self.else_ifs {
|
||||
for (expression, block) in else_ifs {
|
||||
let expression_position = expression.position();
|
||||
let action = expression.evaluate(context, _manage_memory)?;
|
||||
let value = if let Evaluation::Return(value) = action {
|
||||
@ -130,12 +134,12 @@ impl Evaluate for IfElse {
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(else_statement) = self.else_block {
|
||||
else_statement.node.evaluate(context, _manage_memory)
|
||||
} else {
|
||||
Ok(Evaluation::None)
|
||||
}
|
||||
if let Some(else_statement) = self.else_block {
|
||||
else_statement.node.evaluate(context, _manage_memory)
|
||||
} else {
|
||||
Ok(Evaluation::None)
|
||||
}
|
||||
} else {
|
||||
Err(RuntimeError::ValidationFailure(
|
||||
@ -172,7 +176,7 @@ mod tests {
|
||||
ValueNode::String("foo".to_string()).with_position((0, 0))
|
||||
))])
|
||||
.with_position((0, 0)),
|
||||
Vec::with_capacity(0),
|
||||
Some(Vec::with_capacity(0)),
|
||||
None
|
||||
)
|
||||
.evaluate(&mut Context::new(None), true)
|
||||
|
@ -15,8 +15,7 @@ pub enum Token<'src> {
|
||||
Float(f64),
|
||||
String(&'src str),
|
||||
Identifier(&'src str),
|
||||
Operator(Operator),
|
||||
Control(Control),
|
||||
Symbol(Symbol),
|
||||
Keyword(Keyword),
|
||||
}
|
||||
|
||||
@ -29,8 +28,7 @@ impl<'src> Display for Token<'src> {
|
||||
Token::Float(float) => write!(f, "{float}"),
|
||||
Token::String(string) => write!(f, "{string}"),
|
||||
Token::Identifier(string) => write!(f, "{string}"),
|
||||
Token::Operator(operator) => write!(f, "{operator}"),
|
||||
Token::Control(control) => write!(f, "{control}"),
|
||||
Token::Symbol(control) => write!(f, "{control}"),
|
||||
Token::Keyword(keyword) => write!(f, "{keyword}"),
|
||||
}
|
||||
}
|
||||
@ -100,91 +98,80 @@ impl Display for Keyword {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Operator {
|
||||
Add,
|
||||
AddAssign,
|
||||
And,
|
||||
Assign,
|
||||
Divide,
|
||||
pub enum Symbol {
|
||||
Plus,
|
||||
PlusEquals,
|
||||
DoubleAmpersand,
|
||||
Colon,
|
||||
Comma,
|
||||
CurlyClose,
|
||||
CurlyOpen,
|
||||
Slash,
|
||||
Dollar,
|
||||
Dot,
|
||||
DoubleColon,
|
||||
DoubleDot,
|
||||
DoubleEqual,
|
||||
DoubleUnderscore,
|
||||
Equal,
|
||||
FatArrow,
|
||||
Greater,
|
||||
GreaterOrEqual,
|
||||
Less,
|
||||
LessOrEqual,
|
||||
Modulo,
|
||||
Multiply,
|
||||
Not,
|
||||
Percent,
|
||||
Asterisk,
|
||||
Exclamation,
|
||||
NotEqual,
|
||||
Or,
|
||||
SubAssign,
|
||||
Subtract,
|
||||
}
|
||||
|
||||
impl Display for Operator {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Operator::Add => write!(f, "+"),
|
||||
Operator::AddAssign => write!(f, "+="),
|
||||
Operator::And => write!(f, "&&"),
|
||||
Operator::Assign => write!(f, "="),
|
||||
Operator::Divide => write!(f, "="),
|
||||
Operator::Equal => write!(f, "=="),
|
||||
Operator::Greater => write!(f, ">"),
|
||||
Operator::GreaterOrEqual => write!(f, ">="),
|
||||
Operator::Less => write!(f, "<"),
|
||||
Operator::LessOrEqual => write!(f, "<="),
|
||||
Operator::Modulo => write!(f, "%"),
|
||||
Operator::Multiply => write!(f, "*"),
|
||||
Operator::Not => write!(f, "!"),
|
||||
Operator::NotEqual => write!(f, "!="),
|
||||
Operator::Or => write!(f, "||"),
|
||||
Operator::SubAssign => write!(f, "-="),
|
||||
Operator::Subtract => write!(f, "-"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Control {
|
||||
CurlyOpen,
|
||||
CurlyClose,
|
||||
SquareOpen,
|
||||
SquareClose,
|
||||
ParenOpen,
|
||||
DoublePipe,
|
||||
ParenClose,
|
||||
ParenOpen,
|
||||
Pipe,
|
||||
Comma,
|
||||
DoubleColon,
|
||||
Colon,
|
||||
Dollar,
|
||||
Dot,
|
||||
DoubleDot,
|
||||
Semicolon,
|
||||
SkinnyArrow,
|
||||
FatArrow,
|
||||
DoubleUnderscore,
|
||||
SquareClose,
|
||||
SquareOpen,
|
||||
MinusEqual,
|
||||
Minus,
|
||||
}
|
||||
|
||||
impl Display for Control {
|
||||
impl Display for Symbol {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Control::CurlyOpen => write!(f, "{{"),
|
||||
Control::CurlyClose => write!(f, "}}"),
|
||||
Control::Dollar => write!(f, "$"),
|
||||
Control::SquareOpen => write!(f, "["),
|
||||
Control::SquareClose => write!(f, "]"),
|
||||
Control::ParenOpen => write!(f, "("),
|
||||
Control::ParenClose => write!(f, ")"),
|
||||
Control::Pipe => write!(f, "|"),
|
||||
Control::Comma => write!(f, ","),
|
||||
Control::DoubleColon => write!(f, "::"),
|
||||
Control::Colon => write!(f, ":"),
|
||||
Control::Dot => write!(f, "."),
|
||||
Control::Semicolon => write!(f, ";"),
|
||||
Control::DoubleDot => write!(f, ".."),
|
||||
Control::SkinnyArrow => write!(f, "->"),
|
||||
Control::FatArrow => write!(f, "=>"),
|
||||
Control::DoubleUnderscore => write!(f, "__"),
|
||||
Symbol::Asterisk => write!(f, "*"),
|
||||
Symbol::Colon => write!(f, ":"),
|
||||
Symbol::Comma => write!(f, ","),
|
||||
Symbol::CurlyClose => write!(f, "}}"),
|
||||
Symbol::CurlyOpen => write!(f, "{{"),
|
||||
Symbol::Dollar => write!(f, "$"),
|
||||
Symbol::Dot => write!(f, "."),
|
||||
Symbol::DoubleAmpersand => write!(f, "&&"),
|
||||
Symbol::DoubleColon => write!(f, "::"),
|
||||
Symbol::DoubleDot => write!(f, ".."),
|
||||
Symbol::DoubleEqual => write!(f, "=="),
|
||||
Symbol::DoublePipe => write!(f, "||"),
|
||||
Symbol::DoubleUnderscore => write!(f, "__"),
|
||||
Symbol::Equal => write!(f, "="),
|
||||
Symbol::Exclamation => write!(f, "!"),
|
||||
Symbol::FatArrow => write!(f, "=>"),
|
||||
Symbol::Greater => write!(f, ">"),
|
||||
Symbol::GreaterOrEqual => write!(f, ">="),
|
||||
Symbol::Less => write!(f, "<"),
|
||||
Symbol::LessOrEqual => write!(f, "<="),
|
||||
Symbol::Minus => write!(f, "-"),
|
||||
Symbol::MinusEqual => write!(f, "-="),
|
||||
Symbol::NotEqual => write!(f, "!="),
|
||||
Symbol::ParenClose => write!(f, ")"),
|
||||
Symbol::ParenOpen => write!(f, "("),
|
||||
Symbol::Percent => write!(f, "%"),
|
||||
Symbol::Pipe => write!(f, "|"),
|
||||
Symbol::Plus => write!(f, "+"),
|
||||
Symbol::PlusEquals => write!(f, "+="),
|
||||
Symbol::Semicolon => write!(f, ";"),
|
||||
Symbol::SkinnyArrow => write!(f, "->"),
|
||||
Symbol::Slash => write!(f, "/"),
|
||||
Symbol::SquareClose => write!(f, "]"),
|
||||
Symbol::SquareOpen => write!(f, "["),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,51 +281,42 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
_ => Token::Identifier(text),
|
||||
});
|
||||
|
||||
let operator = choice((
|
||||
// logic
|
||||
just("&&").to(Operator::And),
|
||||
just("==").to(Operator::Equal),
|
||||
just("!=").to(Operator::NotEqual),
|
||||
just(">=").to(Operator::GreaterOrEqual),
|
||||
just("<=").to(Operator::LessOrEqual),
|
||||
just(">").to(Operator::Greater),
|
||||
just("<").to(Operator::Less),
|
||||
just("!").to(Operator::Not),
|
||||
just("!=").to(Operator::NotEqual),
|
||||
just("||").to(Operator::Or),
|
||||
// assignment
|
||||
just("=").to(Operator::Assign),
|
||||
just("+=").to(Operator::AddAssign),
|
||||
just("-=").to(Operator::SubAssign),
|
||||
// math
|
||||
just("+").to(Operator::Add),
|
||||
just("-").to(Operator::Subtract),
|
||||
just("*").to(Operator::Multiply),
|
||||
just("/").to(Operator::Divide),
|
||||
just("%").to(Operator::Modulo),
|
||||
))
|
||||
.map(Token::Operator);
|
||||
|
||||
let control = choice((
|
||||
just("->").to(Control::SkinnyArrow),
|
||||
just("=>").to(Control::FatArrow),
|
||||
just("{").to(Control::CurlyOpen),
|
||||
just("}").to(Control::CurlyClose),
|
||||
just("[").to(Control::SquareOpen),
|
||||
just("]").to(Control::SquareClose),
|
||||
just("(").to(Control::ParenOpen),
|
||||
just(")").to(Control::ParenClose),
|
||||
just("|").to(Control::Pipe),
|
||||
just(",").to(Control::Comma),
|
||||
just(";").to(Control::Semicolon),
|
||||
just("::").to(Control::DoubleColon),
|
||||
just(":").to(Control::Colon),
|
||||
just("..").to(Control::DoubleDot),
|
||||
just(".").to(Control::Dot),
|
||||
just("$").to(Control::Dollar),
|
||||
just("__").to(Control::DoubleUnderscore),
|
||||
))
|
||||
.map(Token::Control);
|
||||
let symbol = choice([
|
||||
just("!=").to(Token::Symbol(Symbol::NotEqual)),
|
||||
just("!").to(Token::Symbol(Symbol::Exclamation)),
|
||||
just("$").to(Token::Symbol(Symbol::Dollar)),
|
||||
just("%").to(Token::Symbol(Symbol::Percent)),
|
||||
just("&&").to(Token::Symbol(Symbol::DoubleAmpersand)),
|
||||
just("(").to(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(")").to(Token::Symbol(Symbol::ParenClose)),
|
||||
just("*").to(Token::Symbol(Symbol::Asterisk)),
|
||||
just("+=").to(Token::Symbol(Symbol::PlusEquals)),
|
||||
just("+").to(Token::Symbol(Symbol::Plus)),
|
||||
just(",").to(Token::Symbol(Symbol::Comma)),
|
||||
just("->").to(Token::Symbol(Symbol::SkinnyArrow)),
|
||||
just("-=").to(Token::Symbol(Symbol::MinusEqual)),
|
||||
just("-").to(Token::Symbol(Symbol::Minus)),
|
||||
just("..").to(Token::Symbol(Symbol::DoubleDot)),
|
||||
just(".").to(Token::Symbol(Symbol::Dot)),
|
||||
just("/").to(Token::Symbol(Symbol::Slash)),
|
||||
just("::").to(Token::Symbol(Symbol::DoubleColon)),
|
||||
just(":").to(Token::Symbol(Symbol::Colon)),
|
||||
just(";").to(Token::Symbol(Symbol::Semicolon)),
|
||||
just("<=").to(Token::Symbol(Symbol::LessOrEqual)),
|
||||
just("<").to(Token::Symbol(Symbol::Less)),
|
||||
just("=>").to(Token::Symbol(Symbol::FatArrow)),
|
||||
just("==").to(Token::Symbol(Symbol::DoubleEqual)),
|
||||
just("=").to(Token::Symbol(Symbol::Equal)),
|
||||
just(">=").to(Token::Symbol(Symbol::GreaterOrEqual)),
|
||||
just(">").to(Token::Symbol(Symbol::Greater)),
|
||||
just("[").to(Token::Symbol(Symbol::SquareOpen)),
|
||||
just("]").to(Token::Symbol(Symbol::SquareClose)),
|
||||
just("__").to(Token::Symbol(Symbol::DoubleUnderscore)),
|
||||
just("{").to(Token::Symbol(Symbol::CurlyOpen)),
|
||||
just("||").to(Token::Symbol(Symbol::DoublePipe)),
|
||||
just("|").to(Token::Symbol(Symbol::Pipe)),
|
||||
just("}").to(Token::Symbol(Symbol::CurlyClose)),
|
||||
]);
|
||||
|
||||
choice((
|
||||
line_comment,
|
||||
@ -348,10 +326,9 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
integer,
|
||||
string,
|
||||
identifier_and_keyword,
|
||||
control,
|
||||
operator,
|
||||
symbol,
|
||||
))
|
||||
.map_with(|token, state| (token, state.span()))
|
||||
.map_with(|token: Token, state| (token, state.span()))
|
||||
.padded()
|
||||
.repeated()
|
||||
.collect()
|
||||
@ -427,7 +404,7 @@ mod tests {
|
||||
lex("1..10").unwrap(),
|
||||
vec![
|
||||
(Token::Integer(1), (0..1).into()),
|
||||
(Token::Control(Control::DoubleDot), (1..3).into()),
|
||||
(Token::Symbol(Symbol::DoubleDot), (1..3).into()),
|
||||
(Token::Integer(10), (3..5).into())
|
||||
]
|
||||
)
|
||||
@ -439,7 +416,7 @@ mod tests {
|
||||
lex("1 + 1").unwrap(),
|
||||
vec![
|
||||
(Token::Integer(1), (0..1).into()),
|
||||
(Token::Operator(Operator::Add), (2..3).into()),
|
||||
(Token::Symbol(Symbol::Plus), (2..3).into()),
|
||||
(Token::Integer(1), (4..5).into())
|
||||
]
|
||||
)
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
abstract_tree::*,
|
||||
error::DustError,
|
||||
identifier::Identifier,
|
||||
lexer::{Control, Keyword, Operator, Token},
|
||||
lexer::{Keyword, Symbol, Token},
|
||||
};
|
||||
|
||||
use self::{
|
||||
@ -96,26 +96,26 @@ pub fn parser<'src>(
|
||||
.ignore_then(
|
||||
positioned_identifier
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.at_least(1)
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::Pipe)),
|
||||
just(Token::Control(Control::Pipe)),
|
||||
just(Token::Symbol(Symbol::Pipe)),
|
||||
just(Token::Symbol(Symbol::Pipe)),
|
||||
)
|
||||
.or_not(),
|
||||
)
|
||||
.then(
|
||||
type_constructor
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
just(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(Token::Symbol(Symbol::ParenClose)),
|
||||
),
|
||||
)
|
||||
.then_ignore(just(Token::Control(Control::SkinnyArrow)))
|
||||
.then_ignore(just(Token::Symbol(Symbol::SkinnyArrow)))
|
||||
.then(type_constructor.clone())
|
||||
.map_with(
|
||||
|((type_parameters, value_parameters), return_type), state| {
|
||||
@ -132,11 +132,11 @@ pub fn parser<'src>(
|
||||
|
||||
let list_type = type_constructor
|
||||
.clone()
|
||||
.then_ignore(just(Token::Control(Control::Semicolon)))
|
||||
.then_ignore(just(Token::Symbol(Symbol::Semicolon)))
|
||||
.then(raw_integer.clone())
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::SquareOpen)),
|
||||
just(Token::Control(Control::SquareClose)),
|
||||
just(Token::Symbol(Symbol::SquareOpen)),
|
||||
just(Token::Symbol(Symbol::SquareClose)),
|
||||
)
|
||||
.map_with(|(item_type, length), state| {
|
||||
TypeConstructor::List(
|
||||
@ -151,8 +151,8 @@ pub fn parser<'src>(
|
||||
let list_of_type = type_constructor
|
||||
.clone()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::SquareOpen)),
|
||||
just(Token::Control(Control::SquareClose)),
|
||||
just(Token::Symbol(Symbol::SquareOpen)),
|
||||
just(Token::Symbol(Symbol::SquareClose)),
|
||||
)
|
||||
.map_with(|item_type, state| {
|
||||
TypeConstructor::ListOf(Box::new(item_type).with_position(state.span()))
|
||||
@ -163,13 +163,13 @@ pub fn parser<'src>(
|
||||
.then(
|
||||
type_constructor
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.at_least(1)
|
||||
.allow_trailing()
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
just(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(Token::Symbol(Symbol::ParenClose)),
|
||||
)
|
||||
.or_not(),
|
||||
)
|
||||
@ -190,7 +190,7 @@ pub fn parser<'src>(
|
||||
});
|
||||
|
||||
let type_specification =
|
||||
just(Token::Control(Control::Colon)).ignore_then(type_constructor.clone());
|
||||
just(Token::Symbol(Symbol::Colon)).ignore_then(type_constructor.clone());
|
||||
|
||||
let statement = recursive(|statement| {
|
||||
let allow_built_ins = allow_built_ins.clone();
|
||||
@ -201,8 +201,8 @@ pub fn parser<'src>(
|
||||
.at_least(1)
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::CurlyOpen)),
|
||||
just(Token::Control(Control::CurlyClose)),
|
||||
just(Token::Symbol(Symbol::CurlyOpen)),
|
||||
just(Token::Symbol(Symbol::CurlyClose)),
|
||||
)
|
||||
.map_with(|statements, state| Block::new(statements).with_position(state.span()));
|
||||
|
||||
@ -215,7 +215,7 @@ pub fn parser<'src>(
|
||||
|
||||
let range = raw_integer
|
||||
.clone()
|
||||
.then_ignore(just(Token::Control(Control::DoubleDot)))
|
||||
.then_ignore(just(Token::Symbol(Symbol::DoubleDot)))
|
||||
.then(raw_integer)
|
||||
.map_with(|(start, end), state| {
|
||||
Expression::Value(ValueNode::Range(start..end).with_position(state.span()))
|
||||
@ -223,12 +223,12 @@ pub fn parser<'src>(
|
||||
|
||||
let list = expression
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.allow_trailing()
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::SquareOpen)),
|
||||
just(Token::Control(Control::SquareClose)),
|
||||
just(Token::Symbol(Symbol::SquareOpen)),
|
||||
just(Token::Symbol(Symbol::SquareClose)),
|
||||
)
|
||||
.map_with(|list, state| {
|
||||
Expression::Value(ValueNode::List(list).with_position(state.span()))
|
||||
@ -237,17 +237,17 @@ pub fn parser<'src>(
|
||||
let map_fields = identifier
|
||||
.clone()
|
||||
.then(type_specification.clone().or_not())
|
||||
.then_ignore(just(Token::Operator(Operator::Assign)))
|
||||
.then_ignore(just(Token::Symbol(Symbol::Equal)))
|
||||
.then(expression.clone())
|
||||
.map(|((identifier, r#type), expression)| (identifier, r#type, expression));
|
||||
|
||||
let map = map_fields
|
||||
.separated_by(just(Token::Control(Control::Comma)).or_not())
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)).or_not())
|
||||
.allow_trailing()
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::CurlyOpen)),
|
||||
just(Token::Control(Control::CurlyClose)),
|
||||
just(Token::Symbol(Symbol::CurlyOpen)),
|
||||
just(Token::Symbol(Symbol::CurlyClose)),
|
||||
)
|
||||
.map_with(|map_assigment_list, state| {
|
||||
Expression::Value(
|
||||
@ -259,30 +259,30 @@ pub fn parser<'src>(
|
||||
.ignore_then(
|
||||
identifier
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.at_least(1)
|
||||
.allow_trailing()
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::Pipe)),
|
||||
just(Token::Control(Control::Pipe)),
|
||||
just(Token::Symbol(Symbol::Pipe)),
|
||||
just(Token::Symbol(Symbol::Pipe)),
|
||||
)
|
||||
.or_not(),
|
||||
)
|
||||
.then(
|
||||
identifier
|
||||
.clone()
|
||||
.then_ignore(just(Token::Control(Control::Colon)))
|
||||
.then_ignore(just(Token::Symbol(Symbol::Colon)))
|
||||
.then(type_constructor.clone())
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.allow_trailing()
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
just(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(Token::Symbol(Symbol::ParenClose)),
|
||||
),
|
||||
)
|
||||
.then_ignore(just(Token::Control(Control::SkinnyArrow)))
|
||||
.then_ignore(just(Token::Symbol(Symbol::SkinnyArrow)))
|
||||
.then(type_constructor.clone())
|
||||
.then(block.clone())
|
||||
.map_with(
|
||||
@ -301,16 +301,16 @@ pub fn parser<'src>(
|
||||
|
||||
let enum_instance = positioned_identifier
|
||||
.clone()
|
||||
.then_ignore(just(Token::Control(Control::DoubleColon)))
|
||||
.then_ignore(just(Token::Symbol(Symbol::DoubleColon)))
|
||||
.then(positioned_identifier.clone())
|
||||
.then(
|
||||
expression
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
just(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(Token::Symbol(Symbol::ParenClose)),
|
||||
)
|
||||
.or_not(),
|
||||
)
|
||||
@ -386,16 +386,16 @@ pub fn parser<'src>(
|
||||
|
||||
let turbofish = type_constructor
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.at_least(1)
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
just(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(Token::Symbol(Symbol::ParenClose)),
|
||||
)
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::DoubleColon)),
|
||||
just(Token::Control(Control::DoubleColon)),
|
||||
just(Token::Symbol(Symbol::DoubleColon)),
|
||||
just(Token::Symbol(Symbol::DoubleColon)),
|
||||
);
|
||||
|
||||
let atom = choice((
|
||||
@ -407,8 +407,8 @@ pub fn parser<'src>(
|
||||
basic_value.clone(),
|
||||
identifier_expression.clone(),
|
||||
expression.clone().delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
just(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(Token::Symbol(Symbol::ParenClose)),
|
||||
),
|
||||
));
|
||||
|
||||
@ -416,21 +416,21 @@ pub fn parser<'src>(
|
||||
// Logic
|
||||
prefix(
|
||||
2,
|
||||
just(Token::Operator(Operator::Not)),
|
||||
just(Token::Symbol(Symbol::Exclamation)),
|
||||
|_, expression, span| {
|
||||
Expression::Logic(Box::new(Logic::Not(expression)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::Equal)),
|
||||
just(Token::Symbol(Symbol::DoubleEqual)),
|
||||
|left, _, right, span| {
|
||||
Expression::Logic(Box::new(Logic::Equal(left, right)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::NotEqual)),
|
||||
just(Token::Symbol(Symbol::NotEqual)),
|
||||
|left, _, right, span| {
|
||||
Expression::Logic(
|
||||
Box::new(Logic::NotEqual(left, right)).with_position(span),
|
||||
@ -439,21 +439,21 @@ pub fn parser<'src>(
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::Greater)),
|
||||
just(Token::Symbol(Symbol::Greater)),
|
||||
|left, _, right, span| {
|
||||
Expression::Logic(Box::new(Logic::Greater(left, right)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::Less)),
|
||||
just(Token::Symbol(Symbol::Less)),
|
||||
|left, _, right, span| {
|
||||
Expression::Logic(Box::new(Logic::Less(left, right)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::GreaterOrEqual)),
|
||||
just(Token::Symbol(Symbol::GreaterOrEqual)),
|
||||
|left, _, right, span| {
|
||||
Expression::Logic(
|
||||
Box::new(Logic::GreaterOrEqual(left, right)).with_position(span),
|
||||
@ -462,7 +462,7 @@ pub fn parser<'src>(
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::LessOrEqual)),
|
||||
just(Token::Symbol(Symbol::LessOrEqual)),
|
||||
|left, _, right, span| {
|
||||
Expression::Logic(
|
||||
Box::new(Logic::LessOrEqual(left, right)).with_position(span),
|
||||
@ -471,14 +471,14 @@ pub fn parser<'src>(
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::And)),
|
||||
just(Token::Symbol(Symbol::DoubleAmpersand)),
|
||||
|left, _, right, span| {
|
||||
Expression::Logic(Box::new(Logic::And(left, right)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::Or)),
|
||||
just(Token::Symbol(Symbol::DoublePipe)),
|
||||
|left, _, right, span| {
|
||||
Expression::Logic(Box::new(Logic::Or(left, right)).with_position(span))
|
||||
},
|
||||
@ -486,35 +486,35 @@ pub fn parser<'src>(
|
||||
// Math
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::Add)),
|
||||
just(Token::Symbol(Symbol::Plus)),
|
||||
|left, _, right, span| {
|
||||
Expression::Math(Box::new(Math::Add(left, right)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::Subtract)),
|
||||
just(Token::Symbol(Symbol::Minus)),
|
||||
|left, _, right, span| {
|
||||
Expression::Math(Box::new(Math::Subtract(left, right)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(2),
|
||||
just(Token::Operator(Operator::Multiply)),
|
||||
just(Token::Symbol(Symbol::Asterisk)),
|
||||
|left, _, right, span| {
|
||||
Expression::Math(Box::new(Math::Multiply(left, right)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(2),
|
||||
just(Token::Operator(Operator::Divide)),
|
||||
just(Token::Symbol(Symbol::Slash)),
|
||||
|left, _, right, span| {
|
||||
Expression::Math(Box::new(Math::Divide(left, right)).with_position(span))
|
||||
},
|
||||
),
|
||||
infix(
|
||||
left(1),
|
||||
just(Token::Operator(Operator::Modulo)),
|
||||
just(Token::Symbol(Symbol::Slash)),
|
||||
|left, _, right, span| {
|
||||
Expression::Math(Box::new(Math::Modulo(left, right)).with_position(span))
|
||||
},
|
||||
@ -522,7 +522,7 @@ pub fn parser<'src>(
|
||||
// Indexes
|
||||
infix(
|
||||
left(4),
|
||||
just(Token::Control(Control::Dot)),
|
||||
just(Token::Symbol(Symbol::Dot)),
|
||||
|left, _, right, span| {
|
||||
Expression::MapIndex(
|
||||
Box::new(MapIndex::new(left, right)).with_position(span),
|
||||
@ -532,8 +532,8 @@ pub fn parser<'src>(
|
||||
postfix(
|
||||
3,
|
||||
expression.clone().delimited_by(
|
||||
just(Token::Control(Control::SquareOpen)),
|
||||
just(Token::Control(Control::SquareClose)),
|
||||
just(Token::Symbol(Symbol::SquareOpen)),
|
||||
just(Token::Symbol(Symbol::SquareClose)),
|
||||
),
|
||||
|left, right, span| {
|
||||
Expression::ListIndex(
|
||||
@ -547,11 +547,11 @@ pub fn parser<'src>(
|
||||
turbofish.clone().or_not().then(
|
||||
expression
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
just(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(Token::Symbol(Symbol::ParenClose)),
|
||||
),
|
||||
),
|
||||
|function_expression, (type_parameters, value_parameters), span| {
|
||||
@ -596,8 +596,8 @@ pub fn parser<'src>(
|
||||
|
||||
let async_block = just(Token::Keyword(Keyword::Async))
|
||||
.ignore_then(statement.clone().repeated().collect().delimited_by(
|
||||
just(Token::Control(Control::CurlyOpen)),
|
||||
just(Token::Control(Control::CurlyClose)),
|
||||
just(Token::Symbol(Symbol::CurlyOpen)),
|
||||
just(Token::Symbol(Symbol::CurlyClose)),
|
||||
))
|
||||
.map_with(|statements, state| {
|
||||
Statement::AsyncBlock(AsyncBlock::new(statements).with_position(state.span()))
|
||||
@ -610,9 +610,9 @@ pub fn parser<'src>(
|
||||
.clone()
|
||||
.then(type_specification.clone().or_not())
|
||||
.then(choice((
|
||||
just(Token::Operator(Operator::Assign)).to(AssignmentOperator::Assign),
|
||||
just(Token::Operator(Operator::AddAssign)).to(AssignmentOperator::AddAssign),
|
||||
just(Token::Operator(Operator::SubAssign)).to(AssignmentOperator::SubAssign),
|
||||
just(Token::Symbol(Symbol::Equal)).to(AssignmentOperator::Assign),
|
||||
just(Token::Symbol(Symbol::PlusEquals)).to(AssignmentOperator::AddAssign),
|
||||
just(Token::Symbol(Symbol::MinusEqual)).to(AssignmentOperator::SubAssign),
|
||||
)))
|
||||
.then(statement.clone())
|
||||
.map_with(|(((identifier, r#type), operator), statement), state| {
|
||||
@ -630,8 +630,8 @@ pub fn parser<'src>(
|
||||
.at_least(1)
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Keyword(Keyword::Loop)).then(just(Token::Control(Control::CurlyOpen))),
|
||||
just(Token::Control(Control::CurlyClose)),
|
||||
just(Token::Keyword(Keyword::Loop)).then(just(Token::Symbol(Symbol::CurlyOpen))),
|
||||
just(Token::Symbol(Symbol::CurlyClose)),
|
||||
)
|
||||
.map_with(|statements, state| {
|
||||
Statement::Loop(Loop::new(statements).with_position(state.span()))
|
||||
@ -640,8 +640,8 @@ pub fn parser<'src>(
|
||||
let r#while = just(Token::Keyword(Keyword::While))
|
||||
.ignore_then(expression.clone())
|
||||
.then(statement.clone().repeated().collect().delimited_by(
|
||||
just(Token::Control(Control::CurlyOpen)),
|
||||
just(Token::Control(Control::CurlyClose)),
|
||||
just(Token::Symbol(Symbol::CurlyOpen)),
|
||||
just(Token::Symbol(Symbol::CurlyClose)),
|
||||
))
|
||||
.map_with(|(expression, statements), state| {
|
||||
Statement::While(While::new(expression, statements).with_position(state.span()))
|
||||
@ -656,7 +656,9 @@ pub fn parser<'src>(
|
||||
.ignore_then(expression.clone())
|
||||
.then(block.clone())
|
||||
.repeated()
|
||||
.collect(),
|
||||
.at_least(1)
|
||||
.collect()
|
||||
.or_not(),
|
||||
)
|
||||
.then(
|
||||
just(Token::Keyword(Keyword::Else))
|
||||
@ -674,7 +676,7 @@ 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_ignore(just(Token::Symbol(Symbol::Equal)))
|
||||
.then(type_constructor.clone())
|
||||
.map_with(|(identifier, constructor), state| {
|
||||
Statement::TypeAlias(
|
||||
@ -687,11 +689,11 @@ pub fn parser<'src>(
|
||||
.then(
|
||||
type_constructor
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::ParenOpen)),
|
||||
just(Token::Control(Control::ParenClose)),
|
||||
just(Token::Symbol(Symbol::ParenOpen)),
|
||||
just(Token::Symbol(Symbol::ParenClose)),
|
||||
)
|
||||
.or_not(),
|
||||
)
|
||||
@ -705,24 +707,24 @@ pub fn parser<'src>(
|
||||
.then(
|
||||
positioned_identifier
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.allow_trailing()
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Operator(Operator::Less)),
|
||||
just(Token::Operator(Operator::Greater)),
|
||||
just(Token::Symbol(Symbol::Less)),
|
||||
just(Token::Symbol(Symbol::Greater)),
|
||||
)
|
||||
.or_not(),
|
||||
)
|
||||
.then(
|
||||
enum_variant
|
||||
.separated_by(just(Token::Control(Control::Comma)))
|
||||
.separated_by(just(Token::Symbol(Symbol::Comma)))
|
||||
.allow_trailing()
|
||||
.at_least(1)
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Control(Control::CurlyOpen)),
|
||||
just(Token::Control(Control::CurlyClose)),
|
||||
just(Token::Symbol(Symbol::CurlyOpen)),
|
||||
just(Token::Symbol(Symbol::CurlyClose)),
|
||||
),
|
||||
)
|
||||
.map_with(|((name, type_parameters), variants), state| {
|
||||
@ -751,7 +753,7 @@ pub fn parser<'src>(
|
||||
type_alias,
|
||||
enum_declaration,
|
||||
)))
|
||||
.then_ignore(just(Token::Control(Control::Semicolon)).or_not())
|
||||
.then_ignore(just(Token::Symbol(Symbol::Semicolon)).or_not())
|
||||
});
|
||||
|
||||
statement.repeated().collect()
|
||||
|
@ -587,7 +587,7 @@ fn r#if() {
|
||||
ValueNode::String("foo".to_string()).with_position((10, 15))
|
||||
))])
|
||||
.with_position((8, 17)),
|
||||
Vec::with_capacity(0),
|
||||
None,
|
||||
None
|
||||
)
|
||||
.with_position((0, 17))
|
||||
@ -606,7 +606,7 @@ fn if_else() {
|
||||
ValueNode::String("foo".to_string()).with_position((9, 14))
|
||||
))])
|
||||
.with_position((8, 16)),
|
||||
Vec::with_capacity(0),
|
||||
None,
|
||||
Some(
|
||||
Block::new(vec![Statement::Expression(Expression::Value(
|
||||
ValueNode::String("bar".to_string()).with_position((24, 29))
|
||||
@ -695,6 +695,10 @@ fn r#loop() {
|
||||
.with_position((0, 11))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex_loop() {
|
||||
assert_eq!(
|
||||
parse(&lex("loop { if i > 2 { break } else { i += 1 } }").unwrap()).unwrap()[0],
|
||||
Statement::Loop(
|
||||
@ -709,7 +713,7 @@ fn r#loop() {
|
||||
),
|
||||
Block::new(vec![Statement::Break(().with_position((18, 23)))])
|
||||
.with_position((16, 25)),
|
||||
Vec::with_capacity(0),
|
||||
None,
|
||||
Some(
|
||||
Block::new(vec![Statement::Assignment(
|
||||
Assignment::new(
|
||||
|
Loading…
Reference in New Issue
Block a user