|
@@ -64,19 +64,19 @@ pub enum ParseErrorKind {
|
|
#[error("Expected identifier after 'let' keyword")]
|
|
#[error("Expected identifier after 'let' keyword")]
|
|
ExpectedIdentifierAfterLet,
|
|
ExpectedIdentifierAfterLet,
|
|
|
|
|
|
- #[error("Expected '=' or ':' after identifier in 'let' assignment")]
|
|
|
|
|
|
+ #[error("Expected '=' or ':' after identifier (and type annotation) in 'let' assignment")]
|
|
ExpectedEqualOrColonAfterLetIdentifier,
|
|
ExpectedEqualOrColonAfterLetIdentifier,
|
|
|
|
|
|
#[error("Expected identifier after 'fn' keyword. Note that some reserved words can not be used as function names.")]
|
|
#[error("Expected identifier after 'fn' keyword. Note that some reserved words can not be used as function names.")]
|
|
ExpectedIdentifierAfterFn,
|
|
ExpectedIdentifierAfterFn,
|
|
|
|
|
|
- #[error("Expected function name after '//' operator")]
|
|
|
|
|
|
+ #[error("Expected function name after '//' postfix apply operator")]
|
|
ExpectedIdentifierInPostfixApply,
|
|
ExpectedIdentifierInPostfixApply,
|
|
|
|
|
|
#[error("Expected dimension identifier, '1', or opening parenthesis")]
|
|
#[error("Expected dimension identifier, '1', or opening parenthesis")]
|
|
ExpectedDimensionPrimary,
|
|
ExpectedDimensionPrimary,
|
|
|
|
|
|
- #[error("Expected ',' or '>'")]
|
|
|
|
|
|
+ #[error("Expected ',' or '>' in type parameter list")]
|
|
ExpectedCommaOrRightAngleBracket,
|
|
ExpectedCommaOrRightAngleBracket,
|
|
|
|
|
|
#[error("Expected identifier (type parameter name)")]
|
|
#[error("Expected identifier (type parameter name)")]
|
|
@@ -94,7 +94,7 @@ pub enum ParseErrorKind {
|
|
#[error("Only a single variadic parameter is allowed in a function definition")]
|
|
#[error("Only a single variadic parameter is allowed in a function definition")]
|
|
OnlySingleVariadicParameter,
|
|
OnlySingleVariadicParameter,
|
|
|
|
|
|
- #[error("Variadic parameters are only allowed in foreign functions")]
|
|
|
|
|
|
+ #[error("Variadic parameters are only allowed in foreign functions (without body)")]
|
|
VariadicParameterOnlyAllowedInForeignFunction,
|
|
VariadicParameterOnlyAllowedInForeignFunction,
|
|
|
|
|
|
#[error("Expected identifier (dimension name)")]
|
|
#[error("Expected identifier (dimension name)")]
|
|
@@ -292,6 +292,8 @@ impl<'a> Parser<'a> {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ let mut parameter_span = self.peek().span.clone();
|
|
|
|
+
|
|
let mut parameters = vec![];
|
|
let mut parameters = vec![];
|
|
while self.match_exact(TokenKind::RightParen).is_none() {
|
|
while self.match_exact(TokenKind::RightParen).is_none() {
|
|
if let Some(param_name) = self.match_exact(TokenKind::Identifier) {
|
|
if let Some(param_name) = self.match_exact(TokenKind::Identifier) {
|
|
@@ -309,6 +311,8 @@ impl<'a> Parser<'a> {
|
|
is_variadic,
|
|
is_variadic,
|
|
));
|
|
));
|
|
|
|
|
|
|
|
+ parameter_span = parameter_span.extend(&self.last().unwrap().span);
|
|
|
|
+
|
|
if self.match_exact(TokenKind::Comma).is_none()
|
|
if self.match_exact(TokenKind::Comma).is_none()
|
|
&& self.peek().kind != TokenKind::RightParen
|
|
&& self.peek().kind != TokenKind::RightParen
|
|
{
|
|
{
|
|
@@ -325,14 +329,6 @@ impl<'a> Parser<'a> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- let fn_is_variadic = parameters.iter().any(|p| p.2);
|
|
|
|
- if fn_is_variadic && parameters.len() > 1 {
|
|
|
|
- return Err(ParseError {
|
|
|
|
- kind: ParseErrorKind::OnlySingleVariadicParameter,
|
|
|
|
- span: self.peek().span.clone(),
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
let optional_return_type_dexpr = if self.match_exact(TokenKind::Arrow).is_some() {
|
|
let optional_return_type_dexpr = if self.match_exact(TokenKind::Arrow).is_some() {
|
|
// Parse return type
|
|
// Parse return type
|
|
Some(self.dimension_expression()?)
|
|
Some(self.dimension_expression()?)
|
|
@@ -340,6 +336,14 @@ impl<'a> Parser<'a> {
|
|
None
|
|
None
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ let fn_is_variadic = parameters.iter().any(|p| p.2);
|
|
|
|
+ if fn_is_variadic && parameters.len() > 1 {
|
|
|
|
+ return Err(ParseError {
|
|
|
|
+ kind: ParseErrorKind::OnlySingleVariadicParameter,
|
|
|
|
+ span: parameter_span,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
let body = if self.match_exact(TokenKind::Equal).is_none() {
|
|
let body = if self.match_exact(TokenKind::Equal).is_none() {
|
|
None
|
|
None
|
|
} else {
|
|
} else {
|
|
@@ -349,7 +353,7 @@ impl<'a> Parser<'a> {
|
|
if fn_is_variadic && body.is_some() {
|
|
if fn_is_variadic && body.is_some() {
|
|
return Err(ParseError {
|
|
return Err(ParseError {
|
|
kind: ParseErrorKind::VariadicParameterOnlyAllowedInForeignFunction,
|
|
kind: ParseErrorKind::VariadicParameterOnlyAllowedInForeignFunction,
|
|
- span: self.peek().span.clone(),
|
|
|
|
|
|
+ span: parameter_span,
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -496,7 +500,7 @@ impl<'a> Parser<'a> {
|
|
} else {
|
|
} else {
|
|
Err(ParseError::new(
|
|
Err(ParseError::new(
|
|
ParseErrorKind::CanOnlyCallIdentifier,
|
|
ParseErrorKind::CanOnlyCallIdentifier,
|
|
- self.peek().span.clone(),
|
|
|
|
|
|
+ self.peek().span.clone(), // TODO: Ideally, this span should point to whatever we try to call. Once we have spans in the AST, this should be easy to resolve.
|
|
))
|
|
))
|
|
}
|
|
}
|
|
}
|
|
}
|