Merge pull request #1826 from AleoHQ/issue-1795

Remove expression statements
This commit is contained in:
Collin Chin 2022-05-19 13:01:49 -04:00 committed by GitHub
commit ef47b04c43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 63 additions and 418 deletions

View File

@ -126,7 +126,6 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
Statement::Conditional(conditional) => Statement::Conditional(self.reduce_conditional(conditional)?),
Statement::Iteration(iteration) => Statement::Iteration(Box::new(self.reduce_iteration(iteration)?)),
Statement::Console(console) => Statement::Console(self.reduce_console(console)?),
Statement::Expression(expression) => Statement::Expression(self.reduce_expression_statement(expression)?),
Statement::Block(block) => Statement::Block(self.reduce_block(block)?),
};
@ -241,11 +240,6 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
self.reducer.reduce_console(console_function_call, function)
}
pub fn reduce_expression_statement(&mut self, expression: &ExpressionStatement) -> Result<ExpressionStatement> {
let inner_expression = self.reduce_expression(&expression.expression)?;
self.reducer.reduce_expression_statement(expression, inner_expression)
}
pub fn reduce_block(&mut self, block: &Block) -> Result<Block> {
let mut statements = vec![];
for statement in block.statements.iter() {

View File

@ -232,17 +232,6 @@ pub trait ReconstructingReducer {
})
}
fn reduce_expression_statement(
&mut self,
expression_statement: &ExpressionStatement,
expression: Expression,
) -> Result<ExpressionStatement> {
Ok(ExpressionStatement {
expression,
span: expression_statement.span,
})
}
fn reduce_block(&mut self, block: &Block, statements: Vec<Statement>) -> Result<Block> {
Ok(Block {
statements,

View File

@ -92,10 +92,6 @@ pub trait StatementVisitor<'a> {
Default::default()
}
fn visit_expression_statement(&mut self, _input: &'a ExpressionStatement) -> VisitResult {
Default::default()
}
fn visit_block(&mut self, _input: &'a Block) -> VisitResult {
Default::default()
}

View File

@ -91,7 +91,6 @@ impl<'a, V: ExpressionVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V>
Statement::Conditional(stmt) => self.visit_conditional(stmt),
Statement::Iteration(stmt) => self.visit_iteration(stmt),
Statement::Console(stmt) => self.visit_console(stmt),
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
Statement::Block(stmt) => self.visit_block(stmt),
}
}
@ -144,12 +143,6 @@ impl<'a, V: ExpressionVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V>
}
}
pub fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) {
if let VisitResult::VisitChildren = self.visitor.visit_expression_statement(input) {
self.visit_expression(&input.expression);
}
}
pub fn visit_block(&mut self, input: &'a Block) {
if let VisitResult::VisitChildren = self.visitor.visit_block(input) {
input.statements.iter().for_each(|stmt| self.visit_statement(stmt));

View File

@ -1,38 +0,0 @@
// Copyright (C) 2019-2022 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::{Expression, Node};
use leo_span::Span;
use serde::{Deserialize, Serialize};
use std::fmt;
/// An expression statement `expr;`.
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct ExpressionStatement {
/// The expression to evaluate purely for its side-effects.
pub expression: Expression,
/// The span excluding the semicolon.
pub span: Span,
}
impl fmt::Display for ExpressionStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{};", self.expression)
}
}
crate::simple_node_impl!(ExpressionStatement);

View File

@ -29,9 +29,6 @@ pub use return_statement::*;
pub mod iteration;
pub use iteration::*;
pub mod expression;
pub use expression::*;
pub mod definition;
pub use definition::*;

View File

@ -36,13 +36,20 @@ pub enum Statement {
Iteration(Box<IterationStatement>),
/// A console logging statement.
Console(ConsoleStatement),
/// An expression statement turning an expression into a statement,
/// using the expression only for its side-effects.
Expression(ExpressionStatement),
/// A block statement.
Block(Block),
}
impl Statement {
/// Returns a dummy statement made from an empty block `{}`.
pub fn dummy(span: Span) -> Self {
Self::Block(Block {
statements: Vec::new(),
span,
})
}
}
impl fmt::Display for Statement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
@ -52,7 +59,6 @@ impl fmt::Display for Statement {
Statement::Conditional(x) => x.fmt(f),
Statement::Iteration(x) => x.fmt(f),
Statement::Console(x) => x.fmt(f),
Statement::Expression(x) => x.fmt(f),
Statement::Block(x) => x.fmt(f),
}
}
@ -68,7 +74,6 @@ impl Node for Statement {
Conditional(n) => n.span(),
Iteration(n) => n.span(),
Console(n) => n.span(),
Expression(n) => n.span(),
Block(n) => n.span(),
}
}
@ -82,7 +87,6 @@ impl Node for Statement {
Conditional(n) => n.set_span(span),
Iteration(n) => n.set_span(span),
Console(n) => n.set_span(span),
Expression(n) => n.set_span(span),
Block(n) => n.set_span(span),
}
}

