mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-11 04:49:15 +03:00
push code to parse external calls
This commit is contained in:
parent
93307b1446
commit
0a86a05d20
@ -16,7 +16,7 @@
|
||||
|
||||
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)]
|
||||
pub struct CallExpression {
|
||||
/// An expression evaluating to a callable function,
|
||||
@ -24,13 +24,23 @@ pub struct CallExpression {
|
||||
pub function: Box<Expression>, // todo: make this identifier?
|
||||
/// Expressions for the arguments passed to the functions parameters.
|
||||
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)`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for CallExpression {
|
||||
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() {
|
||||
write!(f, "{}", param)?;
|
||||
if i < self.arguments.len() - 1 {
|
||||
|
@ -91,6 +91,7 @@ pub trait ExpressionReconstructor {
|
||||
.into_iter()
|
||||
.map(|arg| self.reconstruct_expression(arg).0)
|
||||
.collect(),
|
||||
external: input.external,
|
||||
span: input.span,
|
||||
}),
|
||||
Default::default(),
|
||||
|
@ -364,6 +364,21 @@ impl ParserContext<'_> {
|
||||
index,
|
||||
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 {
|
||||
// Parse identifier name.
|
||||
let name = self.expect_identifier()?;
|
||||
@ -389,6 +404,7 @@ impl ParserContext<'_> {
|
||||
expr = Expression::Call(CallExpression {
|
||||
span: expr.span() + span,
|
||||
function: Box::new(expr),
|
||||
external: None,
|
||||
arguments,
|
||||
});
|
||||
}
|
||||
|
@ -95,12 +95,11 @@ impl ParserContext<'_> {
|
||||
|
||||
// Parse `.leo`.
|
||||
self.expect(&Token::Dot)?;
|
||||
let leo_file_extension = self.expect_identifier()?;
|
||||
|
||||
// Throw error for non-leo files.
|
||||
if leo_file_extension.name.ne(&sym::leo) {
|
||||
return Err(ParserError::leo_imports_only(leo_file_extension, self.token.span).into());
|
||||
if !self.eat(&Token::Leo) {
|
||||
// Throw error for non-leo files.
|
||||
return Err(ParserError::leo_imports_only(self.token.span).into());
|
||||
}
|
||||
|
||||
let _end = self.expect(&Token::Semicolon)?;
|
||||
|
||||
// Tokenize and parse import file.
|
||||
|
@ -417,6 +417,7 @@ impl Token {
|
||||
"increment" => Token::Increment,
|
||||
"import" => Token::Import,
|
||||
"let" => Token::Let,
|
||||
"leo" => Token::Leo,
|
||||
"mapping" => Token::Mapping,
|
||||
"public" => Token::Public,
|
||||
"record" => Token::Record,
|
||||
|
@ -130,6 +130,8 @@ pub enum Token {
|
||||
Return,
|
||||
SelfLower,
|
||||
Static,
|
||||
// For imports.
|
||||
Leo,
|
||||
|
||||
// Meta Tokens
|
||||
Eof,
|
||||
@ -213,6 +215,7 @@ impl Token {
|
||||
Token::Increment => sym::increment,
|
||||
Token::Import => sym::import,
|
||||
Token::Let => sym::Let,
|
||||
Token::Leo => sym::leo,
|
||||
Token::Mapping => sym::mapping,
|
||||
Token::Public => sym::Public,
|
||||
Token::Record => sym::record,
|
||||
@ -335,6 +338,7 @@ impl fmt::Display for Token {
|
||||
Public => write!(f, "public"),
|
||||
Return => write!(f, "return"),
|
||||
Static => write!(f, "static"),
|
||||
Leo => write!(f, "leo"),
|
||||
Eof => write!(f, "<eof>"),
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +276,10 @@ impl<'a> CodeGenerator<'a> {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
for argument in input.arguments.iter() {
|
||||
|
@ -133,6 +133,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
|
||||
function: input.function,
|
||||
// Consume the arguments.
|
||||
arguments,
|
||||
external: input.external,
|
||||
span: input.span,
|
||||
}));
|
||||
statements.push(statement);
|
||||
|
@ -249,8 +249,8 @@ create_messages!(
|
||||
|
||||
@formatted
|
||||
leo_imports_only {
|
||||
args: (name: impl Display),
|
||||
msg: format!("Invalid import call to non-leo file `{name}`."),
|
||||
args: (),
|
||||
msg: "Invalid import call to non-leo file.",
|
||||
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