diff --git a/src/ast.rs b/src/ast.rs index 6f8f55942d..fe5b35bca4 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -268,6 +268,21 @@ impl<'ast> fmt::Display for Variable<'ast> { } } +#[derive(Debug, FromPest, PartialEq, Clone)] +#[pest_ast(rule(Rule::optionally_typed_variable))] +pub struct OptionallyTypedVariable<'ast> { + pub ty: Option>, + pub id: Variable<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + +impl<'ast> fmt::Display for OptionallyTypedVariable<'ast> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.id) + } +} + // Access #[derive(Clone, Debug, FromPest, PartialEq)] @@ -782,25 +797,6 @@ impl<'ast> FromPest<'ast> for Expression<'ast> { // Statements -#[derive(Clone, Debug, FromPest, PartialEq)] -#[pest_ast(rule(Rule::statement_assign))] -pub struct AssignStatement<'ast> { - pub assignee: Assignee<'ast>, - pub expression: Expression<'ast>, - #[pest_ast(outer())] - pub span: Span<'ast>, -} - -#[derive(Clone, Debug, FromPest, PartialEq)] -#[pest_ast(rule(Rule::statement_definition))] -pub struct DefinitionStatement<'ast> { - pub ty: Type<'ast>, - pub variable: Variable<'ast>, - pub expression: Expression<'ast>, - #[pest_ast(outer())] - pub span: Span<'ast>, -} - #[derive(Clone, Debug, FromPest, PartialEq)] #[pest_ast(rule(Rule::statement_return))] pub struct ReturnStatement<'ast> { @@ -820,25 +816,43 @@ pub struct ForStatement<'ast> { pub span: Span<'ast>, } +#[derive(Clone, Debug, FromPest, PartialEq)] +#[pest_ast(rule(Rule::statement_multiple_assignment))] +pub struct MultipleAssignmentStatement<'ast> { + pub assignees: Vec>, + pub function_name: Variable<'ast>, + pub arguments: Vec>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + +#[derive(Clone, Debug, FromPest, PartialEq)] +#[pest_ast(rule(Rule::statement_definition))] +pub struct DefinitionStatement<'ast> { + pub ty: Type<'ast>, + pub variable: Variable<'ast>, + pub expression: Expression<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + +#[derive(Clone, Debug, FromPest, PartialEq)] +#[pest_ast(rule(Rule::statement_assign))] +pub struct AssignStatement<'ast> { + pub assignee: Assignee<'ast>, + pub expression: Expression<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, +} + #[derive(Clone, Debug, FromPest, PartialEq)] #[pest_ast(rule(Rule::statement))] pub enum Statement<'ast> { - Assign(AssignStatement<'ast>), - Definition(DefinitionStatement<'ast>), Return(ReturnStatement<'ast>), Iteration(ForStatement<'ast>), -} - -impl<'ast> fmt::Display for AssignStatement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} = {}", self.assignee, self.expression) - } -} - -impl<'ast> fmt::Display for DefinitionStatement<'ast> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} {} = {}", self.ty, self.variable, self.expression) - } + MultipleAssignment(MultipleAssignmentStatement<'ast>), + Definition(DefinitionStatement<'ast>), + Assign(AssignStatement<'ast>), } impl<'ast> fmt::Display for ReturnStatement<'ast> { @@ -863,13 +877,38 @@ impl<'ast> fmt::Display for ForStatement<'ast> { } } +impl<'ast> fmt::Display for MultipleAssignmentStatement<'ast> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for (i, id) in self.assignees.iter().enumerate() { + write!(f, "{}", id)?; + if i < ids.len() - 1 { + write!(f, ", ")?; + } + } + write!(f, " = {}", self.function_id) + } +} + +impl<'ast> fmt::Display for DefinitionStatement<'ast> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} {} = {}", self.ty, self.variable, self.expression) + } +} + +impl<'ast> fmt::Display for AssignStatement<'ast> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} = {}", self.assignee, self.expression) + } +} + impl<'ast> fmt::Display for Statement<'ast> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Statement::Assign(ref statement) => write!(f, "{}", statement), - Statement::Definition(ref statement) => write!(f, "{}", statement), Statement::Return(ref statement) => write!(f, "{}", statement), Statement::Iteration(ref statement) => write!(f, "{}", statement), + Statement::MultipleAssignment(ref statement) => write!(f, "{}", statement), + Statement::Assign(ref statement) => write!(f, "{}", statement), + Statement::Definition(ref statement) => write!(f, "{}", statement), } } } diff --git a/src/leo.pest b/src/leo.pest index bebde9d5fc..6ed5f27fcd 100644 --- a/src/leo.pest +++ b/src/leo.pest @@ -76,6 +76,8 @@ protected_name = { visibility | value_boolean | "return" } // "def" | "in" | "return" | "struct" | "true" } variable = @{ ((!protected_name ~ ASCII_ALPHA) | (protected_name ~ (ASCII_ALPHANUMERIC | "_"))) ~ (ASCII_ALPHANUMERIC | "_")* } +optionally_typed_variable = { (variable) | (ty ~ variable) } +optionally_typed_variable_tuple = _{ optionally_typed_variable ~ ("," ~ optionally_typed_variable)* } expression_primitive = { value | variable } /// Access @@ -139,14 +141,16 @@ expression_tuple = _{ (expression ~ ("," ~ expression)*)? } /// Statements -statement_assign = { assignee ~ "=" ~ expression } -statement_definition = { ty ~ variable ~ "=" ~ expression } statement_return = { "return" ~ expression_tuple } statement_for = { "for" ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"} +statement_multiple_assignment = { optionally_typed_variable_tuple ~ "=" ~ variable ~ "(" ~ expression_tuple ~ ")" } +statement_definition = { ty ~ variable ~ "=" ~ expression } +statement_assign = { assignee ~ "=" ~ expression } statement = { (statement_return | (statement_for + | statement_multiple_assignment | statement_definition | statement_assign ) ~ NEWLINE