View File

@ -70,11 +70,11 @@ impl ParserContext<'_> {
value,
})))
} else {
// Error on `expr;` but recover as an empty block `{}`.
self.expect(&Token::Semicolon)?;
Ok(Statement::Expression(ExpressionStatement {
span: expr.span(),
expression: expr,
}))
let span = expr.span() + self.prev_token.span;
self.emit_err(ParserError::expr_stmts_disallowed(span));
Ok(Statement::dummy(span))
}
}

View File

@ -15,7 +15,7 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{tokenizer, ParserContext, SpannedToken};
use leo_ast::{Expression, ExpressionStatement, Statement, ValueExpression};
use leo_ast::Statement;
use leo_errors::{emitter::Handler, LeoError};
use leo_span::{
source_map::FileName,
@ -122,10 +122,7 @@ impl Namespace for ParseStatementNamespace {
create_session_if_not_set_then(|s| {
let tokenizer = tokenize(test, s)?;
if all_are_comments(&tokenizer) {
return Ok(yaml_or_fail(Statement::Expression(ExpressionStatement {
expression: Expression::Value(ValueExpression::String(Vec::new(), Default::default())),
span: Span::default(),
})));
return Ok(yaml_or_fail(Statement::dummy(Span::default())));
}
with_handler(tokenizer, |p| p.parse_statement()).map(yaml_or_fail)
})

View File

@ -123,11 +123,6 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
VisitResult::VisitChildren
}
fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) -> VisitResult {
self.compare_expr_type(&input.expression, None, input.span());
VisitResult::SkipChildren
}
fn visit_block(&mut self, input: &'a Block) -> VisitResult {
self.symbol_table.push_variable_scope();
// have to redo the logic here so we have scoping
@ -139,7 +134,6 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
Statement::Conditional(stmt) => self.visit_conditional(stmt),
Statement::Iteration(stmt) => self.visit_iteration(stmt),
Statement::Console(stmt) => self.visit_console(stmt),
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
Statement::Block(stmt) => self.visit_block(stmt),
};
});

View File

@ -374,4 +374,12 @@ create_messages!(
msg: "Unicode bidi override code point encountered.",
help: None,
}
/// Previously, expression statements were allowed, but not anymore.
@formatted
expr_stmts_disallowed {
args: (),
msg: "Expression statements are no longer supported.",
help: None,
}
);

View File

@ -207,7 +207,7 @@ fn set_panic_hook() {
fn main() {
set_panic_hook();
handle_error(create_session_if_not_set_then(|_| run_with_args(Opt::from_args())));
create_session_if_not_set_then(|_| handle_error(run_with_args(Opt::from_args())));
}
/// Run command with custom build arguments.

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372003]: Unknown function `my_function`\n --> compiler-test:4:5\n |\n 4 | my_function();\n | ^^^^^^^^^^^\nError [ETYC0372003]: Unknown function `my_function`\n --> compiler-test:4:5\n |\n 4 | my_function();\n | ^^^^^^^^^^^"
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> compiler-test:4:5\n |\n 4 | my_function();\n | ^^^^^^^^^^^^^^"

View File

