Support parsing awaiting of futures both as f.await() and Future::await(f)

This commit is contained in:
evan-schott 2024-02-28 19:37:07 -08:00
parent ef069da30f
commit a3e3065bd3
5 changed files with 42 additions and 25 deletions

View File

@ -33,6 +33,8 @@ pub enum AccessExpression {
AssociatedFunction(AssociatedFunction),
/// An expression accessing a field in a structure, e.g., `struct_var.field`.
Member(MemberAccess),
/// Access a method associated to an instance of a struct, `f.await()`.
MethodCall(MethodCall),
/// Access to a tuple field using its position, e.g., `tuple.1`.
Tuple(TupleAccess),
}
@ -44,6 +46,7 @@ impl Node for AccessExpression {
AccessExpression::AssociatedConstant(n) => n.span(),
AccessExpression::AssociatedFunction(n) => n.span(),
AccessExpression::Member(n) => n.span(),
AccessExpression::MethodCall(n) => n.span(),
AccessExpression::Tuple(n) => n.span(),
}
}
@ -54,6 +57,7 @@ impl Node for AccessExpression {
AccessExpression::AssociatedConstant(n) => n.set_span(span),
AccessExpression::AssociatedFunction(n) => n.set_span(span),
AccessExpression::Member(n) => n.set_span(span),
AccessExpression::MethodCall(n) => n.set_span(span),
AccessExpression::Tuple(n) => n.set_span(span),
}
}
@ -64,6 +68,7 @@ impl Node for AccessExpression {
AccessExpression::AssociatedConstant(n) => n.id(),
AccessExpression::AssociatedFunction(n) => n.id(),
AccessExpression::Member(n) => n.id(),
AccessExpression::MethodCall(n) => n.id(),
AccessExpression::Tuple(n) => n.id(),
}
}
@ -74,6 +79,7 @@ impl Node for AccessExpression {
AccessExpression::AssociatedConstant(n) => n.set_id(id),
AccessExpression::AssociatedFunction(n) => n.set_id(id),
AccessExpression::Member(n) => n.set_id(id),
AccessExpression::MethodCall(n) => n.set_id(id),
AccessExpression::Tuple(n) => n.set_id(id),
}
}
@ -87,6 +93,7 @@ impl fmt::Display for AccessExpression {
AssociatedConstant(access) => access.fmt(f),
AssociatedFunction(access) => access.fmt(f),
Member(access) => access.fmt(f),
MethodCall(access) => access.fmt(f),
Tuple(access) => access.fmt(f),
}
}

View File

@ -35,7 +35,7 @@ use crate::{
};
use leo_span::{sym, Span, Symbol};
use crate::Type::{Composite};
use crate::{stub::future_stub::FutureStub, Type::Composite};
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use snarkvm::{
@ -47,7 +47,6 @@ use snarkvm::{
synthesizer::program::{ClosureCore, CommandTrait, FunctionCore, InstructionTrait},
};
use std::fmt;
use crate::stub::future_stub::FutureStub;
/// A function stub definition.
#[derive(Clone, Serialize, Deserialize)]
@ -107,7 +106,18 @@ impl FunctionStub {
_ => Type::Tuple(TupleType::new(output.iter().map(get_output_type).collect())),
};
FunctionStub { annotations, is_async, variant, identifier, future_stubs: Vec::new(), input, output, output_type, span, id }
FunctionStub {
annotations,
is_async,
variant,
identifier,
future_stubs: Vec::new(),
input,
output,
output_type,
span,
id,
}
}
/// Returns function name.
@ -271,10 +281,17 @@ impl FunctionStub {
is_async: true,
variant: Variant::Transition,
identifier: Identifier::new(name, Default::default()),
future_stubs: function.inputs().iter().filter_map(|input| match input.value_type() {
ValueType::Future(val) => Some(FutureStub::new(Identifier::from(val.program_id().name()).name, Identifier::from(val.resource()).name)),
_ => None,
}).collect(),
future_stubs: function
.inputs()
.iter()
.filter_map(|input| match input.value_type() {
ValueType::Future(val) => Some(FutureStub::new(
Identifier::from(val.program_id().name()).name,
Identifier::from(val.resource()).name,
)),
_ => None,
})
.collect(),
input: function
.finalize_logic()
.unwrap()

View File

@ -35,25 +35,19 @@ impl Eq for FutureStub {}
impl FutureStub {
/// Initialize a new future stub.
pub fn new(
program: Symbol,
function: Symbol,
) -> Self {
FutureStub {
program,
function,
}
pub fn new(program: Symbol, function: Symbol) -> Self {
FutureStub { program, function }
}
pub fn to_key(&self) -> (Symbol, Symbol) {
(self.program, self.function)
}
/// Get the program.
pub fn program(&self) -> Symbol {
self.program
}
/// Get the function.
pub fn function(&self) -> Symbol {
self.function

View File

@ -31,6 +31,7 @@ impl FutureType {
pub fn new(inputs: Vec<Type>) -> Self {
Self { inputs }
}
/// Returns the inputs of the future type.
pub fn inputs(&self) -> &[Type] {
&self.inputs

View File

@ -357,13 +357,11 @@ impl ParserContext<'_> {
span,
id: self.node_builder.next_id(),
})))
} else if let (0, Some(CoreFunction::FutureAwait)) =
(args.len(), CoreFunction::from_symbols(sym::Future, method.name))
{
Ok(Expression::Access(AccessExpression::AssociatedFunction(AssociatedFunction {
variant: method,
name: Identifier::new(sym::Future, self.node_builder.next_id()),
arguments: Vec::new(),
} else if let (0, sym::Await) = (args.len(), method.name) {
Ok(Expression::Access(AccessExpression::MethodCall(MethodCall {
receiver: Box::new(receiver),
name: method,
arguments: args,
span,
id: self.node_builder.next_id(),
})))