diff --git a/compiler/parser/src/parser/expression.rs b/compiler/parser/src/parser/expression.rs index aaaffdf472..07c156eb5a 100644 --- a/compiler/parser/src/parser/expression.rs +++ b/compiler/parser/src/parser/expression.rs @@ -429,28 +429,39 @@ impl ParserContext<'_> { self.parse_paren_comma_list(|p| p.parse_expression().map(Some)) } - // Parses an external function call `credits.aleo/transfer()` or `board.leo/make_move()` - fn parse_external_call(&mut self, expr: Expression) -> Result { + // Parses an external function call `credits.aleo/transfer()` or locator `token.aleo/accounts`. + fn parse_external_resource(&mut self, expr: Expression) -> Result { // Eat an external function call. self.eat(&Token::Div); // todo: Make `/` a more general token. - // Parse function name. + // Parse name. let name = self.expect_identifier()?; - // Parsing a '{' means that user is trying to illegally define an external record. - if self.token.token == Token::LeftCurly { - return Err(ParserError::cannot_define_external_record(expr.span() + name.span()).into()); - } - - // Parse the function call. - let (arguments, _, span) = self.parse_paren_comma_list(|p| p.parse_expression().map(Some))?; - // Parse the parent program identifier. let program: Symbol = match expr { Expression::Identifier(identifier) => identifier.name, _ => unreachable!("Function called must be preceded by a program identifier."), }; + // Parsing a '{' means that user is trying to illegally define an external record. + if self.token.token == Token::LeftCurly { + return Err(ParserError::cannot_define_external_record(expr.span() + name.span()).into()); + } + + // If there is no parenthesis, then it is a locator. + if self.token.token != Token::LeftParen { + // Parse an external resource locator. + return Ok(Expression::Locator(LocatorExpression { + program, + name: name.name, + span: expr.span() + name.span(), + id: self.node_builder.next_id(), + })); + } + + // Parse the function call. + let (arguments, _, span) = self.parse_paren_comma_list(|p| p.parse_expression().map(Some))?; + Ok(Expression::Call(CallExpression { span: expr.span() + span, function: Box::new(Expression::Identifier(name)), @@ -483,7 +494,8 @@ impl ParserContext<'_> { } else if self.eat(&Token::Leo) { return Err(ParserError::only_aleo_external_calls(expr.span()).into()); } else if self.eat(&Token::Aleo) { - expr = self.parse_external_call(expr)?; + + expr = self.parse_external_resource(expr)?; } else { // Parse identifier name. let name = self.expect_identifier()?;