|
|
@ -90,25 +90,34 @@ impl Parser { |
|
|
|
|
|
|
|
|
|
|
|
fn parse_arguments(&mut self) -> Result<Vec<Variable>, String> { |
|
|
|
fn parse_arguments(&mut self) -> Result<Vec<Variable>, String> { |
|
|
|
let mut args = Vec::new(); |
|
|
|
let mut args = Vec::new(); |
|
|
|
while self.peek_token(TokenKind::BraceClose).is_err() { |
|
|
|
|
|
|
|
let next = self.next()?; |
|
|
|
// If there is an argument
|
|
|
|
match next.kind { |
|
|
|
if let TokenKind::Identifier(_) = self.peek()?.kind { |
|
|
|
TokenKind::Comma => { |
|
|
|
// Parse first argument
|
|
|
|
continue; |
|
|
|
args.push(self.parse_typed_argument_list()?); |
|
|
|
} |
|
|
|
// Then continue to parse arguments
|
|
|
|
TokenKind::Identifier(name) => { |
|
|
|
// as long as a comma token is found
|
|
|
|
args.push(Variable { |
|
|
|
while self.peek_token(TokenKind::Comma).is_ok() { |
|
|
|
name, |
|
|
|
self.match_token(TokenKind::Comma)?; |
|
|
|
ty: Some(self.parse_type()?), |
|
|
|
args.push(self.parse_typed_argument_list()?); |
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_ => return Err(self.make_error(TokenKind::Identifier("Argument".into()), next)), |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Ok(args) |
|
|
|
Ok(args) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_typed_argument_list(&mut self) -> Result<Variable, String> { |
|
|
|
|
|
|
|
let next = self.next()?; |
|
|
|
|
|
|
|
if let TokenKind::Identifier(name) = next.kind { |
|
|
|
|
|
|
|
return Ok(Variable { |
|
|
|
|
|
|
|
name, |
|
|
|
|
|
|
|
ty: Some(self.parse_type()?), |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Err(format!("Argument could not be parsed: {}", next.raw)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn parse_type(&mut self) -> Result<Type, String> { |
|
|
|
fn parse_type(&mut self) -> Result<Type, String> { |
|
|
|
self.match_token(TokenKind::Colon)?; |
|
|
|
self.match_token(TokenKind::Colon)?; |
|
|
|
let next = self.peek()?; |
|
|
|
let next = self.peek()?; |
|
|
|