mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 18:52:58 +03:00
merge master, update serialization test
This commit is contained in:
commit
4cac0aeb41
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -2478,9 +2478,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.59"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
|
||||
checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -14,7 +14,7 @@
|
||||
// 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::{FunctionInput, Identifier, Span, Statement, Type};
|
||||
use crate::{Block, FunctionInput, Identifier, Span, Type};
|
||||
use leo_grammar::functions::Function as GrammarFunction;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -25,7 +25,7 @@ pub struct Function {
|
||||
pub identifier: Identifier,
|
||||
pub input: Vec<FunctionInput>,
|
||||
pub output: Option<Type>,
|
||||
pub statements: Vec<Statement>,
|
||||
pub block: Block,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
@ -43,13 +43,13 @@ impl<'ast> From<GrammarFunction<'ast>> for Function {
|
||||
|
||||
let parameters = function.parameters.into_iter().map(FunctionInput::from).collect();
|
||||
let returns = function.returns.map(Type::from);
|
||||
let statements = function.statements.into_iter().map(Statement::from).collect();
|
||||
let block = Block::from(function.block);
|
||||
|
||||
Function {
|
||||
identifier: function_name,
|
||||
input: parameters,
|
||||
output: returns,
|
||||
statements,
|
||||
block,
|
||||
span: Span::from(function.span),
|
||||
}
|
||||
}
|
||||
@ -91,16 +91,10 @@ impl Function {
|
||||
|
||||
let parameters = self.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
let returns = self.output.as_ref().map(|type_| type_.to_string());
|
||||
let statements = self
|
||||
.statements
|
||||
.iter()
|
||||
.map(|s| format!("\t{}\n", s))
|
||||
.collect::<Vec<_>>()
|
||||
.join("");
|
||||
if returns.is_none() {
|
||||
write!(f, "({}) {{\n{}}}", parameters, statements,)
|
||||
write!(f, "({}) {}", parameters, self.block)
|
||||
} else {
|
||||
write!(f, "({}) -> {} {{\n{}}}", parameters, returns.unwrap(), statements,)
|
||||
write!(f, "({}) -> {} {}", parameters, returns.unwrap(), self.block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
48
ast/src/statements/block.rs
Normal file
48
ast/src/statements/block.rs
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// 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::Statement;
|
||||
use leo_grammar::statements::Block as GrammarBlock;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Block {
|
||||
pub statements: Vec<Statement>,
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarBlock<'ast>> for Block {
|
||||
fn from(block: GrammarBlock<'ast>) -> Self {
|
||||
Block {
|
||||
statements: block.statements.into_iter().map(Statement::from).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Block {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "{{")?;
|
||||
if self.statements.is_empty() {
|
||||
writeln!(f, "\t")?;
|
||||
} else {
|
||||
self.statements
|
||||
.iter()
|
||||
.try_for_each(|statement| writeln!(f, "\t{}", statement))?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
// 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::{ConditionalStatement, Statement};
|
||||
use crate::{Block, ConditionalStatement};
|
||||
use leo_grammar::statements::ConditionalNestedOrEndStatement as GrammarConditionalNestedOrEndStatement;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -23,7 +23,7 @@ use std::fmt;
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ConditionalNestedOrEndStatement {
|
||||
Nested(Box<ConditionalStatement>),
|
||||
End(Vec<Statement>),
|
||||
End(Block),
|
||||
}
|
||||
|
||||
impl<'ast> From<GrammarConditionalNestedOrEndStatement<'ast>> for ConditionalNestedOrEndStatement {
|
||||
@ -32,8 +32,8 @@ impl<'ast> From<GrammarConditionalNestedOrEndStatement<'ast>> for ConditionalNes
|
||||
GrammarConditionalNestedOrEndStatement::Nested(nested) => {
|
||||
ConditionalNestedOrEndStatement::Nested(Box::new(ConditionalStatement::from(*nested)))
|
||||
}
|
||||
GrammarConditionalNestedOrEndStatement::End(statements) => {
|
||||
ConditionalNestedOrEndStatement::End(statements.into_iter().map(Statement::from).collect())
|
||||
GrammarConditionalNestedOrEndStatement::End(block) => {
|
||||
ConditionalNestedOrEndStatement::End(Block::from(block))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -43,13 +43,7 @@ impl fmt::Display for ConditionalNestedOrEndStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested),
|
||||
ConditionalNestedOrEndStatement::End(ref statements) => {
|
||||
writeln!(f, "else {{")?;
|
||||
for statement in statements.iter() {
|
||||
writeln!(f, "\t\t{}", statement)?;
|
||||
}
|
||||
write!(f, "\t}}")
|
||||
}
|
||||
ConditionalNestedOrEndStatement::End(ref block) => write!(f, "else {}", block),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// 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::{ConditionalNestedOrEndStatement, Expression, Statement};
|
||||
use crate::{Block, ConditionalNestedOrEndStatement, Expression};
|
||||
use leo_grammar::statements::ConditionalStatement as GrammarConditionalStatement;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -23,7 +23,7 @@ use std::fmt;
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ConditionalStatement {
|
||||
pub condition: Expression,
|
||||
pub statements: Vec<Statement>,
|
||||
pub block: Block,
|
||||
pub next: Option<ConditionalNestedOrEndStatement>,
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ impl<'ast> From<GrammarConditionalStatement<'ast>> for ConditionalStatement {
|
||||
fn from(statement: GrammarConditionalStatement<'ast>) -> Self {
|
||||
ConditionalStatement {
|
||||
condition: Expression::from(statement.condition),
|
||||
statements: statement.statements.into_iter().map(Statement::from).collect(),
|
||||
block: Block::from(statement.block),
|
||||
next: statement
|
||||
.next
|
||||
.map(|n_or_e| Some(ConditionalNestedOrEndStatement::from(n_or_e)))
|
||||
@ -42,13 +42,10 @@ impl<'ast> From<GrammarConditionalStatement<'ast>> for ConditionalStatement {
|
||||
|
||||
impl fmt::Display for ConditionalStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "if ({}) {{", self.condition)?;
|
||||
for statement in self.statements.iter() {
|
||||
writeln!(f, "\t\t{}", statement)?;
|
||||
}
|
||||
write!(f, "if ({}) {}", self.condition, self.block)?;
|
||||
match self.next.clone() {
|
||||
Some(n_or_e) => write!(f, "\t}} {}", n_or_e),
|
||||
None => write!(f, "\t}}"),
|
||||
Some(n_or_e) => write!(f, " {}", n_or_e),
|
||||
None => write!(f, ""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,3 +22,6 @@ pub use conditional_statement::*;
|
||||
|
||||
pub mod statement;
|
||||
pub use statement::*;
|
||||
|
||||
pub mod block;
|
||||
pub use block::*;
|
||||
|
@ -14,7 +14,17 @@
|
||||
// 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::{Assignee, ConditionalStatement, ConsoleFunctionCall, Declare, Expression, Identifier, Span, Variables};
|
||||
use crate::{
|
||||
Assignee,
|
||||
Block,
|
||||
ConditionalStatement,
|
||||
ConsoleFunctionCall,
|
||||
Declare,
|
||||
Expression,
|
||||
Identifier,
|
||||
Span,
|
||||
Variables,
|
||||
};
|
||||
use leo_grammar::{
|
||||
console::ConsoleFunctionCall as GrammarConsoleFunctionCall,
|
||||
operations::AssignOperation,
|
||||
@ -38,7 +48,7 @@ pub enum Statement {
|
||||
Definition(Declare, Variables, Expression, Span),
|
||||
Assign(Assignee, Expression, Span),
|
||||
Conditional(ConditionalStatement, Span),
|
||||
Iteration(Identifier, Box<(Expression, Expression)>, Vec<Statement>, Span),
|
||||
Iteration(Identifier, Box<(Expression, Expression)>, Block, Span),
|
||||
Console(ConsoleFunctionCall),
|
||||
Expression(Expression, Span),
|
||||
}
|
||||
@ -127,7 +137,7 @@ impl<'ast> From<ForStatement<'ast>> for Statement {
|
||||
Statement::Iteration(
|
||||
Identifier::from(statement.index),
|
||||
Box::new((Expression::from(statement.start), Expression::from(statement.stop))),
|
||||
statement.statements.into_iter().map(Statement::from).collect(),
|
||||
Block::from(statement.block),
|
||||
Span::from(statement.span),
|
||||
)
|
||||
}
|
||||
@ -176,12 +186,8 @@ impl fmt::Display for Statement {
|
||||
}
|
||||
Statement::Assign(ref variable, ref statement, ref _span) => write!(f, "{} = {};", variable, statement),
|
||||
Statement::Conditional(ref statement, ref _span) => write!(f, "{}", statement),
|
||||
Statement::Iteration(ref var, ref start_stop, ref list, ref _span) => {
|
||||
writeln!(f, "for {} in {}..{} {{", var, start_stop.0, start_stop.1)?;
|
||||
for l in list {
|
||||
writeln!(f, "\t\t{}", l)?;
|
||||
}
|
||||
write!(f, "\t}}")
|
||||
Statement::Iteration(ref var, ref start_stop, ref block, ref _span) => {
|
||||
write!(f, "for {} in {}..{} {}", var, start_stop.0, start_stop.1, block)
|
||||
}
|
||||
Statement::Console(ref console) => write!(f, "{}", console),
|
||||
Statement::Expression(ref expression, ref _span) => write!(f, "{};", expression),
|
||||
|
@ -8,50 +8,52 @@
|
||||
"identifier": "{\"name\":\"main\",\"span\":\"{\\\"text\\\":\\\" function main() {\\\",\\\"line\\\":1,\\\"start\\\":10,\\\"end\\\":14}\"}",
|
||||
"input": [],
|
||||
"output": null,
|
||||
"statements": [
|
||||
{
|
||||
"Return": [
|
||||
{
|
||||
"Add": [[
|
||||
{
|
||||
"Implicit": [
|
||||
"1",
|
||||
{
|
||||
"text": " return 1 + 1",
|
||||
"line": 2,
|
||||
"start": 12,
|
||||
"end": 13
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Implicit": [
|
||||
"1",
|
||||
{
|
||||
"text": " return 1 + 1",
|
||||
"line": 2,
|
||||
"start": 16,
|
||||
"end": 17
|
||||
}
|
||||
]
|
||||
}],
|
||||
{
|
||||
"text": " return 1 + 1",
|
||||
"line": 2,
|
||||
"start": 12,
|
||||
"end": 17
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": " return 1 + 1",
|
||||
"line": 2,
|
||||
"start": 5,
|
||||
"end": 17
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"block" : {
|
||||
"statements": [
|
||||
{
|
||||
"Return": [
|
||||
{
|
||||
"Add": [[
|
||||
{
|
||||
"Implicit": [
|
||||
"1",
|
||||
{
|
||||
"text": " return 1 + 1",
|
||||
"line": 2,
|
||||
"start": 12,
|
||||
"end": 13
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Implicit": [
|
||||
"1",
|
||||
{
|
||||
"text": " return 1 + 1",
|
||||
"line": 2,
|
||||
"start": 16,
|
||||
"end": 17
|
||||
}
|
||||
]
|
||||
}],
|
||||
{
|
||||
"text": " return 1 + 1",
|
||||
"line": 2,
|
||||
"start": 12,
|
||||
"end": 17
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": " return 1 + 1",
|
||||
"line": 2,
|
||||
"start": 5,
|
||||
"end": 17
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"span": {
|
||||
"text": " function main() {",
|
||||
"line": 1,
|
||||
|
@ -93,7 +93,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// Evaluate every statement in the function and save all potential results
|
||||
let mut results = vec![];
|
||||
|
||||
for statement in function.statements.iter() {
|
||||
for statement in function.block.statements.iter() {
|
||||
let mut result = self.enforce_statement(
|
||||
cs,
|
||||
scope,
|
||||
|
@ -17,7 +17,7 @@
|
||||
//! Enforces a branch of a conditional or iteration statement in a compiled Leo program.
|
||||
|
||||
use crate::{program::ConstrainedProgram, GroupType, IndicatorAndConstrainedValue, StatementResult};
|
||||
use leo_ast::{Statement, Type};
|
||||
use leo_ast::{Block, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -28,19 +28,19 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
/// Evaluates a branch of one or more statements and returns a result in
|
||||
/// the given scope.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn evaluate_branch<CS: ConstraintSystem<F>>(
|
||||
pub fn evaluate_block<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: &str,
|
||||
function_scope: &str,
|
||||
indicator: Option<Boolean>,
|
||||
statements: Vec<Statement>,
|
||||
block: Block,
|
||||
return_type: Option<Type>,
|
||||
mut_self: bool,
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let mut results = Vec::with_capacity(statements.len());
|
||||
let mut results = Vec::with_capacity(block.statements.len());
|
||||
// Evaluate statements. Only allow a single return argument to be returned.
|
||||
for statement in statements.into_iter() {
|
||||
for statement in block.statements.into_iter() {
|
||||
let mut value = self.enforce_statement(
|
||||
cs,
|
||||
file_scope,
|
@ -17,5 +17,5 @@
|
||||
//! Methods to enforce constraints on a branch of a conditional or iteration statement
|
||||
//! in a compiled Leo program.
|
||||
|
||||
pub mod branch;
|
||||
pub use self::branch::*;
|
||||
pub mod block;
|
||||
pub use self::block::*;
|
@ -89,12 +89,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let mut results = vec![];
|
||||
|
||||
// Evaluate branch 1
|
||||
let mut branch_1_result = self.evaluate_branch(
|
||||
let mut branch_1_result = self.evaluate_block(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
Some(branch_1_indicator),
|
||||
statement.statements,
|
||||
statement.block,
|
||||
return_type.clone(),
|
||||
mut_self,
|
||||
)?;
|
||||
@ -128,12 +128,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
mut_self,
|
||||
span,
|
||||
)?,
|
||||
ConditionalNestedOrEndStatement::End(statements) => self.evaluate_branch(
|
||||
ConditionalNestedOrEndStatement::End(block) => self.evaluate_block(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
Some(branch_2_indicator),
|
||||
statements,
|
||||
block,
|
||||
return_type,
|
||||
mut_self,
|
||||
)?,
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
Integer,
|
||||
StatementResult,
|
||||
};
|
||||
use leo_ast::{Expression, Identifier, Span, Statement, Type};
|
||||
use leo_ast::{Block, Expression, Identifier, Span, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -46,7 +46,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
index: Identifier,
|
||||
start: Expression,
|
||||
stop: Expression,
|
||||
statements: Vec<Statement>,
|
||||
block: Block,
|
||||
return_type: Option<Type>,
|
||||
mut_self: bool,
|
||||
span: &Span,
|
||||
@ -68,12 +68,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
);
|
||||
|
||||
// Evaluate statements and possibly return early
|
||||
let mut result = self.evaluate_branch(
|
||||
let mut result = self.evaluate_block(
|
||||
&mut cs.ns(|| format!("for loop iteration {} {}:{}", i, span.line, span.start)),
|
||||
file_scope,
|
||||
function_scope,
|
||||
indicator,
|
||||
statements.clone(),
|
||||
block.clone(),
|
||||
return_type.clone(),
|
||||
mut_self,
|
||||
)?;
|
||||
|
@ -19,8 +19,8 @@
|
||||
pub mod assign;
|
||||
pub use self::assign::*;
|
||||
|
||||
pub mod branch;
|
||||
pub use self::branch::*;
|
||||
pub mod block;
|
||||
pub use self::block::*;
|
||||
|
||||
pub mod conditional;
|
||||
pub use self::conditional::*;
|
||||
|
@ -96,7 +96,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
results.append(&mut result);
|
||||
}
|
||||
Statement::Iteration(index, start_stop, statements, span) => {
|
||||
Statement::Iteration(index, start_stop, block, span) => {
|
||||
let mut result = self.enforce_iteration_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
@ -105,7 +105,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
index,
|
||||
start_stop.0,
|
||||
start_stop.1,
|
||||
statements,
|
||||
block,
|
||||
return_type,
|
||||
mut_self,
|
||||
&span,
|
||||
|
@ -18,6 +18,7 @@ use crate::{CoreCircuit, CoreCircuitError, Value};
|
||||
|
||||
use leo_ast::{
|
||||
ArrayDimensions,
|
||||
Block,
|
||||
Circuit,
|
||||
CircuitMember,
|
||||
Expression,
|
||||
@ -105,23 +106,25 @@ impl CoreCircuit for Blake2sCircuit {
|
||||
span: span.clone(),
|
||||
}]),
|
||||
)),
|
||||
statements: vec![Statement::Return(
|
||||
Expression::CoreFunctionCall(
|
||||
Self::name(),
|
||||
vec![
|
||||
Expression::Identifier(Identifier {
|
||||
name: "seed".to_owned(),
|
||||
span: span.clone(),
|
||||
}),
|
||||
Expression::Identifier(Identifier {
|
||||
name: "message".to_owned(),
|
||||
span: span.clone(),
|
||||
}),
|
||||
],
|
||||
block: Block {
|
||||
statements: vec![Statement::Return(
|
||||
Expression::CoreFunctionCall(
|
||||
Self::name(),
|
||||
vec![
|
||||
Expression::Identifier(Identifier {
|
||||
name: "seed".to_owned(),
|
||||
span: span.clone(),
|
||||
}),
|
||||
Expression::Identifier(Identifier {
|
||||
name: "message".to_owned(),
|
||||
span: span.clone(),
|
||||
}),
|
||||
],
|
||||
span.clone(),
|
||||
),
|
||||
span.clone(),
|
||||
),
|
||||
span.clone(),
|
||||
)],
|
||||
)],
|
||||
},
|
||||
span,
|
||||
})],
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// 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::{ast::Rule, common::Identifier, functions::input::Input, statements::Statement, types::Type, SpanDef};
|
||||
use crate::{ast::Rule, common::Identifier, functions::input::Input, statements::Block, types::Type, SpanDef};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
@ -26,7 +26,7 @@ pub struct Function<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub parameters: Vec<Input<'ast>>,
|
||||
pub returns: Option<Type<'ast>>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
pub block: Block<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
#[serde(with = "SpanDef")]
|
||||
pub span: Span<'ast>,
|
||||
|
@ -396,9 +396,11 @@ statement = {
|
||||
// Declared in statements/assign_statement.rs
|
||||
statement_assign = { assignee ~ operation_assign ~ expression ~ LINE_END }
|
||||
|
||||
block = { "{" ~ NEWLINE* ~ statement* ~ NEWLINE* ~ "}" }
|
||||
|
||||
// Declared in statements/conditional_statement.rs
|
||||
statement_conditional = {"if " ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else " ~ conditional_nested_or_end_statement)?}
|
||||
conditional_nested_or_end_statement = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
statement_conditional = {"if " ~ expression ~ block ~ ("else " ~ conditional_nested_or_end_statement)?}
|
||||
conditional_nested_or_end_statement = { statement_conditional | block }
|
||||
|
||||
// Declared in statements/definition_statement.rs
|
||||
statement_definition = { declare ~ variables ~ "=" ~ expression ~ LINE_END}
|
||||
@ -407,7 +409,7 @@ statement_definition = { declare ~ variables ~ "=" ~ expression ~ LINE_END}
|
||||
statement_expression = { expression ~ LINE_END }
|
||||
|
||||
// Declared in statements/for_statement.rs
|
||||
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
statement_for = { "for " ~ identifier ~ "in " ~ expression ~ ".." ~ expression ~ block }
|
||||
|
||||
// Declared in statements/return_statement.rs
|
||||
statement_return = { "return " ~ expression}
|
||||
@ -418,7 +420,7 @@ statement_return = { "return " ~ expression}
|
||||
test_function = { "test " ~ function }
|
||||
|
||||
// Declared in functions/function.rs
|
||||
function = { "function " ~ identifier ~ input_tuple ~ ("->" ~ type_)? ~ "{" ~ NEWLINE* ~ statement* ~ NEWLINE* ~ "}" ~ NEWLINE* }
|
||||
function = { "function " ~ identifier ~ input_tuple ~ ("->" ~ type_)? ~ block ~ NEWLINE* }
|
||||
|
||||
// Declared in functions/input/function_input.rs
|
||||
function_input = { mutable? ~ identifier ~ ":" ~ type_ }
|
||||
|
45
grammar/src/statements/block.rs
Normal file
45
grammar/src/statements/block.rs
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// 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::{ast::Rule, statements::Statement, SpanDef};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use serde::Serialize;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
|
||||
#[pest_ast(rule(Rule::block))]
|
||||
pub struct Block<'ast> {
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
#[serde(with = "SpanDef")]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Block<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "{{")?;
|
||||
if self.statements.is_empty() {
|
||||
writeln!(f, "\t")?;
|
||||
} else {
|
||||
self.statements
|
||||
.iter()
|
||||
.try_for_each(|statement| writeln!(f, "\t{}", statement))?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
statements::{ConditionalStatement, Statement},
|
||||
statements::{Block, ConditionalStatement},
|
||||
};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
@ -27,14 +27,14 @@ use std::fmt;
|
||||
#[pest_ast(rule(Rule::conditional_nested_or_end_statement))]
|
||||
pub enum ConditionalNestedOrEndStatement<'ast> {
|
||||
Nested(Box<ConditionalStatement<'ast>>),
|
||||
End(Vec<Statement<'ast>>),
|
||||
End(Block<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ConditionalNestedOrEndStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested),
|
||||
ConditionalNestedOrEndStatement::End(ref statements) => write!(f, "else {{\n \t{:#?}\n }}", statements),
|
||||
ConditionalNestedOrEndStatement::End(ref block) => write!(f, "else {}", block),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
expressions::Expression,
|
||||
statements::{ConditionalNestedOrEndStatement, Statement},
|
||||
statements::{Block, ConditionalNestedOrEndStatement},
|
||||
SpanDef,
|
||||
};
|
||||
|
||||
@ -30,7 +30,7 @@ use std::fmt;
|
||||
#[pest_ast(rule(Rule::statement_conditional))]
|
||||
pub struct ConditionalStatement<'ast> {
|
||||
pub condition: Expression<'ast>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
pub block: Block<'ast>,
|
||||
pub next: Option<ConditionalNestedOrEndStatement<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
#[serde(with = "SpanDef")]
|
||||
@ -39,11 +39,10 @@ pub struct ConditionalStatement<'ast> {
|
||||
|
||||
impl<'ast> fmt::Display for ConditionalStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "if ({}) {{", self.condition)?;
|
||||
writeln!(f, "\t{:#?}", self.statements)?;
|
||||
write!(f, "if ({}) {}", self.condition, self.block)?;
|
||||
self.next
|
||||
.as_ref()
|
||||
.map(|n_or_e| write!(f, "}} {}", n_or_e))
|
||||
.unwrap_or_else(|| write!(f, "}}"))
|
||||
.map(|n_or_e| write!(f, " {}", n_or_e))
|
||||
.unwrap_or_else(|| write!(f, ""))
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// 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::{ast::Rule, common::Identifier, expressions::Expression, statements::Statement, SpanDef};
|
||||
use crate::{ast::Rule, common::Identifier, expressions::Expression, statements::Block, SpanDef};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
@ -27,7 +27,7 @@ pub struct ForStatement<'ast> {
|
||||
pub index: Identifier<'ast>,
|
||||
pub start: Expression<'ast>,
|
||||
pub stop: Expression<'ast>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
pub block: Block<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
#[serde(with = "SpanDef")]
|
||||
pub span: Span<'ast>,
|
||||
@ -35,10 +35,6 @@ pub struct ForStatement<'ast> {
|
||||
|
||||
impl<'ast> fmt::Display for ForStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"for {} in {}..{} {{ {:#?} }}",
|
||||
self.index, self.start, self.stop, self.statements
|
||||
)
|
||||
write!(f, "for {} in {}..{} {}", self.index, self.start, self.stop, self.block)
|
||||
}
|
||||
}
|
||||
|
@ -37,3 +37,6 @@ pub use return_statement::*;
|
||||
|
||||
pub mod statement;
|
||||
pub use statement::*;
|
||||
|
||||
pub mod block;
|
||||
pub use block::*;
|
||||
|
38
grammar/tests/display.rs
Normal file
38
grammar/tests/display.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// 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 from_pest::FromPest;
|
||||
use leo_grammar::{
|
||||
ast::{LanguageParser, Rule},
|
||||
statements::ConditionalStatement,
|
||||
};
|
||||
|
||||
use pest::*;
|
||||
|
||||
#[test]
|
||||
fn conditional_statement_display() {
|
||||
let input = r#"if (true) {
|
||||
|
||||
} else {
|
||||
|
||||
}"#;
|
||||
let conditional_statement =
|
||||
ConditionalStatement::from_pest(&mut LanguageParser::parse(Rule::statement_conditional, input).unwrap())
|
||||
.unwrap();
|
||||
let displayed = format!("{}", conditional_statement);
|
||||
|
||||
assert_eq!(input, displayed);
|
||||
}
|
@ -75,7 +75,7 @@ fn empty_def() {
|
||||
input: "function x() {}",
|
||||
rule: Rule::function,
|
||||
tokens: [
|
||||
function(0, 15, [identifier(9, 10, [])])
|
||||
function(0, 15, [identifier(9, 10, []), block(13, 15, [])])
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -87,7 +87,7 @@ fn returning_unit_type() {
|
||||
input: "function x() -> () {}",
|
||||
rule: Rule::function,
|
||||
tokens: [
|
||||
function(0, 21, [identifier(9, 10, []), type_(16, 18, [type_tuple(16, 18, [])])])
|
||||
function(0, 21, [identifier(9, 10, []), type_(16, 18, [type_tuple(16, 18, [])]), block(19, 21, [])])
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -99,8 +99,10 @@ fn returning_unit_value() {
|
||||
input: "function x() { return () }",
|
||||
rule: Rule::function,
|
||||
tokens: [
|
||||
function(0, 26, [identifier(9, 10, []), statement(15, 25, [
|
||||
statement_return(15, 25, [expression(22, 25, [expression_term(22, 24, [expression_tuple(22, 24, [])])])])
|
||||
function(0, 26, [identifier(9, 10, []), block(13, 26, [
|
||||
statement(15, 25, [
|
||||
statement_return(15, 25, [expression(22, 25, [expression_term(22, 24, [expression_tuple(22, 24, [])])])])
|
||||
])
|
||||
])])
|
||||
]
|
||||
}
|
||||
@ -122,9 +124,11 @@ fn id_def() {
|
||||
])
|
||||
]),
|
||||
type_(22, 24, [type_data(22, 24, [type_integer(22, 24, [type_integer_unsigned(22, 24, [type_u8(22, 24, [])])])])]),
|
||||
statement(27, 36, [statement_return(27, 36, [
|
||||
expression(34, 36, [expression_term(34, 35, [identifier(34, 35, [])])])
|
||||
])])
|
||||
block(25, 37, [
|
||||
statement(27, 36, [statement_return(27, 36, [
|
||||
expression(34, 36, [expression_term(34, 35, [identifier(34, 35, [])])])
|
||||
])])
|
||||
]),
|
||||
])
|
||||
]
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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/>.
|
||||
|
||||
mod display;
|
||||
mod expression;
|
||||
mod function;
|
||||
mod serialization;
|
||||
|
@ -12,55 +12,62 @@
|
||||
},
|
||||
"parameters": [],
|
||||
"returns": null,
|
||||
"statements": [
|
||||
{
|
||||
"Return": {
|
||||
"expression": {
|
||||
"Binary": {
|
||||
"operation": "Add",
|
||||
"left": {
|
||||
"Value": {
|
||||
"Implicit": {
|
||||
"Positive": {
|
||||
"value": "1",
|
||||
"span": {
|
||||
"input": "1",
|
||||
"start": 29,
|
||||
"end": 30
|
||||
"block": {
|
||||
"statements": [
|
||||
{
|
||||
"Return": {
|
||||
"expression": {
|
||||
"Binary": {
|
||||
"operation": "Add",
|
||||
"left": {
|
||||
"Value": {
|
||||
"Implicit": {
|
||||
"Positive": {
|
||||
"value": "1",
|
||||
"span": {
|
||||
"input": "1",
|
||||
"start": 29,
|
||||
"end": 30
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Implicit": {
|
||||
"Positive": {
|
||||
"value": "1",
|
||||
"span": {
|
||||
"input": "1",
|
||||
"start": 33,
|
||||
"end": 34
|
||||
},
|
||||
"right": {
|
||||
"Value": {
|
||||
"Implicit": {
|
||||
"Positive": {
|
||||
"value": "1",
|
||||
"span": {
|
||||
"input": "1",
|
||||
"start": 33,
|
||||
"end": 34
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"input": "1 + 1",
|
||||
"start": 29,
|
||||
"end": 34
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"input": "1 + 1",
|
||||
"start": 29,
|
||||
"end": 34
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"input": "return 1 + 1",
|
||||
"start": 22,
|
||||
"end": 34
|
||||
}
|
||||
},
|
||||
"span": {
|
||||
"input": "return 1 + 1",
|
||||
"start": 22,
|
||||
"end": 34
|
||||
}
|
||||
}
|
||||
],
|
||||
"span": {
|
||||
"input": "{\n return 1 + 1\n}",
|
||||
"start": 16,
|
||||
"end": 36
|
||||
}
|
||||
],
|
||||
},
|
||||
"span": {
|
||||
"input": "function main() {\n return 1 + 1\n}\n",
|
||||
"start": 0,
|
||||
|
@ -19,3 +19,6 @@ pub use self::cli::*;
|
||||
|
||||
pub mod commands;
|
||||
pub use self::commands::*;
|
||||
|
||||
pub mod updater;
|
||||
pub use self::updater::*;
|
||||
|
31
leo/errors/updater.rs
Normal file
31
leo/errors/updater.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// 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/>.
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum UpdaterError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("The current version {} is more recent than the release version {}", _0, _1)]
|
||||
OldReleaseVersion(String, String),
|
||||
}
|
||||
|
||||
impl From<self_update::errors::Error> for UpdaterError {
|
||||
fn from(error: self_update::errors::Error) -> Self {
|
||||
tracing::error!("{}\n", error);
|
||||
UpdaterError::Crate("self_update", error.to_string())
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
|
||||
// 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::config::Config;
|
||||
use crate::{config::Config, errors::UpdaterError};
|
||||
|
||||
use colored::Colorize;
|
||||
use self_update::{backends::github, version::bump_is_greater, Status};
|
||||
@ -27,7 +27,7 @@ impl Updater {
|
||||
const LEO_REPO_OWNER: &'static str = "AleoHQ";
|
||||
|
||||
/// Show all available releases for `leo`.
|
||||
pub fn show_available_releases() -> Result<(), self_update::errors::Error> {
|
||||
pub fn show_available_releases() -> Result<(), UpdaterError> {
|
||||
let releases = github::ReleaseList::configure()
|
||||
.repo_owner(Self::LEO_REPO_OWNER)
|
||||
.repo_name(Self::LEO_REPO_NAME)
|
||||
@ -42,7 +42,7 @@ impl Updater {
|
||||
}
|
||||
|
||||
/// Update `leo` to the latest release.
|
||||
pub fn update_to_latest_release(show_output: bool) -> Result<Status, self_update::errors::Error> {
|
||||
pub fn update_to_latest_release(show_output: bool) -> Result<Status, UpdaterError> {
|
||||
let status = github::Update::configure()
|
||||
.repo_owner(Self::LEO_REPO_OWNER)
|
||||
.repo_name(Self::LEO_REPO_NAME)
|
||||
@ -58,7 +58,7 @@ impl Updater {
|
||||
}
|
||||
|
||||
/// Check if there is an available update for `leo` and return the newest release.
|
||||
pub fn update_available() -> Result<Option<String>, self_update::errors::Error> {
|
||||
pub fn update_available() -> Result<String, UpdaterError> {
|
||||
let updater = github::Update::configure()
|
||||
.repo_owner(Self::LEO_REPO_OWNER)
|
||||
.repo_name(Self::LEO_REPO_NAME)
|
||||
@ -70,9 +70,9 @@ impl Updater {
|
||||
let latest_release = updater.get_latest_release()?;
|
||||
|
||||
if bump_is_greater(¤t_version, &latest_release.version)? {
|
||||
Ok(Some(latest_release.version))
|
||||
Ok(latest_release.version)
|
||||
} else {
|
||||
Ok(None)
|
||||
Err(UpdaterError::OldReleaseVersion(current_version, latest_release.version))
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ impl Updater {
|
||||
}
|
||||
} else {
|
||||
// If the auto update configuration is off, notify the user to update leo.
|
||||
if let Some(latest_version) = Self::update_available().unwrap() {
|
||||
if let Ok(latest_version) = Self::update_available() {
|
||||
let mut message = "🟢 A new version is available! Run".bold().green().to_string();
|
||||
message += &" `leo update` ".bold().white();
|
||||
message += &format!("to update to v{}.", latest_version).bold().green();
|
||||
|
@ -19,6 +19,7 @@ use leo_ast::{
|
||||
ArrayDimensions,
|
||||
Assignee,
|
||||
AssigneeAccess,
|
||||
Block,
|
||||
CircuitVariableDefinition,
|
||||
ConditionalNestedOrEndStatement,
|
||||
ConditionalStatement,
|
||||
@ -42,7 +43,7 @@ pub struct Frame {
|
||||
pub function_type: FunctionType,
|
||||
pub self_type: Option<CircuitType>,
|
||||
pub scopes: Vec<Scope>,
|
||||
pub statements: Vec<Statement>,
|
||||
pub block: Block,
|
||||
pub type_assertions: Vec<TypeAssertion>,
|
||||
pub user_defined_types: SymbolTable,
|
||||
}
|
||||
@ -77,7 +78,7 @@ impl Frame {
|
||||
function_type,
|
||||
self_type,
|
||||
scopes,
|
||||
statements: function.statements,
|
||||
block: function.block,
|
||||
type_assertions: vec![],
|
||||
user_defined_types,
|
||||
};
|
||||
@ -117,7 +118,7 @@ impl Frame {
|
||||
function_type,
|
||||
self_type: Some(self_type),
|
||||
scopes,
|
||||
statements: function.statements,
|
||||
block: function.block,
|
||||
type_assertions: Vec::new(),
|
||||
user_defined_types,
|
||||
};
|
||||
@ -230,7 +231,7 @@ impl Frame {
|
||||
/// Collects a vector of `TypeAssertion` predicates from a vector of statements.
|
||||
///
|
||||
fn parse_statements(&mut self) -> Result<(), FrameError> {
|
||||
for statement in self.statements.clone() {
|
||||
for statement in self.block.statements.clone() {
|
||||
self.parse_statement(&statement)?;
|
||||
}
|
||||
|
||||
@ -248,8 +249,8 @@ impl Frame {
|
||||
}
|
||||
Statement::Assign(assignee, expression, span) => self.parse_assign(assignee, expression, span),
|
||||
Statement::Conditional(conditional, span) => self.parse_statement_conditional(conditional, span),
|
||||
Statement::Iteration(identifier, from_to, statements, span) => {
|
||||
self.parse_iteration(identifier, from_to, statements, span)
|
||||
Statement::Iteration(identifier, from_to, block, span) => {
|
||||
self.parse_iteration(identifier, from_to, block, span)
|
||||
}
|
||||
Statement::Expression(expression, span) => self.parse_statement_expression(expression, span),
|
||||
Statement::Console(_console_call) => Ok(()), // Console function calls do not generate type assertions.
|
||||
@ -386,13 +387,13 @@ impl Frame {
|
||||
///
|
||||
/// Collects `TypeAssertion` predicates from a block of statements.
|
||||
///
|
||||
fn parse_block(&mut self, statements: &[Statement], _span: &Span) -> Result<(), FrameError> {
|
||||
fn parse_block(&mut self, block: &Block, _span: &Span) -> Result<(), FrameError> {
|
||||
// Push new scope.
|
||||
let scope = Scope::new(self.scopes.last().cloned());
|
||||
self.push_scope(scope);
|
||||
|
||||
// Parse all statements.
|
||||
for statement in statements {
|
||||
for statement in &block.statements {
|
||||
self.parse_statement(&statement)?;
|
||||
}
|
||||
|
||||
@ -420,7 +421,7 @@ impl Frame {
|
||||
self.assert_equal(boolean_type, condition, span);
|
||||
|
||||
// Parse conditional statements.
|
||||
self.parse_block(&conditional.statements, span)?;
|
||||
self.parse_block(&conditional.block, span)?;
|
||||
|
||||
// Parse conditional or end.
|
||||
if let Some(cond_or_end) = &conditional.next {
|
||||
@ -451,7 +452,7 @@ impl Frame {
|
||||
&mut self,
|
||||
identifier: &Identifier,
|
||||
from_to: &(Expression, Expression),
|
||||
statements: &[Statement],
|
||||
statements: &Block,
|
||||
span: &Span,
|
||||
) -> Result<(), FrameError> {
|
||||
// Insert variable into symbol table with u32 type.
|
||||
|
Loading…
Reference in New Issue
Block a user