|
|
@@ -258,7 +258,7 @@ impl ParseError {
|
|
|
}
|
|
|
|
|
|
type Result<T, E = ParseError> = std::result::Result<T, E>;
|
|
|
-type ParseResult = Result<Vec<Statement>, (Vec<Statement>, Vec<ParseError>)>;
|
|
|
+type ParseResult<'a> = Result<Vec<Statement<'a>>, (Vec<Statement<'a>>, Vec<ParseError>)>;
|
|
|
|
|
|
static PROCEDURES: &[TokenKind] = &[
|
|
|
TokenKind::ProcedurePrint,
|
|
|
@@ -267,12 +267,12 @@ static PROCEDURES: &[TokenKind] = &[
|
|
|
TokenKind::ProcedureType,
|
|
|
];
|
|
|
|
|
|
-struct Parser {
|
|
|
+struct Parser<'a> {
|
|
|
current: usize,
|
|
|
- decorator_stack: Vec<Decorator>,
|
|
|
+ decorator_stack: Vec<Decorator<'a>>,
|
|
|
}
|
|
|
|
|
|
-impl Parser {
|
|
|
+impl<'a> Parser<'a> {
|
|
|
pub(crate) fn new() -> Self {
|
|
|
Parser {
|
|
|
current: 0,
|
|
|
@@ -280,7 +280,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn skip_empty_lines(&mut self, tokens: &[Token]) {
|
|
|
+ fn skip_empty_lines<'b>(&mut self, tokens: &'b [Token<'a>]) {
|
|
|
while self.match_exact(tokens, TokenKind::Newline).is_some() {}
|
|
|
}
|
|
|
|
|
|
@@ -289,7 +289,7 @@ impl Parser {
|
|
|
/// will try to recover from the error and parse as many statements as possible
|
|
|
/// while stacking all the errors in a `Vec`. At the end, it returns the complete
|
|
|
/// list of statements parsed + the list of errors accumulated.
|
|
|
- fn parse(&mut self, tokens: &[Token]) -> ParseResult {
|
|
|
+ fn parse(&mut self, tokens: &[Token<'a>]) -> ParseResult<'a> {
|
|
|
let mut statements = vec![];
|
|
|
let mut errors = vec![];
|
|
|
|
|
|
@@ -348,7 +348,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn accepts_prefix(&mut self, tokens: &[Token]) -> Result<Option<AcceptsPrefix>> {
|
|
|
+ fn accepts_prefix(&mut self, tokens: &[Token<'a>]) -> Result<Option<AcceptsPrefix>> {
|
|
|
if self.match_exact(tokens, TokenKind::Colon).is_some() {
|
|
|
if self.match_exact(tokens, TokenKind::Long).is_some() {
|
|
|
Ok(Some(AcceptsPrefix::only_long()))
|
|
|
@@ -371,16 +371,18 @@ impl Parser {
|
|
|
|
|
|
fn list_of_aliases(
|
|
|
&mut self,
|
|
|
- tokens: &[Token],
|
|
|
- ) -> Result<Vec<(String, Option<AcceptsPrefix>)>> {
|
|
|
+ tokens: &[Token<'a>],
|
|
|
+ ) -> Result<Vec<(&'a str, Option<AcceptsPrefix>, Span)>> {
|
|
|
if self.match_exact(tokens, TokenKind::RightParen).is_some() {
|
|
|
return Ok(vec![]);
|
|
|
}
|
|
|
|
|
|
- let mut identifiers: Vec<(String, Option<AcceptsPrefix>)> =
|
|
|
- vec![(self.identifier(tokens)?, self.accepts_prefix(tokens)?)];
|
|
|
+ let span = self.peek(tokens).span;
|
|
|
+ let mut identifiers = vec![(self.identifier(tokens)?, self.accepts_prefix(tokens)?, span)];
|
|
|
+
|
|
|
while self.match_exact(tokens, TokenKind::Comma).is_some() {
|
|
|
- identifiers.push((self.identifier(tokens)?, self.accepts_prefix(tokens)?));
|
|
|
+ let span = self.peek(tokens).span;
|
|
|
+ identifiers.push((self.identifier(tokens)?, self.accepts_prefix(tokens)?, span));
|
|
|
}
|
|
|
|
|
|
if self.match_exact(tokens, TokenKind::RightParen).is_none() {
|
|
|
@@ -393,7 +395,7 @@ impl Parser {
|
|
|
Ok(identifiers)
|
|
|
}
|
|
|
|
|
|
- fn statement(&mut self, tokens: &[Token]) -> Result<Statement> {
|
|
|
+ fn statement(&mut self, tokens: &[Token<'a>]) -> Result<Statement<'a>> {
|
|
|
if !(self.peek(tokens).kind == TokenKind::At
|
|
|
|| self.peek(tokens).kind == TokenKind::Unit
|
|
|
|| self.peek(tokens).kind == TokenKind::Let
|
|
|
@@ -430,9 +432,9 @@ impl Parser {
|
|
|
|
|
|
fn parse_variable(
|
|
|
&mut self,
|
|
|
- tokens: &[Token],
|
|
|
+ tokens: &[Token<'a>],
|
|
|
flush_decorators: bool,
|
|
|
- ) -> Result<DefineVariable> {
|
|
|
+ ) -> Result<DefineVariable<'a>> {
|
|
|
if let Some(identifier) = self.match_exact(tokens, TokenKind::Identifier) {
|
|
|
let identifier_span = self.last(tokens).unwrap().span;
|
|
|
|
|
|
@@ -472,7 +474,7 @@ impl Parser {
|
|
|
|
|
|
Ok(DefineVariable {
|
|
|
identifier_span,
|
|
|
- identifier: identifier.lexeme.to_owned(),
|
|
|
+ identifier: identifier.lexeme,
|
|
|
expr,
|
|
|
type_annotation,
|
|
|
decorators,
|
|
|
@@ -486,7 +488,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn parse_function_declaration(&mut self, tokens: &[Token]) -> Result<Statement> {
|
|
|
+ fn parse_function_declaration(&mut self, tokens: &[Token<'a>]) -> Result<Statement<'a>> {
|
|
|
if let Some(fn_name) = self.match_exact(tokens, TokenKind::Identifier) {
|
|
|
let function_name_span = self.last(tokens).unwrap().span;
|
|
|
let mut type_parameters = vec![];
|
|
|
@@ -520,7 +522,7 @@ impl Parser {
|
|
|
};
|
|
|
|
|
|
let span = self.last(tokens).unwrap().span;
|
|
|
- type_parameters.push((span, type_parameter_name.lexeme.to_string(), bound));
|
|
|
+ type_parameters.push((span, type_parameter_name.lexeme, bound));
|
|
|
|
|
|
if self.match_exact(tokens, TokenKind::Comma).is_none()
|
|
|
&& self.peek(tokens).kind != TokenKind::GreaterThan
|
|
|
@@ -559,7 +561,7 @@ impl Parser {
|
|
|
None
|
|
|
};
|
|
|
|
|
|
- parameters.push((span, param_name.lexeme.to_string(), param_type_dexpr));
|
|
|
+ parameters.push((span, param_name.lexeme, param_type_dexpr));
|
|
|
|
|
|
parameter_span = parameter_span.extend(&self.last(tokens).unwrap().span);
|
|
|
|
|
|
@@ -645,7 +647,7 @@ impl Parser {
|
|
|
|
|
|
Ok(Statement::DefineFunction {
|
|
|
function_name_span,
|
|
|
- function_name: fn_name.lexeme.to_owned(),
|
|
|
+ function_name: fn_name.lexeme,
|
|
|
type_parameters,
|
|
|
parameters,
|
|
|
body,
|
|
|
@@ -661,7 +663,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn parse_dimension_declaration(&mut self, tokens: &[Token]) -> Result<Statement> {
|
|
|
+ fn parse_dimension_declaration(&mut self, tokens: &[Token<'a>]) -> Result<Statement<'a>> {
|
|
|
if let Some(identifier) = self.match_exact(tokens, TokenKind::Identifier) {
|
|
|
if identifier.lexeme.starts_with("__") {
|
|
|
return Err(ParseError::new(
|
|
|
@@ -681,13 +683,13 @@ impl Parser {
|
|
|
|
|
|
Ok(Statement::DefineDimension(
|
|
|
identifier.span,
|
|
|
- identifier.lexeme.to_owned(),
|
|
|
+ identifier.lexeme,
|
|
|
dexprs,
|
|
|
))
|
|
|
} else {
|
|
|
Ok(Statement::DefineDimension(
|
|
|
identifier.span,
|
|
|
- identifier.lexeme.to_owned(),
|
|
|
+ identifier.lexeme,
|
|
|
vec![],
|
|
|
))
|
|
|
}
|
|
|
@@ -699,7 +701,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn parse_decorators(&mut self, tokens: &[Token]) -> Result<Statement> {
|
|
|
+ fn parse_decorators(&mut self, tokens: &[Token<'a>]) -> Result<Statement<'a>> {
|
|
|
if let Some(decorator) = self.match_exact(tokens, TokenKind::Identifier) {
|
|
|
let decorator = match decorator.lexeme {
|
|
|
"metric_prefixes" => Decorator::MetricPrefixes,
|
|
|
@@ -816,7 +818,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn parse_unit_declaration(&mut self, tokens: &[Token]) -> Result<Statement> {
|
|
|
+ fn parse_unit_declaration(&mut self, tokens: &[Token<'a>]) -> Result<Statement<'a>> {
|
|
|
if let Some(identifier) = self.match_exact(tokens, TokenKind::Identifier) {
|
|
|
let identifier_span = self.last(tokens).unwrap().span;
|
|
|
let (type_annotation_span, dexpr) =
|
|
|
@@ -827,7 +829,7 @@ impl Parser {
|
|
|
(None, None)
|
|
|
};
|
|
|
|
|
|
- let unit_name = identifier.lexeme.to_owned();
|
|
|
+ let unit_name = identifier.lexeme;
|
|
|
|
|
|
if decorator::contains_examples(&self.decorator_stack) {
|
|
|
return Err(ParseError {
|
|
|
@@ -878,7 +880,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn parse_use(&mut self, tokens: &[Token]) -> Result<Statement> {
|
|
|
+ fn parse_use(&mut self, tokens: &[Token<'a>]) -> Result<Statement<'a>> {
|
|
|
let mut span = self.peek(tokens).span;
|
|
|
|
|
|
if let Some(identifier) = self.match_exact(tokens, TokenKind::Identifier) {
|
|
|
@@ -905,7 +907,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn parse_struct(&mut self, tokens: &[Token]) -> Result<Statement> {
|
|
|
+ fn parse_struct(&mut self, tokens: &[Token<'a>]) -> Result<Statement<'a>> {
|
|
|
let name = self.identifier(tokens)?;
|
|
|
let name_span = self.last(tokens).unwrap().span;
|
|
|
|
|
|
@@ -954,7 +956,7 @@ impl Parser {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- fields.push((field_name.span, field_name.lexeme.to_owned(), attr_type));
|
|
|
+ fields.push((field_name.span, field_name.lexeme, attr_type));
|
|
|
}
|
|
|
|
|
|
Ok(Statement::DefineStruct {
|
|
|
@@ -964,7 +966,7 @@ impl Parser {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- fn parse_procedure(&mut self, tokens: &[Token]) -> Result<Statement> {
|
|
|
+ fn parse_procedure(&mut self, tokens: &[Token<'a>]) -> Result<Statement<'a>> {
|
|
|
let span = self.last(tokens).unwrap().span;
|
|
|
let procedure_kind = match self.last(tokens).unwrap().kind {
|
|
|
TokenKind::ProcedurePrint => ProcedureKind::Print,
|
|
|
@@ -994,11 +996,11 @@ impl Parser {
|
|
|
/// - arg `next` specifiy the next parser to call between each symbols
|
|
|
fn parse_binop(
|
|
|
&mut self,
|
|
|
- tokens: &[Token],
|
|
|
+ tokens: &[Token<'a>],
|
|
|
op_symbol: &[TokenKind],
|
|
|
op: impl Fn(TokenKind) -> BinaryOperator,
|
|
|
- next_parser: impl Fn(&mut Self) -> Result<Expression>,
|
|
|
- ) -> Result<Expression> {
|
|
|
+ next_parser: impl Fn(&mut Self) -> Result<Expression<'a>>,
|
|
|
+ ) -> Result<Expression<'a>> {
|
|
|
let mut expr = next_parser(self)?;
|
|
|
while let Some(matched) = self.match_any(tokens, op_symbol) {
|
|
|
let span_op = Some(self.last(tokens).unwrap().span);
|
|
|
@@ -1014,13 +1016,13 @@ impl Parser {
|
|
|
Ok(expr)
|
|
|
}
|
|
|
|
|
|
- pub fn expression(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ pub fn expression(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
self.postfix_apply(tokens)
|
|
|
}
|
|
|
|
|
|
- fn identifier(&mut self, tokens: &[Token]) -> Result<String> {
|
|
|
+ fn identifier(&mut self, tokens: &[Token<'a>]) -> Result<&'a str> {
|
|
|
if let Some(identifier) = self.match_exact(tokens, TokenKind::Identifier) {
|
|
|
- Ok(identifier.lexeme.to_owned())
|
|
|
+ Ok(identifier.lexeme)
|
|
|
} else {
|
|
|
Err(ParseError::new(
|
|
|
ParseErrorKind::ExpectedIdentifier,
|
|
|
@@ -1029,7 +1031,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pub fn postfix_apply(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ pub fn postfix_apply(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
let mut expr = self.condition(tokens)?;
|
|
|
let mut full_span = expr.full_span();
|
|
|
while self.match_exact(tokens, TokenKind::PostfixApply).is_some() {
|
|
|
@@ -1062,7 +1064,7 @@ impl Parser {
|
|
|
Ok(expr)
|
|
|
}
|
|
|
|
|
|
- fn condition(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn condition(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
if self.match_exact(tokens, TokenKind::If).is_some() {
|
|
|
let span_if = self.last(tokens).unwrap().span;
|
|
|
let condition_expr = self.conversion(tokens)?;
|
|
|
@@ -1104,7 +1106,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn conversion(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn conversion(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
self.parse_binop(
|
|
|
tokens,
|
|
|
&[TokenKind::Arrow, TokenKind::To],
|
|
|
@@ -1113,7 +1115,7 @@ impl Parser {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- fn logical_or(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn logical_or(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
self.parse_binop(
|
|
|
tokens,
|
|
|
&[TokenKind::LogicalOr],
|
|
|
@@ -1122,7 +1124,7 @@ impl Parser {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- fn logical_and(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn logical_and(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
self.parse_binop(
|
|
|
tokens,
|
|
|
&[TokenKind::LogicalAnd],
|
|
|
@@ -1131,7 +1133,7 @@ impl Parser {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- fn logical_neg(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn logical_neg(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
if self
|
|
|
.match_exact(tokens, TokenKind::ExclamationMark)
|
|
|
.is_some()
|
|
|
@@ -1149,7 +1151,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn comparison(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn comparison(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
self.parse_binop(
|
|
|
tokens,
|
|
|
&[
|
|
|
@@ -1173,7 +1175,7 @@ impl Parser {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- fn term(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn term(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
self.parse_binop(
|
|
|
tokens,
|
|
|
&[TokenKind::Plus, TokenKind::Minus],
|
|
|
@@ -1186,7 +1188,7 @@ impl Parser {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- fn factor(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn factor(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
self.parse_binop(
|
|
|
tokens,
|
|
|
&[TokenKind::Multiply, TokenKind::Divide],
|
|
|
@@ -1199,7 +1201,7 @@ impl Parser {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- fn per_factor(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn per_factor(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
self.parse_binop(
|
|
|
tokens,
|
|
|
&[TokenKind::Per],
|
|
|
@@ -1208,7 +1210,7 @@ impl Parser {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- fn unary(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn unary(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
if self.match_exact(tokens, TokenKind::Minus).is_some() {
|
|
|
let span = self.last(tokens).unwrap().span;
|
|
|
let rhs = self.unary(tokens)?;
|
|
|
@@ -1227,7 +1229,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn ifactor(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn ifactor(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
let mut expr = self.power(tokens)?;
|
|
|
|
|
|
while self.next_token_could_start_power_expression(tokens) {
|
|
|
@@ -1243,7 +1245,7 @@ impl Parser {
|
|
|
Ok(expr)
|
|
|
}
|
|
|
|
|
|
- fn power(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn power(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
let mut expr = self.factorial(tokens)?;
|
|
|
|
|
|
if self.match_exact(tokens, TokenKind::Power).is_some() {
|
|
|
@@ -1278,7 +1280,7 @@ impl Parser {
|
|
|
Ok(expr)
|
|
|
}
|
|
|
|
|
|
- fn factorial(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn factorial(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
let mut expr = self.unicode_power(tokens)?;
|
|
|
|
|
|
while self
|
|
|
@@ -1323,7 +1325,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn unicode_power(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn unicode_power(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
let mut expr = self.call(tokens)?;
|
|
|
|
|
|
if let Some(exponent) = self.match_exact(tokens, TokenKind::UnicodeExponent) {
|
|
|
@@ -1343,7 +1345,7 @@ impl Parser {
|
|
|
Ok(expr)
|
|
|
}
|
|
|
|
|
|
- fn call(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn call(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
let mut expr = self.primary(tokens)?;
|
|
|
|
|
|
loop {
|
|
|
@@ -1367,13 +1369,13 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn arguments(&mut self, tokens: &[Token]) -> Result<Vec<Expression>> {
|
|
|
+ fn arguments(&mut self, tokens: &[Token<'a>]) -> Result<Vec<Expression<'a>>> {
|
|
|
self.skip_empty_lines(tokens);
|
|
|
if self.match_exact(tokens, TokenKind::RightParen).is_some() {
|
|
|
return Ok(vec![]);
|
|
|
}
|
|
|
|
|
|
- let mut args: Vec<Expression> = vec![self.expression(tokens)?];
|
|
|
+ let mut args = vec![self.expression(tokens)?];
|
|
|
loop {
|
|
|
self.skip_empty_lines(tokens);
|
|
|
|
|
|
@@ -1404,7 +1406,7 @@ impl Parser {
|
|
|
Ok(args)
|
|
|
}
|
|
|
|
|
|
- fn primary(&mut self, tokens: &[Token]) -> Result<Expression> {
|
|
|
+ fn primary(&mut self, tokens: &[Token<'a>]) -> Result<Expression<'a>> {
|
|
|
// This function needs to be kept in sync with `next_token_could_start_power_expression` below.
|
|
|
|
|
|
let overflow_error = |span| {
|
|
|
@@ -1525,7 +1527,7 @@ impl Parser {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- fields.push((field_name.span, field_name.lexeme.to_owned(), expr));
|
|
|
+ fields.push((field_name.span, field_name.lexeme, expr));
|
|
|
}
|
|
|
|
|
|
let full_span = span.extend(&self.last(tokens).unwrap().span);
|
|
|
@@ -1533,12 +1535,12 @@ impl Parser {
|
|
|
return Ok(Expression::InstantiateStruct {
|
|
|
full_span,
|
|
|
ident_span: span,
|
|
|
- name: identifier.lexeme.to_owned(),
|
|
|
+ name: identifier.lexeme,
|
|
|
fields,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- Ok(Expression::Identifier(span, identifier.lexeme.to_owned()))
|
|
|
+ Ok(Expression::Identifier(span, identifier.lexeme))
|
|
|
} else if let Some(inner) = self.match_any(tokens, &[TokenKind::True, TokenKind::False]) {
|
|
|
Ok(Expression::Boolean(
|
|
|
inner.span,
|
|
|
@@ -1636,9 +1638,9 @@ impl Parser {
|
|
|
|
|
|
fn interpolation(
|
|
|
&mut self,
|
|
|
- tokens: &[Token],
|
|
|
- parts: &mut Vec<StringPart>,
|
|
|
- token: &Token,
|
|
|
+ tokens: &[Token<'a>],
|
|
|
+ parts: &mut Vec<StringPart<'a>>,
|
|
|
+ token: &Token<'a>,
|
|
|
) -> Result<()> {
|
|
|
parts.push(StringPart::Fixed(strip_and_escape(token.lexeme)));
|
|
|
|
|
|
@@ -1646,7 +1648,7 @@ impl Parser {
|
|
|
|
|
|
let format_specifiers = self
|
|
|
.match_exact(tokens, TokenKind::StringInterpolationSpecifiers)
|
|
|
- .map(|token| token.lexeme.to_owned());
|
|
|
+ .map(|token| token.lexeme);
|
|
|
|
|
|
parts.push(StringPart::Interpolation {
|
|
|
span: expr.full_span(),
|
|
|
@@ -1671,7 +1673,7 @@ impl Parser {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- fn type_annotation(&mut self, tokens: &[Token]) -> Result<TypeAnnotation> {
|
|
|
+ fn type_annotation(&mut self, tokens: &[Token<'a>]) -> Result<TypeAnnotation> {
|
|
|
if let Some(token) = self.match_exact(tokens, TokenKind::Bool) {
|
|
|
Ok(TypeAnnotation::Bool(token.span))
|
|
|
} else if let Some(token) = self.match_exact(tokens, TokenKind::String) {
|
|
|
@@ -1756,11 +1758,11 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn dimension_expression(&mut self, tokens: &[Token]) -> Result<TypeExpression> {
|
|
|
+ fn dimension_expression(&mut self, tokens: &[Token<'a>]) -> Result<TypeExpression> {
|
|
|
self.dimension_factor(tokens)
|
|
|
}
|
|
|
|
|
|
- fn dimension_factor(&mut self, tokens: &[Token]) -> Result<TypeExpression> {
|
|
|
+ fn dimension_factor(&mut self, tokens: &[Token<'a>]) -> Result<TypeExpression> {
|
|
|
let mut expr = self.dimension_power(tokens)?;
|
|
|
while let Some(operator_token) =
|
|
|
self.match_any(tokens, &[TokenKind::Multiply, TokenKind::Divide])
|
|
|
@@ -1777,7 +1779,7 @@ impl Parser {
|
|
|
Ok(expr)
|
|
|
}
|
|
|
|
|
|
- fn dimension_power(&mut self, tokens: &[Token]) -> Result<TypeExpression> {
|
|
|
+ fn dimension_power(&mut self, tokens: &[Token<'a>]) -> Result<TypeExpression> {
|
|
|
let expr = self.dimension_primary(tokens)?;
|
|
|
|
|
|
if self.match_exact(tokens, TokenKind::Power).is_some() {
|
|
|
@@ -1805,7 +1807,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn dimension_exponent(&mut self, tokens: &[Token]) -> Result<(Span, Exponent)> {
|
|
|
+ fn dimension_exponent(&mut self, tokens: &[Token<'a>]) -> Result<(Span, Exponent)> {
|
|
|
if let Some(token) = self.match_exact(tokens, TokenKind::Number) {
|
|
|
let span = self.last(tokens).unwrap().span;
|
|
|
let num_str = token.lexeme.replace('_', "");
|
|
|
@@ -1867,7 +1869,7 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn dimension_primary(&mut self, tokens: &[Token]) -> Result<TypeExpression> {
|
|
|
+ fn dimension_primary(&mut self, tokens: &[Token<'a>]) -> Result<TypeExpression> {
|
|
|
let e = Err(ParseError::new(
|
|
|
ParseErrorKind::ExpectedDimensionPrimary,
|
|
|
self.peek(tokens).span,
|
|
|
@@ -1905,11 +1907,11 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn match_exact<'a>(
|
|
|
+ fn match_exact<'b>(
|
|
|
&mut self,
|
|
|
- tokens: &'a [Token<'a>],
|
|
|
+ tokens: &'b [Token<'a>],
|
|
|
token_kind: TokenKind,
|
|
|
- ) -> Option<&'a Token<'a>> {
|
|
|
+ ) -> Option<&'b Token<'a>> {
|
|
|
let token = self.peek(tokens);
|
|
|
if token.kind == token_kind {
|
|
|
self.advance(tokens);
|
|
|
@@ -1932,22 +1934,22 @@ impl Parser {
|
|
|
|
|
|
/// Same as 'match_exact', but skips empty lines before matching. Note that this
|
|
|
/// does *not* skip empty lines in case there is no match.
|
|
|
- fn match_exact_beyond_linebreaks<'a>(
|
|
|
+ fn match_exact_beyond_linebreaks<'b>(
|
|
|
&mut self,
|
|
|
- tokens: &'a [Token<'a>],
|
|
|
+ tokens: &'b [Token<'a>],
|
|
|
token_kind: TokenKind,
|
|
|
- ) -> Option<&'a Token<'a>> {
|
|
|
+ ) -> Option<&'b Token<'a>> {
|
|
|
if self.look_ahead_beyond_linebreak(tokens, token_kind) {
|
|
|
self.skip_empty_lines(tokens);
|
|
|
}
|
|
|
self.match_exact(tokens, token_kind)
|
|
|
}
|
|
|
|
|
|
- fn match_any<'a>(
|
|
|
+ fn match_any<'b>(
|
|
|
&mut self,
|
|
|
- tokens: &'a [Token<'a>],
|
|
|
+ tokens: &'b [Token<'a>],
|
|
|
kinds: &[TokenKind],
|
|
|
- ) -> Option<&'a Token<'a>> {
|
|
|
+ ) -> Option<&'b Token<'a>> {
|
|
|
for kind in kinds {
|
|
|
if let result @ Some(..) = self.match_exact(tokens, *kind) {
|
|
|
return result;
|
|
|
@@ -1962,11 +1964,11 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn peek<'a>(&self, tokens: &'a [Token<'a>]) -> &'a Token<'a> {
|
|
|
+ fn peek<'b>(&self, tokens: &'b [Token<'a>]) -> &'b Token<'a> {
|
|
|
&tokens[self.current]
|
|
|
}
|
|
|
|
|
|
- fn last<'a>(&self, tokens: &'a [Token<'a>]) -> Option<&'a Token<'a>> {
|
|
|
+ fn last<'b>(&self, tokens: &'b [Token<'a>]) -> Option<&'b Token<'a>> {
|
|
|
if self.current == 0 {
|
|
|
None
|
|
|
} else {
|
|
|
@@ -2024,7 +2026,7 @@ fn strip_and_escape(s: &str) -> String {
|
|
|
/// will try to recover from the error and parse as many statements as possible
|
|
|
/// while stacking all the errors in a `Vec`. At the end, it returns the complete
|
|
|
/// list of statements parsed + the list of errors accumulated.
|
|
|
-pub fn parse(input: &str, code_source_id: usize) -> ParseResult {
|
|
|
+pub fn parse(input: &str, code_source_id: usize) -> ParseResult<'_> {
|
|
|
use crate::tokenizer::tokenize;
|
|
|
|
|
|
let tokens = tokenize(input, code_source_id)
|
|
|
@@ -2032,8 +2034,10 @@ pub fn parse(input: &str, code_source_id: usize) -> ParseResult {
|
|
|
ParseError::new(ParseErrorKind::TokenizerError(kind), span)
|
|
|
})
|
|
|
.map_err(|e| (Vec::new(), vec![e]))?;
|
|
|
+ let tokens = &tokens;
|
|
|
+
|
|
|
let mut parser = Parser::new();
|
|
|
- parser.parse(&tokens)
|
|
|
+ parser.parse(tokens)
|
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
|
@@ -2053,9 +2057,12 @@ mod tests {
|
|
|
use std::fmt::Write;
|
|
|
|
|
|
use super::*;
|
|
|
- use crate::ast::{
|
|
|
- binop, boolean, conditional, factorial, identifier, list, logical_neg, negate, scalar,
|
|
|
- struct_, ReplaceSpans,
|
|
|
+ use crate::{
|
|
|
+ ast::{
|
|
|
+ binop, boolean, conditional, factorial, identifier, list, logical_neg, negate, scalar,
|
|
|
+ struct_, ReplaceSpans,
|
|
|
+ },
|
|
|
+ span::ByteIndex,
|
|
|
};
|
|
|
|
|
|
#[track_caller]
|
|
|
@@ -2472,7 +2479,7 @@ mod tests {
|
|
|
&["let foo = 1", "let foo=1"],
|
|
|
Statement::DefineVariable(DefineVariable {
|
|
|
identifier_span: Span::dummy(),
|
|
|
- identifier: "foo".into(),
|
|
|
+ identifier: "foo",
|
|
|
expr: scalar!(1.0),
|
|
|
type_annotation: None,
|
|
|
decorators: Vec::new(),
|
|
|
@@ -2483,7 +2490,7 @@ mod tests {
|
|
|
&["let x: Length = 1 * meter"],
|
|
|
Statement::DefineVariable(DefineVariable {
|
|
|
identifier_span: Span::dummy(),
|
|
|
- identifier: "x".into(),
|
|
|
+ identifier: "x",
|
|
|
expr: binop!(scalar!(1.0), Mul, identifier!("meter")),
|
|
|
type_annotation: Some(TypeAnnotation::TypeExpression(
|
|
|
TypeExpression::TypeIdentifier(Span::dummy(), "Length".into()),
|
|
|
@@ -2497,14 +2504,33 @@ mod tests {
|
|
|
&["@name(\"myvar\") @aliases(foo, bar) let x: Length = 1 * meter"],
|
|
|
Statement::DefineVariable(DefineVariable {
|
|
|
identifier_span: Span::dummy(),
|
|
|
- identifier: "x".into(),
|
|
|
+ identifier: "x",
|
|
|
expr: binop!(scalar!(1.0), Mul, identifier!("meter")),
|
|
|
type_annotation: Some(TypeAnnotation::TypeExpression(
|
|
|
TypeExpression::TypeIdentifier(Span::dummy(), "Length".into()),
|
|
|
)),
|
|
|
decorators: vec![
|
|
|
decorator::Decorator::Name("myvar".into()),
|
|
|
- decorator::Decorator::Aliases(vec![("foo".into(), None), ("bar".into(), None)]),
|
|
|
+ decorator::Decorator::Aliases(vec![
|
|
|
+ (
|
|
|
+ "foo",
|
|
|
+ None,
|
|
|
+ Span {
|
|
|
+ start: ByteIndex(24),
|
|
|
+ end: ByteIndex(27),
|
|
|
+ code_source_id: 0,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ (
|
|
|
+ "bar",
|
|
|
+ None,
|
|
|
+ Span {
|
|
|
+ start: ByteIndex(29),
|
|
|
+ end: ByteIndex(32),
|
|
|
+ code_source_id: 0,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ]),
|
|
|
],
|
|
|
}),
|
|
|
);
|
|
|
@@ -2536,7 +2562,7 @@ mod tests {
|
|
|
fn dimension_definition() {
|
|
|
parse_as(
|
|
|
&["dimension px"],
|
|
|
- Statement::DefineDimension(Span::dummy(), "px".into(), vec![]),
|
|
|
+ Statement::DefineDimension(Span::dummy(), "px", vec![]),
|
|
|
);
|
|
|
|
|
|
parse_as(
|
|
|
@@ -2547,7 +2573,7 @@ mod tests {
|
|
|
],
|
|
|
Statement::DefineDimension(
|
|
|
Span::dummy(),
|
|
|
- "Area".into(),
|
|
|
+ "Area",
|
|
|
vec![TypeExpression::Multiply(
|
|
|
Span::dummy(),
|
|
|
Box::new(TypeExpression::TypeIdentifier(
|
|
|
@@ -2566,7 +2592,7 @@ mod tests {
|
|
|
&["dimension Velocity = Length / Time"],
|
|
|
Statement::DefineDimension(
|
|
|
Span::dummy(),
|
|
|
- "Velocity".into(),
|
|
|
+ "Velocity",
|
|
|
vec![TypeExpression::Divide(
|
|
|
Span::dummy(),
|
|
|
Box::new(TypeExpression::TypeIdentifier(
|
|
|
@@ -2582,7 +2608,7 @@ mod tests {
|
|
|
&["dimension Area = Length^2"],
|
|
|
Statement::DefineDimension(
|
|
|
Span::dummy(),
|
|
|
- "Area".into(),
|
|
|
+ "Area",
|
|
|
vec![TypeExpression::Power(
|
|
|
Some(Span::dummy()),
|
|
|
Box::new(TypeExpression::TypeIdentifier(
|
|
|
@@ -2599,7 +2625,7 @@ mod tests {
|
|
|
&["dimension Energy = Mass * Length^2 / Time^2"],
|
|
|
Statement::DefineDimension(
|
|
|
Span::dummy(),
|
|
|
- "Energy".into(),
|
|
|
+ "Energy",
|
|
|
vec![TypeExpression::Divide(
|
|
|
Span::dummy(),
|
|
|
Box::new(TypeExpression::Multiply(
|
|
|
@@ -2629,7 +2655,7 @@ mod tests {
|
|
|
&["dimension X = Length^(12345/67890)"],
|
|
|
Statement::DefineDimension(
|
|
|
Span::dummy(),
|
|
|
- "X".into(),
|
|
|
+ "X",
|
|
|
vec![TypeExpression::Power(
|
|
|
Some(Span::dummy()),
|
|
|
Box::new(TypeExpression::TypeIdentifier(
|
|
|
@@ -2655,7 +2681,7 @@ mod tests {
|
|
|
&["fn foo() = 1", "fn foo() =\n 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
+ function_name: "foo",
|
|
|
type_parameters: vec![],
|
|
|
parameters: vec![],
|
|
|
body: Some(scalar!(1.0)),
|
|
|
@@ -2669,7 +2695,7 @@ mod tests {
|
|
|
&["fn foo() -> Scalar = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
+ function_name: "foo",
|
|
|
type_parameters: vec![],
|
|
|
parameters: vec![],
|
|
|
body: Some(scalar!(1.0)),
|
|
|
@@ -2685,9 +2711,9 @@ mod tests {
|
|
|
&["fn foo(x) = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
+ function_name: "foo",
|
|
|
type_parameters: vec![],
|
|
|
- parameters: vec![(Span::dummy(), "x".into(), None)],
|
|
|
+ parameters: vec![(Span::dummy(), "x", None)],
|
|
|
body: Some(scalar!(1.0)),
|
|
|
local_variables: vec![],
|
|
|
return_type_annotation: None,
|
|
|
@@ -2699,9 +2725,9 @@ mod tests {
|
|
|
&["fn foo(x,) = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
+ function_name: "foo",
|
|
|
type_parameters: vec![],
|
|
|
- parameters: vec![(Span::dummy(), "x".into(), None)],
|
|
|
+ parameters: vec![(Span::dummy(), "x", None)],
|
|
|
body: Some(scalar!(1.0)),
|
|
|
local_variables: vec![],
|
|
|
return_type_annotation: None,
|
|
|
@@ -2716,12 +2742,9 @@ mod tests {
|
|
|
) = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
+ function_name: "foo",
|
|
|
type_parameters: vec![],
|
|
|
- parameters: vec![
|
|
|
- (Span::dummy(), "x".into(), None),
|
|
|
- (Span::dummy(), "y".into(), None),
|
|
|
- ],
|
|
|
+ parameters: vec![(Span::dummy(), "x", None), (Span::dummy(), "y", None)],
|
|
|
body: Some(scalar!(1.0)),
|
|
|
local_variables: vec![],
|
|
|
return_type_annotation: None,
|
|
|
@@ -2733,12 +2756,12 @@ mod tests {
|
|
|
&["fn foo(x, y, z) = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
+ function_name: "foo",
|
|
|
type_parameters: vec![],
|
|
|
parameters: vec![
|
|
|
- (Span::dummy(), "x".into(), None),
|
|
|
- (Span::dummy(), "y".into(), None),
|
|
|
- (Span::dummy(), "z".into(), None),
|
|
|
+ (Span::dummy(), "x", None),
|
|
|
+ (Span::dummy(), "y", None),
|
|
|
+ (Span::dummy(), "z", None),
|
|
|
],
|
|
|
body: Some(scalar!(1.0)),
|
|
|
local_variables: vec![],
|
|
|
@@ -2751,26 +2774,26 @@ mod tests {
|
|
|
&["fn foo(x: Length, y: Time, z: Length^3 · Time^2) -> Scalar = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
+ function_name: "foo",
|
|
|
type_parameters: vec![],
|
|
|
parameters: vec![
|
|
|
(
|
|
|
Span::dummy(),
|
|
|
- "x".into(),
|
|
|
+ "x",
|
|
|
Some(TypeAnnotation::TypeExpression(
|
|
|
TypeExpression::TypeIdentifier(Span::dummy(), "Length".into()),
|
|
|
)),
|
|
|
),
|
|
|
(
|
|
|
Span::dummy(),
|
|
|
- "y".into(),
|
|
|
+ "y",
|
|
|
Some(TypeAnnotation::TypeExpression(
|
|
|
TypeExpression::TypeIdentifier(Span::dummy(), "Time".into()),
|
|
|
)),
|
|
|
),
|
|
|
(
|
|
|
Span::dummy(),
|
|
|
- "z".into(),
|
|
|
+ "z",
|
|
|
Some(TypeAnnotation::TypeExpression(TypeExpression::Multiply(
|
|
|
Span::dummy(),
|
|
|
Box::new(TypeExpression::Power(
|
|
|
@@ -2807,11 +2830,11 @@ mod tests {
|
|
|
&["fn foo<X>(x: X) = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
- type_parameters: vec![(Span::dummy(), "X".into(), None)],
|
|
|
+ function_name: "foo",
|
|
|
+ type_parameters: vec![(Span::dummy(), "X", None)],
|
|
|
parameters: vec![(
|
|
|
Span::dummy(),
|
|
|
- "x".into(),
|
|
|
+ "x",
|
|
|
Some(TypeAnnotation::TypeExpression(
|
|
|
TypeExpression::TypeIdentifier(Span::dummy(), "X".into()),
|
|
|
)),
|
|
|
@@ -2827,11 +2850,11 @@ mod tests {
|
|
|
&["fn foo<X: Dim>(x: X) = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "foo".into(),
|
|
|
- type_parameters: vec![(Span::dummy(), "X".into(), Some(TypeParameterBound::Dim))],
|
|
|
+ function_name: "foo",
|
|
|
+ type_parameters: vec![(Span::dummy(), "X", Some(TypeParameterBound::Dim))],
|
|
|
parameters: vec![(
|
|
|
Span::dummy(),
|
|
|
- "x".into(),
|
|
|
+ "x",
|
|
|
Some(TypeAnnotation::TypeExpression(
|
|
|
TypeExpression::TypeIdentifier(Span::dummy(), "X".into()),
|
|
|
)),
|
|
|
@@ -2847,9 +2870,9 @@ mod tests {
|
|
|
&["@name(\"Some function\") @description(\"This is a description of some_function.\") fn some_function(x) = 1"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "some_function".into(),
|
|
|
+ function_name: "some_function",
|
|
|
type_parameters: vec![],
|
|
|
- parameters: vec![(Span::dummy(), "x".into(), None)],
|
|
|
+ parameters: vec![(Span::dummy(), "x", None)],
|
|
|
body: Some(scalar!(1.0)),
|
|
|
local_variables: vec![],
|
|
|
return_type_annotation: None,
|
|
|
@@ -2884,13 +2907,13 @@ mod tests {
|
|
|
&["fn double_kef(x) = y where y = x * 2"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "double_kef".into(),
|
|
|
+ function_name: "double_kef",
|
|
|
type_parameters: vec![],
|
|
|
- parameters: vec![(Span::dummy(), "x".into(), None)],
|
|
|
+ parameters: vec![(Span::dummy(), "x", None)],
|
|
|
body: Some(identifier!("y")),
|
|
|
local_variables: vec![DefineVariable {
|
|
|
identifier_span: Span::dummy(),
|
|
|
- identifier: String::from("y"),
|
|
|
+ identifier: "y",
|
|
|
expr: binop!(identifier!("x"), Mul, scalar!(2.0)),
|
|
|
type_annotation: None,
|
|
|
decorators: vec![],
|
|
|
@@ -2906,21 +2929,21 @@ mod tests {
|
|
|
and z = y + x"],
|
|
|
Statement::DefineFunction {
|
|
|
function_name_span: Span::dummy(),
|
|
|
- function_name: "kefirausaure".into(),
|
|
|
+ function_name: "kefirausaure",
|
|
|
type_parameters: vec![],
|
|
|
- parameters: vec![(Span::dummy(), "x".into(), None)],
|
|
|
+ parameters: vec![(Span::dummy(), "x", None)],
|
|
|
body: Some(binop!(identifier!("z"), Add, identifier!("y"))),
|
|
|
local_variables: vec![
|
|
|
DefineVariable {
|
|
|
identifier_span: Span::dummy(),
|
|
|
- identifier: String::from("y"),
|
|
|
+ identifier: "y",
|
|
|
expr: binop!(identifier!("x"), Add, identifier!("x")),
|
|
|
type_annotation: None,
|
|
|
decorators: vec![],
|
|
|
},
|
|
|
DefineVariable {
|
|
|
identifier_span: Span::dummy(),
|
|
|
- identifier: String::from("z"),
|
|
|
+ identifier: "z",
|
|
|
expr: binop!(identifier!("y"), Add, identifier!("x")),
|
|
|
type_annotation: None,
|
|
|
decorators: vec![],
|
|
|
@@ -3366,7 +3389,7 @@ mod tests {
|
|
|
StringPart::Interpolation {
|
|
|
span: Span::dummy(),
|
|
|
expr: Box::new(binop!(scalar!(1.0), Add, scalar!(2.0))),
|
|
|
- format_specifiers: Some(":0.2".to_string()),
|
|
|
+ format_specifiers: Some(":0.2"),
|
|
|
},
|
|
|
],
|
|
|
),
|
|
|
@@ -3389,11 +3412,11 @@ mod tests {
|
|
|
&["struct Foo { foo: Scalar, bar: Scalar }"],
|
|
|
Statement::DefineStruct {
|
|
|
struct_name_span: Span::dummy(),
|
|
|
- struct_name: "Foo".to_owned(),
|
|
|
+ struct_name: "Foo",
|
|
|
fields: vec![
|
|
|
(
|
|
|
Span::dummy(),
|
|
|
- "foo".to_owned(),
|
|
|
+ "foo",
|
|
|
TypeAnnotation::TypeExpression(TypeExpression::TypeIdentifier(
|
|
|
Span::dummy(),
|
|
|
"Scalar".to_owned(),
|
|
|
@@ -3401,7 +3424,7 @@ mod tests {
|
|
|
),
|
|
|
(
|
|
|
Span::dummy(),
|
|
|
- "bar".to_owned(),
|
|
|
+ "bar",
|
|
|
TypeAnnotation::TypeExpression(TypeExpression::TypeIdentifier(
|
|
|
Span::dummy(),
|
|
|
"Scalar".to_owned(),
|
|
|
@@ -3430,7 +3453,7 @@ mod tests {
|
|
|
foo: scalar!(1.0),
|
|
|
bar: scalar!(2.0)
|
|
|
}),
|
|
|
- "foo".to_owned(),
|
|
|
+ "foo",
|
|
|
),
|
|
|
);
|
|
|
}
|