@ -1,127 +1,5 @@
---
namespace: Parse
expectation: Pass
expectation: Fail
outputs:
- name: ""
expected_input: []
functions:
"{\"name\":\"x\",\"span\":\"{\\\"lo\\\":11,\\\"hi\\\":12}\"}":
identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":11,\\\"hi\\\":12}\"}"
input:
- Variable:
identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":22,\\\"hi\\\":23}\"}"
mode: Constant
type_:
IntegerType: U32
span:
lo: 22
hi: 23
output:
IntegerType: U8
core_mapping: ~
block:
statements:
- Conditional:
condition:
Binary:
left:
Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":45,\\\"hi\\\":46}\"}"
right:
Value:
Integer:
- U32
- "5"
- span:
lo: 49
hi: 53
op: Lt
span:
lo: 45
hi: 53
block:
statements:
- Expression:
expression:
Call:
function:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":64,\\\"hi\\\":65}\"}"
arguments:
- Binary:
left:
Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":66,\\\"hi\\\":67}\"}"
right:
Value:
Integer:
- U32
- "1"
- span:
lo: 68
hi: 72
op: Add
span:
lo: 66
hi: 72
span:
lo: 64
hi: 73
span:
lo: 64
hi: 73
span:
lo: 54
hi: 80
next: ~
span:
lo: 42
hi: 80
span:
lo: 36
hi: 82
span:
lo: 2
hi: 82
"{\"name\":\"main\",\"span\":\"{\\\"lo\\\":93,\\\"hi\\\":97}\"}":
identifier: "{\"name\":\"main\",\"span\":\"{\\\"lo\\\":93,\\\"hi\\\":97}\"}"
input:
- Variable:
identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":98,\\\"hi\\\":99}\"}"
mode: Private
type_: Boolean
span:
lo: 98
hi: 99
output: Boolean
core_mapping: ~
block:
statements:
- Expression:
expression:
Call:
function:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":121,\\\"hi\\\":122}\"}"
arguments:
- Value:
Integer:
- U32
- "1"
- span:
lo: 123
hi: 127
span:
lo: 121
hi: 128
span:
lo: 121
hi: 128
- Return:
expression:
Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":141,\\\"hi\\\":142}\"}"
span:
lo: 134
hi: 142
span:
lo: 115
hi: 145
span:
lo: 84
hi: 145
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:5:9\n |\n 5 | x(y+1u32);\n | ^^^^^^^^^^\nError [EPAR0370043]: Expression statements are no longer supported.\n --> test:10:5\n |\n 10 | x(1u32);\n | ^^^^^^^^"

View File

@ -1,71 +1,5 @@
---
namespace: Parse
expectation: Pass
expectation: Fail
outputs:
- name: ""
expected_input: []
functions:
"{\"name\":\"inf\",\"span\":\"{\\\"lo\\\":11,\\\"hi\\\":14}\"}":
identifier: "{\"name\":\"inf\",\"span\":\"{\\\"lo\\\":11,\\\"hi\\\":14}\"}"
input: []
output:
IntegerType: U8
core_mapping: ~
block:
statements:
- Expression:
expression:
Call:
function:
Identifier: "{\"name\":\"inf\",\"span\":\"{\\\"lo\\\":29,\\\"hi\\\":32}\"}"
arguments: []
span:
lo: 29
hi: 34
span:
lo: 29
hi: 34
span:
lo: 23
hi: 37
span:
lo: 2
hi: 37
"{\"name\":\"main\",\"span\":\"{\\\"lo\\\":48,\\\"hi\\\":52}\"}":
identifier: "{\"name\":\"main\",\"span\":\"{\\\"lo\\\":48,\\\"hi\\\":52}\"}"
input:
- Variable:
identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":53,\\\"hi\\\":54}\"}"
mode: Private
type_: Boolean
span:
lo: 53
hi: 54
output: Boolean
core_mapping: ~
block:
statements:
- Expression:
expression:
Call:
function:
Identifier: "{\"name\":\"inf\",\"span\":\"{\\\"lo\\\":76,\\\"hi\\\":79}\"}"
arguments: []
span:
lo: 76
hi: 81
span:
lo: 76
hi: 81
- Return:
expression:
Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":94,\\\"hi\\\":95}\"}"
span:
lo: 87
hi: 95
span:
lo: 70
hi: 98
span:
lo: 39
hi: 98
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:4:5\n |\n 4 | inf();\n | ^^^^^^\nError [EPAR0370043]: Expression statements are no longer supported.\n --> test:8:5\n |\n 8 | inf();\n | ^^^^^^"

View File

@ -125,12 +125,6 @@ outputs:
hi: 6
block:
statements:
- Expression:
expression:
Identifier: "{\"name\":\"expr\",\"span\":\"{\\\"lo\\\":9,\\\"hi\\\":13}\"}"
span:
lo: 9
hi: 13
- Return:
expression:
Value:
@ -138,15 +132,15 @@ outputs:
- U8
- "0"
- span:
lo: 22
hi: 25
lo: 16
hi: 19
span:
lo: 15
hi: 25
lo: 9
hi: 19
span:
lo: 7
hi: 28
hi: 22
next: ~
span:
lo: 0
hi: 28
hi: 22

View File

@ -1,36 +1,7 @@
---
namespace: ParseStatement
expectation: Pass
expectation: Fail
outputs:
- Expression:
expression:
Identifier: "{\"name\":\"expr\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":4}\"}"
span:
lo: 0
hi: 4
- Expression:
expression:
Binary:
left:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
right:
Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":2,\\\"hi\\\":3}\"}"
op: Add
span:
lo: 0
hi: 3
span:
lo: 0
hi: 3
- Expression:
expression:
Call:
function:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
arguments: []
span:
lo: 0
hi: 3
span:
lo: 0
hi: 3
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | expr;\n | ^^^^^"
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x+y;\n | ^^^^"
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x();\n | ^^^^"

