allow static, and calls

This commit is contained in:
gluaxspeed 2021-02-01 15:20:24 -05:00
parent 7affb3e099
commit 1cbbee4517
4 changed files with 34 additions and 15 deletions

View File

@ -259,29 +259,42 @@ impl<'ast> From<SelfPostfixExpression<'ast>> for Expression {
fn from(expression: SelfPostfixExpression<'ast>) -> Self {
let variable = Expression::Identifier(Identifier::from(expression.name));
// ast::PostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but Access call expressions
// ast::SelfPostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but Access call expressions
// are recursive, so it is `Select(Call(a, 34), 42)`. We apply this transformation here
// we start with the id, and we fold the array of accesses by wrapping the current value
expression
let final_expression = expression
.accesses
.into_iter()
.fold(variable, |acc, access| match access {
// Handle array accesses
// Handle function calls
SelfAccess::Call(function) => Expression::Call(CallExpression {
function: Box::new(acc),
arguments: function.expressions.into_iter().map(Expression::from).collect(),
span: Span::from(function.span),
}),
// Handle circuit member accesses
SelfAccess::Object(circuit_object) => Expression::CircuitMemberAccess(CircuitMemberAccessExpression {
circuit: Box::new(acc),
name: Identifier::from(circuit_object.identifier),
span: Span::from(circuit_object.span),
}),
})
// Handle static access
SelfAccess::StaticObject(circuit_object) => {
Expression::CircuitStaticFunctionAccess(CircuitStaticFunctionAccessExpression {
circuit: Box::new(acc),
name: Identifier::from(circuit_object.identifier),
span: Span::from(circuit_object.span),
})
}
});
// Handle calls, should only ever come after self. or self::
match expression.call {
Some(function) => {
return Expression::Call(CallExpression {
function: Box::new(final_expression),
arguments: function.expressions.into_iter().map(Expression::from).collect(),
span: Span::from(function.span),
});
}
None => return final_expression,
}
}
}

View File

@ -22,6 +22,6 @@ use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::self_access))]
pub enum SelfAccess<'ast> {
Call(CallAccess<'ast>),
Object(MemberAccess<'ast>),
StaticObject(StaticMemberAccess<'ast>),
}

View File

@ -14,7 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{access::SelfAccess, ast::Rule, common::SelfKeyword, SpanDef};
use crate::{
access::{CallAccess, SelfAccess},
ast::Rule,
common::SelfKeyword,
SpanDef,
};
use pest::Span;
use pest_ast::FromPest;
@ -25,6 +30,7 @@ use serde::Serialize;
pub struct SelfPostfixExpression<'ast> {
pub name: SelfKeyword<'ast>,
pub accesses: Vec<SelfAccess<'ast>>,
pub call: Option<CallAccess<'ast>>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,

View File

@ -302,7 +302,7 @@ value_address = ${ type_address ~ "(" ~ address ~ ")" }
access = { access_array | access_tuple | access_call | access_member | access_static_member }
// Declared in access/self_access.rs
self_access = { access_member }
self_access = { access_member | access_static_member }
// Declared in access/array_access.rs
access_array = !{ "[" ~ range_or_expression ~ "]" }
@ -389,7 +389,7 @@ expression_unary = { operation_unary ~ expression_term }
expression_postfix = ${ keyword_or_identifier ~ access+ }
// Declared in expressions/self_postfix_expression.rs
self_expression_postfix = ${ self_keyword ~ self_access+ }
self_expression_postfix = ${ self_keyword ~ self_access+ ~ access_call? }
/// Statements