mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-13 08:47:17 +03:00
push code to parse external calls
This commit is contained in:
parent
93307b1446
commit
0a86a05d20
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// A function call expression, e.g., `foo(args)` or `Foo::bar(args)`.
|
/// A function call expression, e.g.`foo(args)` or `Foo::bar(args)`.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct CallExpression {
|
pub struct CallExpression {
|
||||||
/// An expression evaluating to a callable function,
|
/// An expression evaluating to a callable function,
|
||||||
@ -24,13 +24,23 @@ pub struct CallExpression {
|
|||||||
pub function: Box<Expression>, // todo: make this identifier?
|
pub function: Box<Expression>, // todo: make this identifier?
|
||||||
/// Expressions for the arguments passed to the functions parameters.
|
/// Expressions for the arguments passed to the functions parameters.
|
||||||
pub arguments: Vec<Expression>,
|
pub arguments: Vec<Expression>,
|
||||||
|
/// The name of the external program call, e.g.`bar` in `bar.leo`.
|
||||||
|
pub external: Option<Box<Expression>>,
|
||||||
/// Span of the entire call `function(arguments)`.
|
/// Span of the entire call `function(arguments)`.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CallExpression {
|
impl fmt::Display for CallExpression {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}(", self.function)?;
|
match &self.external {
|
||||||
|
Some(external) => {
|
||||||
|
write!(f, "{}.leo/{}(", external, self.function)?;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
write!(f, "{}(", self.function)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i, param) in self.arguments.iter().enumerate() {
|
for (i, param) in self.arguments.iter().enumerate() {
|
||||||
write!(f, "{}", param)?;
|
write!(f, "{}", param)?;
|
||||||
if i < self.arguments.len() - 1 {
|
if i < self.arguments.len() - 1 {
|
||||||
|
@ -91,6 +91,7 @@ pub trait ExpressionReconstructor {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|arg| self.reconstruct_expression(arg).0)
|
.map(|arg| self.reconstruct_expression(arg).0)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
external: input.external,
|
||||||
span: input.span,
|
span: input.span,
|
||||||
}),
|
}),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
@ -364,6 +364,21 @@ impl ParserContext<'_> {
|
|||||||
index,
|
index,
|
||||||
span,
|
span,
|
||||||
}))
|
}))
|
||||||
|
} else if self.eat(&Token::Leo) {
|
||||||
|
// Eat an external function call.
|
||||||
|
self.eat(&Token::Div); // todo: Make `/` a more general token.
|
||||||
|
|
||||||
|
// Parse function name.
|
||||||
|
let name = self.expect_identifier()?;
|
||||||
|
|
||||||
|
// Parse the function call.
|
||||||
|
let (arguments, _, span) = self.parse_paren_comma_list(|p| p.parse_expression().map(Some))?;
|
||||||
|
expr = Expression::Call(CallExpression {
|
||||||
|
span: expr.span() + span,
|
||||||
|
function: Box::new(Expression::Identifier(name)),
|
||||||
|
external: Some(Box::new(expr)),
|
||||||
|
arguments,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Parse identifier name.
|
// Parse identifier name.
|
||||||
let name = self.expect_identifier()?;
|
let name = self.expect_identifier()?;
|
||||||
@ -389,6 +404,7 @@ impl ParserContext<'_> {
|
|||||||
expr = Expression::Call(CallExpression {
|
expr = Expression::Call(CallExpression {
|
||||||
span: expr.span() + span,
|
span: expr.span() + span,
|
||||||
function: Box::new(expr),
|
function: Box::new(expr),
|
||||||
|
external: None,
|
||||||
arguments,
|
arguments,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -95,12 +95,11 @@ impl ParserContext<'_> {
|
|||||||
|
|
||||||
// Parse `.leo`.
|
// Parse `.leo`.
|
||||||
self.expect(&Token::Dot)?;
|
self.expect(&Token::Dot)?;
|
||||||
let leo_file_extension = self.expect_identifier()?;
|
if !self.eat(&Token::Leo) {
|
||||||
|
// Throw error for non-leo files.
|
||||||
// Throw error for non-leo files.
|
return Err(ParserError::leo_imports_only(self.token.span).into());
|
||||||
if leo_file_extension.name.ne(&sym::leo) {
|
|
||||||
return Err(ParserError::leo_imports_only(leo_file_extension, self.token.span).into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _end = self.expect(&Token::Semicolon)?;
|
let _end = self.expect(&Token::Semicolon)?;
|
||||||
|
|
||||||
// Tokenize and parse import file.
|
// Tokenize and parse import file.
|
||||||
|
@ -417,6 +417,7 @@ impl Token {
|
|||||||
"increment" => Token::Increment,
|
"increment" => Token::Increment,
|
||||||
"import" => Token::Import,
|
"import" => Token::Import,
|
||||||
"let" => Token::Let,
|
"let" => Token::Let,
|
||||||
|
"leo" => Token::Leo,
|
||||||
"mapping" => Token::Mapping,
|
"mapping" => Token::Mapping,
|
||||||
"public" => Token::Public,
|
"public" => Token::Public,
|
||||||
"record" => Token::Record,
|
"record" => Token::Record,
|
||||||
|
@ -130,6 +130,8 @@ pub enum Token {
|
|||||||
Return,
|
Return,
|
||||||
SelfLower,
|
SelfLower,
|
||||||
Static,
|
Static,
|
||||||
|
// For imports.
|
||||||
|
Leo,
|
||||||
|
|
||||||
// Meta Tokens
|
// Meta Tokens
|
||||||
Eof,
|
Eof,
|
||||||
@ -213,6 +215,7 @@ impl Token {
|
|||||||
Token::Increment => sym::increment,
|
Token::Increment => sym::increment,
|
||||||
Token::Import => sym::import,
|
Token::Import => sym::import,
|
||||||
Token::Let => sym::Let,
|
Token::Let => sym::Let,
|
||||||
|
Token::Leo => sym::leo,
|
||||||
Token::Mapping => sym::mapping,
|
Token::Mapping => sym::mapping,
|
||||||
Token::Public => sym::Public,
|
Token::Public => sym::Public,
|
||||||
Token::Record => sym::record,
|
Token::Record => sym::record,
|
||||||
@ -335,6 +338,7 @@ impl fmt::Display for Token {
|
|||||||
Public => write!(f, "public"),
|
Public => write!(f, "public"),
|
||||||
Return => write!(f, "return"),
|
Return => write!(f, "return"),
|
||||||
Static => write!(f, "static"),
|
Static => write!(f, "static"),
|
||||||
|
Leo => write!(f, "leo"),
|
||||||
Eof => write!(f, "<eof>"),
|
Eof => write!(f, "<eof>"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,10 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_call(&mut self, input: &'a CallExpression) -> (String, String) {
|
fn visit_call(&mut self, input: &'a CallExpression) -> (String, String) {
|
||||||
let mut call_instruction = format!(" call {} ", input.function);
|
let mut call_instruction = match &input.external {
|
||||||
|
Some(external) => format!(" call {}.aleo/{} ", external, input.function),
|
||||||
|
None => format!(" call {} ", input.function),
|
||||||
|
};
|
||||||
let mut instructions = String::new();
|
let mut instructions = String::new();
|
||||||
|
|
||||||
for argument in input.arguments.iter() {
|
for argument in input.arguments.iter() {
|
||||||
|
@ -133,6 +133,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
|
|||||||
function: input.function,
|
function: input.function,
|
||||||
// Consume the arguments.
|
// Consume the arguments.
|
||||||
arguments,
|
arguments,
|
||||||
|
external: input.external,
|
||||||
span: input.span,
|
span: input.span,
|
||||||
}));
|
}));
|
||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
|
@ -249,8 +249,8 @@ create_messages!(
|
|||||||
|
|
||||||
@formatted
|
@formatted
|
||||||
leo_imports_only {
|
leo_imports_only {
|
||||||
args: (name: impl Display),
|
args: (),
|
||||||
msg: format!("Invalid import call to non-leo file `{name}`."),
|
msg: "Invalid import call to non-leo file.",
|
||||||
help: Some("Only imports of Leo `.leo` files are currently supported.".to_string()),
|
help: Some("Only imports of Leo `.leo` files are currently supported.".to_string()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
0
examples/helloworld/imports/point.leo
Normal file
0
examples/helloworld/imports/point.leo
Normal file
Loading…
Reference in New Issue
Block a user