View File

@ -40,7 +40,7 @@ outputs:
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a true b;\n | ^"
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a false b;\n | ^"
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = a 0 b;\n | ^"
- "did not consume all input: '=' @ 1:3-4\n'b' @ 1:4-5\n';' @ 1:5-6\n"
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x;=b;\n | ^^"
- "Error [EPAR0370009]: unexpected string: expected 'int or ident', got '='\n --> test:1:3\n |\n 1 | x.=b;\n | ^"
- "Error [EPAR0370005]: expected ; -- got ','\n --> test:1:2\n |\n 1 | x,=b; // 43\n | ^"
- "Error [EPAR0370005]: expected ; -- got '['\n --> test:1:2\n |\n 1 | x[=b;\n | ^"
@ -57,3 +57,8 @@ outputs:
- "Error [EPAR0370009]: unexpected string: expected 'expression', got '='\n --> test:1:4\n |\n 1 | x<==b;\n | ^"
- "Error [EPAR0370005]: expected ; -- got '..'\n --> test:1:2\n |\n 1 | x..=b;\n | ^^"
- "Error [EPAR0370021]: Expected more characters to lex but found none."
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x==b;\n | ^^^^^"
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x!=b;\n | ^^^^^"
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x>=b;\n | ^^^^^"
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x<=b;\n | ^^^^^"
- "Error [EPAR0370043]: Expression statements are no longer supported.\n --> test:1:1\n |\n 1 | x>=b;\n | ^^^^^"

View File

@ -176,76 +176,6 @@ outputs:
span:
lo: 0
hi: 4
- Expression:
expression:
Binary:
left:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
right:
Identifier: "{\"name\":\"b\",\"span\":\"{\\\"lo\\\":3,\\\"hi\\\":4}\"}"
op: Eq
span:
lo: 0
hi: 4
span:
lo: 0
hi: 4
- Expression:
expression:
Binary:
left:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
right:
Identifier: "{\"name\":\"b\",\"span\":\"{\\\"lo\\\":3,\\\"hi\\\":4}\"}"
op: Ne
span:
lo: 0
hi: 4
span:
lo: 0
hi: 4
- Expression:
expression:
Binary:
left:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
right:
Identifier: "{\"name\":\"b\",\"span\":\"{\\\"lo\\\":3,\\\"hi\\\":4}\"}"
op: Ge
span:
lo: 0
hi: 4
span:
lo: 0
hi: 4
- Expression:
expression:
Binary:
left:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
right:
Identifier: "{\"name\":\"b\",\"span\":\"{\\\"lo\\\":3,\\\"hi\\\":4}\"}"
op: Le
span:
lo: 0
hi: 4
span:
lo: 0
hi: 4
- Expression:
expression:
Binary:
left:
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":1}\"}"
right:
Identifier: "{\"name\":\"b\",\"span\":\"{\\\"lo\\\":3,\\\"hi\\\":4}\"}"
op: Ge
span:
lo: 0
hi: 4
span:
lo: 0
hi: 4
- Assign:
operation: Assign
assignee:

View File

@ -1,6 +1,6 @@
/*
namespace: Parse
expectation: Pass
expectation: Fail
*/
function x(constant y: u32) -> u8 {
@ -12,4 +12,4 @@ function x(constant y: u32) -> u8 {
function main(y: bool) -> bool {
x(1u32);
return y;
}
}

View File

@ -1,6 +1,6 @@
/*
namespace: Parse
expectation: Pass
expectation: Fail
*/
function inf() -> u8 {
@ -10,4 +10,4 @@ function inf() -> u8 {
function main(y: bool) -> bool {
inf();
return y;
}
}

View File

@ -16,6 +16,5 @@ if (x) {} else {}
if x+y {} else if x+z {} else {}
if x+y {
expr;
return 0u8;
}
}

View File

@ -1,10 +1,10 @@
/*
namespace: ParseStatement
expectation: Pass
expectation: Fail
*/
expr;
x+y;
x();
x();

View File

@ -113,3 +113,13 @@ x<==b;
x..=b;
x&=b;
x==b;
x!=b;
x>=b;
x<=b;
x>=b;

View File

@ -20,16 +20,6 @@ let x: u8 = a > b;
x_=b;
x==b;
x!=b;
x>=b;
x<=b;
x>=b;
xconsole=b;
xconst=b;