mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-11 04:49:15 +03:00
Remove Increment, Decrement statements from AST
This commit is contained in:
parent
4ee06d4342
commit
4f27c92f15
@ -75,10 +75,8 @@ pub trait StatementConsumer {
|
||||
Statement::Block(stmt) => self.consume_block(stmt),
|
||||
Statement::Conditional(stmt) => self.consume_conditional(stmt),
|
||||
Statement::Console(stmt) => self.consume_console(stmt),
|
||||
Statement::Decrement(stmt) => self.consume_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.consume_definition(stmt),
|
||||
Statement::Expression(stmt) => self.consume_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.consume_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.consume_iteration(*stmt),
|
||||
Statement::Return(stmt) => self.consume_return(stmt),
|
||||
}
|
||||
@ -94,14 +92,10 @@ pub trait StatementConsumer {
|
||||
|
||||
fn consume_console(&mut self, input: ConsoleStatement) -> Self::Output;
|
||||
|
||||
fn consume_decrement(&mut self, input: DecrementStatement) -> Self::Output;
|
||||
|
||||
fn consume_definition(&mut self, input: DefinitionStatement) -> Self::Output;
|
||||
|
||||
fn consume_expression_statement(&mut self, input: ExpressionStatement) -> Self::Output;
|
||||
|
||||
fn consume_increment(&mut self, input: IncrementStatement) -> Self::Output;
|
||||
|
||||
fn consume_iteration(&mut self, input: IterationStatement) -> Self::Output;
|
||||
|
||||
fn consume_return(&mut self, input: ReturnStatement) -> Self::Output;
|
||||
|
@ -157,10 +157,8 @@ pub trait StatementReconstructor: ExpressionReconstructor {
|
||||
}
|
||||
Statement::Conditional(stmt) => self.reconstruct_conditional(stmt),
|
||||
Statement::Console(stmt) => self.reconstruct_console(stmt),
|
||||
Statement::Decrement(stmt) => self.reconstruct_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.reconstruct_definition(stmt),
|
||||
Statement::Expression(stmt) => self.reconstruct_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.reconstruct_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.reconstruct_iteration(*stmt),
|
||||
Statement::Return(stmt) => self.reconstruct_return(stmt),
|
||||
}
|
||||
@ -239,19 +237,6 @@ pub trait StatementReconstructor: ExpressionReconstructor {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Reconstructor should visit this.
|
||||
fn reconstruct_decrement(&mut self, input: DecrementStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
(
|
||||
Statement::Decrement(DecrementStatement {
|
||||
mapping: input.mapping,
|
||||
amount: input.amount,
|
||||
index: input.index,
|
||||
span: input.span,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn reconstruct_definition(&mut self, input: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
(
|
||||
Statement::Definition(DefinitionStatement {
|
||||
@ -275,19 +260,6 @@ pub trait StatementReconstructor: ExpressionReconstructor {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Reconstructor should visit this.
|
||||
fn reconstruct_increment(&mut self, input: IncrementStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
(
|
||||
Statement::Increment(IncrementStatement {
|
||||
mapping: input.mapping,
|
||||
index: input.index,
|
||||
amount: input.amount,
|
||||
span: input.span,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn reconstruct_iteration(&mut self, input: IterationStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
(
|
||||
Statement::Iteration(Box::new(IterationStatement {
|
||||
|
@ -122,10 +122,8 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
||||
Statement::Block(stmt) => self.visit_block(stmt),
|
||||
Statement::Conditional(stmt) => self.visit_conditional(stmt),
|
||||
Statement::Console(stmt) => self.visit_console(stmt),
|
||||
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.visit_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||
Statement::Return(stmt) => self.visit_return(stmt),
|
||||
}
|
||||
@ -173,12 +171,6 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
||||
};
|
||||
}
|
||||
|
||||
fn visit_decrement(&mut self, input: &'a DecrementStatement) {
|
||||
self.visit_expression(&input.amount, &Default::default());
|
||||
self.visit_expression(&input.index, &Default::default());
|
||||
self.visit_identifier(&input.mapping, &Default::default());
|
||||
}
|
||||
|
||||
fn visit_definition(&mut self, input: &'a DefinitionStatement) {
|
||||
self.visit_expression(&input.value, &Default::default());
|
||||
}
|
||||
@ -187,12 +179,6 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
||||
self.visit_expression(&input.expression, &Default::default());
|
||||
}
|
||||
|
||||
fn visit_increment(&mut self, input: &'a IncrementStatement) {
|
||||
self.visit_expression(&input.amount, &Default::default());
|
||||
self.visit_expression(&input.index, &Default::default());
|
||||
self.visit_identifier(&input.mapping, &Default::default());
|
||||
}
|
||||
|
||||
fn visit_iteration(&mut self, input: &'a IterationStatement) {
|
||||
self.visit_expression(&input.start, &Default::default());
|
||||
self.visit_expression(&input.stop, &Default::default());
|
||||
|
@ -1,43 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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, Identifier, Node};
|
||||
|
||||
use leo_span::Span;
|
||||
|
||||
use core::fmt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A decrement statement `decrement(foo, bar, 1);`.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
pub struct DecrementStatement {
|
||||
/// The mapping to be modified.
|
||||
pub mapping: Identifier,
|
||||
/// The index of the element to be decremented.
|
||||
pub index: Expression,
|
||||
/// The amount to decrement the element by.
|
||||
pub amount: Expression,
|
||||
/// The span of `decrement(foo, bar, 1)` excluding the semicolon.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for DecrementStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "decrement({}, {}, {});", self.mapping, self.index, self.amount)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(DecrementStatement);
|
@ -1,43 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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, Identifier, Node};
|
||||
|
||||
use leo_span::Span;
|
||||
|
||||
use core::fmt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An increment statement `increment(foo, bar, 1);`.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
pub struct IncrementStatement {
|
||||
/// The mapping to be modified.
|
||||
pub mapping: Identifier,
|
||||
/// The index of the element to be incremented.
|
||||
pub index: Expression,
|
||||
/// The amount to increment the element by.
|
||||
pub amount: Expression,
|
||||
/// The span of `increment(foo, bar, 1)` excluding the semicolon.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for IncrementStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "increment({}, {}, {});", self.mapping, self.index, self.amount)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(IncrementStatement);
|
@ -29,18 +29,12 @@ pub use conditional::*;
|
||||
pub mod console;
|
||||
pub use console::*;
|
||||
|
||||
pub mod decrement;
|
||||
pub use decrement::*;
|
||||
|
||||
pub mod definition;
|
||||
pub use definition::*;
|
||||
|
||||
pub mod expression;
|
||||
pub use expression::*;
|
||||
|
||||
pub mod increment;
|
||||
pub use increment::*;
|
||||
|
||||
pub mod iteration;
|
||||
pub use iteration::*;
|
||||
|
||||
@ -67,14 +61,10 @@ pub enum Statement {
|
||||
Conditional(ConditionalStatement),
|
||||
/// A console logging statement.
|
||||
Console(ConsoleStatement),
|
||||
/// A decrement statement.
|
||||
Decrement(DecrementStatement),
|
||||
/// A binding or set of bindings / variables to declare.
|
||||
Definition(DefinitionStatement),
|
||||
/// An expression statement
|
||||
Expression(ExpressionStatement),
|
||||
/// An increment statement.
|
||||
Increment(IncrementStatement),
|
||||
/// A `for` statement.
|
||||
Iteration(Box<IterationStatement>),
|
||||
/// A return statement `return expr;`.
|
||||
@ -96,10 +86,8 @@ impl fmt::Display for Statement {
|
||||
Statement::Block(x) => x.fmt(f),
|
||||
Statement::Conditional(x) => x.fmt(f),
|
||||
Statement::Console(x) => x.fmt(f),
|
||||
Statement::Decrement(x) => x.fmt(f),
|
||||
Statement::Definition(x) => x.fmt(f),
|
||||
Statement::Expression(x) => x.fmt(f),
|
||||
Statement::Increment(x) => x.fmt(f),
|
||||
Statement::Iteration(x) => x.fmt(f),
|
||||
Statement::Return(x) => x.fmt(f),
|
||||
}
|
||||
@ -115,10 +103,8 @@ impl Node for Statement {
|
||||
Block(n) => n.span(),
|
||||
Conditional(n) => n.span(),
|
||||
Console(n) => n.span(),
|
||||
Decrement(n) => n.span(),
|
||||
Definition(n) => n.span(),
|
||||
Expression(n) => n.span(),
|
||||
Increment(n) => n.span(),
|
||||
Iteration(n) => n.span(),
|
||||
Return(n) => n.span(),
|
||||
}
|
||||
@ -132,10 +118,8 @@ impl Node for Statement {
|
||||
Block(n) => n.set_span(span),
|
||||
Conditional(n) => n.set_span(span),
|
||||
Console(n) => n.set_span(span),
|
||||
Decrement(n) => n.set_span(span),
|
||||
Definition(n) => n.set_span(span),
|
||||
Expression(n) => n.set_span(span),
|
||||
Increment(n) => n.set_span(span),
|
||||
Iteration(n) => n.set_span(span),
|
||||
Return(n) => n.set_span(span),
|
||||
}
|
||||
|
@ -23,11 +23,9 @@ use leo_ast::{
|
||||
Block,
|
||||
ConditionalStatement,
|
||||
ConsoleStatement,
|
||||
DecrementStatement,
|
||||
DefinitionStatement,
|
||||
Expression,
|
||||
ExpressionStatement,
|
||||
IncrementStatement,
|
||||
IterationStatement,
|
||||
Mode,
|
||||
Output,
|
||||
@ -46,10 +44,8 @@ impl<'a> CodeGenerator<'a> {
|
||||
Statement::Block(stmt) => self.visit_block(stmt),
|
||||
Statement::Conditional(stmt) => self.visit_conditional(stmt),
|
||||
Statement::Console(stmt) => self.visit_console(stmt),
|
||||
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.visit_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||
Statement::Return(stmt) => self.visit_return(stmt),
|
||||
}
|
||||
@ -170,24 +166,6 @@ impl<'a> CodeGenerator<'a> {
|
||||
self.visit_expression(&input.expression).1
|
||||
}
|
||||
|
||||
fn visit_increment(&mut self, input: &'a IncrementStatement) -> String {
|
||||
let (index, mut instructions) = self.visit_expression(&input.index);
|
||||
let (amount, amount_instructions) = self.visit_expression(&input.amount);
|
||||
instructions.push_str(&amount_instructions);
|
||||
instructions.push_str(&format!(" increment {}[{index}] by {amount};\n", input.mapping));
|
||||
|
||||
instructions
|
||||
}
|
||||
|
||||
fn visit_decrement(&mut self, input: &'a DecrementStatement) -> String {
|
||||
let (index, mut instructions) = self.visit_expression(&input.index);
|
||||
let (amount, amount_instructions) = self.visit_expression(&input.amount);
|
||||
instructions.push_str(&amount_instructions);
|
||||
instructions.push_str(&format!(" decrement {}[{index}] by {amount};\n", input.mapping));
|
||||
|
||||
instructions
|
||||
}
|
||||
|
||||
fn visit_assign(&mut self, input: &'a AssignStatement) -> String {
|
||||
match (&input.place, &input.value) {
|
||||
(Expression::Identifier(identifier), _) => {
|
||||
|
@ -23,12 +23,10 @@ use leo_ast::{
|
||||
Block,
|
||||
ConditionalStatement,
|
||||
ConsoleStatement,
|
||||
DecrementStatement,
|
||||
DefinitionStatement,
|
||||
Expression,
|
||||
ExpressionReconstructor,
|
||||
ExpressionStatement,
|
||||
IncrementStatement,
|
||||
IterationStatement,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
@ -125,24 +123,6 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
unreachable!("`ConsoleStatement`s should not be in the AST at this phase of compilation.")
|
||||
}
|
||||
|
||||
fn reconstruct_decrement(&mut self, input: DecrementStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
// Set the `is_necessary` flag.
|
||||
self.is_necessary = true;
|
||||
|
||||
// Visit the statement.
|
||||
let statement = Statement::Decrement(DecrementStatement {
|
||||
mapping: input.mapping,
|
||||
index: self.reconstruct_expression(input.index).0,
|
||||
amount: self.reconstruct_expression(input.amount).0,
|
||||
span: input.span,
|
||||
});
|
||||
|
||||
// Unset the `is_necessary` flag.
|
||||
self.is_necessary = false;
|
||||
|
||||
(statement, Default::default())
|
||||
}
|
||||
|
||||
/// Static single assignment replaces definition statements with assignment statements.
|
||||
fn reconstruct_definition(&mut self, _: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
unreachable!("`DefinitionStatement`s should not exist in the AST at this phase of compilation.")
|
||||
@ -174,24 +154,6 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
}
|
||||
}
|
||||
|
||||
fn reconstruct_increment(&mut self, input: IncrementStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
// Set the `is_necessary` flag.
|
||||
self.is_necessary = true;
|
||||
|
||||
// Visit the statement.
|
||||
let statement = Statement::Increment(IncrementStatement {
|
||||
mapping: input.mapping,
|
||||
index: self.reconstruct_expression(input.index).0,
|
||||
amount: self.reconstruct_expression(input.amount).0,
|
||||
span: input.span,
|
||||
});
|
||||
|
||||
// Unset the `is_necessary` flag.
|
||||
self.is_necessary = false;
|
||||
|
||||
(statement, Default::default())
|
||||
}
|
||||
|
||||
/// Loop unrolling unrolls and removes iteration statements from the program.
|
||||
fn reconstruct_iteration(&mut self, _: IterationStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
unreachable!("`IterationStatement`s should not be in the AST at this phase of compilation.");
|
||||
|
@ -24,13 +24,11 @@ use leo_ast::{
|
||||
CallExpression,
|
||||
ConditionalStatement,
|
||||
ConsoleStatement,
|
||||
DecrementStatement,
|
||||
DefinitionStatement,
|
||||
Expression,
|
||||
ExpressionConsumer,
|
||||
ExpressionStatement,
|
||||
Identifier,
|
||||
IncrementStatement,
|
||||
IterationStatement,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
@ -200,25 +198,6 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
unreachable!("Parsing guarantees that console statements are not present in the program.")
|
||||
}
|
||||
|
||||
/// Consumes the expressions associated with the `DecrementStatement`, returning the simplified `DecrementStatement`.
|
||||
fn consume_decrement(&mut self, input: DecrementStatement) -> Self::Output {
|
||||
// First consume the expression associated with the amount.
|
||||
let (amount, mut statements) = self.consume_expression(input.amount);
|
||||
|
||||
// Then, consume the expression associated with the index.
|
||||
let (index, index_statements) = self.consume_expression(input.index);
|
||||
statements.extend(index_statements);
|
||||
|
||||
statements.push(Statement::Decrement(DecrementStatement {
|
||||
mapping: input.mapping,
|
||||
index,
|
||||
amount,
|
||||
span: input.span,
|
||||
}));
|
||||
|
||||
statements
|
||||
}
|
||||
|
||||
/// Consumes the `DefinitionStatement` into an `AssignStatement`, renaming the left-hand-side as appropriate.
|
||||
fn consume_definition(&mut self, definition: DefinitionStatement) -> Self::Output {
|
||||
// First consume the right-hand-side of the definition.
|
||||
@ -299,25 +278,6 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
statements
|
||||
}
|
||||
|
||||
/// Consumes the expressions associated with the `IncrementStatement`, returning a simplified `IncrementStatement`.
|
||||
fn consume_increment(&mut self, input: IncrementStatement) -> Self::Output {
|
||||
// First consume the expression associated with the amount.
|
||||
let (amount, mut statements) = self.consume_expression(input.amount);
|
||||
|
||||
// Then, consume the expression associated with the index.
|
||||
let (index, index_statements) = self.consume_expression(input.index);
|
||||
statements.extend(index_statements);
|
||||
|
||||
statements.push(Statement::Increment(IncrementStatement {
|
||||
mapping: input.mapping,
|
||||
index,
|
||||
amount,
|
||||
span: input.span,
|
||||
}));
|
||||
|
||||
statements
|
||||
}
|
||||
|
||||
// TODO: Error message
|
||||
fn consume_iteration(&mut self, _input: IterationStatement) -> Self::Output {
|
||||
unreachable!("`IterationStatement`s should not be in the AST at this phase of compilation.");
|
||||
|
@ -35,10 +35,8 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
Statement::Block(stmt) => self.visit_block(stmt),
|
||||
Statement::Conditional(stmt) => self.visit_conditional(stmt),
|
||||
Statement::Console(stmt) => self.visit_console(stmt),
|
||||
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.visit_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||
Statement::Return(stmt) => self.visit_return(stmt),
|
||||
}
|
||||
@ -152,35 +150,6 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
unreachable!("Parsing guarantees that console statements are not present in the AST.");
|
||||
}
|
||||
|
||||
fn visit_decrement(&mut self, input: &'a DecrementStatement) {
|
||||
if !self.is_finalize {
|
||||
self.emit_err(TypeCheckerError::invalid_operation_outside_finalize("decrement", input.span()));
|
||||
}
|
||||
|
||||
// Assert that the first operand is a mapping.
|
||||
let mapping_type = self.visit_identifier(&input.mapping, &None);
|
||||
self.assert_mapping_type(&mapping_type, input.span());
|
||||
|
||||
match mapping_type {
|
||||
None => self.emit_err(TypeCheckerError::could_not_determine_type(input.mapping, input.mapping.span)),
|
||||
Some(Type::Mapping(mapping_type)) => {
|
||||
// Check that the index matches the key type of the mapping.
|
||||
let index_type = self.visit_expression(&input.index, &None);
|
||||
self.assert_type(&index_type, &mapping_type.key, input.index.span());
|
||||
|
||||
// Check that the amount matches the value type of the mapping.
|
||||
let amount_type = self.visit_expression(&input.amount, &None);
|
||||
self.assert_type(&amount_type, &mapping_type.value, input.amount.span());
|
||||
|
||||
// Check that the amount type is incrementable.
|
||||
self.assert_field_group_scalar_int_type(&amount_type, input.amount.span());
|
||||
}
|
||||
Some(mapping_type) => {
|
||||
self.emit_err(TypeCheckerError::expected_one_type_of("mapping", mapping_type, input.mapping.span))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_definition(&mut self, input: &'a DefinitionStatement) {
|
||||
let declaration =
|
||||
if input.declaration_type == DeclarationType::Const { VariableType::Const } else { VariableType::Mut };
|
||||
@ -260,35 +229,6 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_increment(&mut self, input: &'a IncrementStatement) {
|
||||
if !self.is_finalize {
|
||||
self.emit_err(TypeCheckerError::invalid_operation_outside_finalize("increment", input.span()));
|
||||
}
|
||||
|
||||
// Assert that the first operand is a mapping.
|
||||
let mapping_type = self.visit_identifier(&input.mapping, &None);
|
||||
self.assert_mapping_type(&mapping_type, input.span());
|
||||
|
||||
match mapping_type {
|
||||
None => self.emit_err(TypeCheckerError::could_not_determine_type(input.mapping, input.mapping.span)),
|
||||
Some(Type::Mapping(mapping_type)) => {
|
||||
// Check that the index matches the key type of the mapping.
|
||||
let index_type = self.visit_expression(&input.index, &None);
|
||||
self.assert_type(&index_type, &mapping_type.key, input.index.span());
|
||||
|
||||
// Check that the amount matches the value type of the mapping.
|
||||
let amount_type = self.visit_expression(&input.amount, &None);
|
||||
self.assert_type(&amount_type, &mapping_type.value, input.amount.span());
|
||||
|
||||
// Check that the amount type is incrementable.
|
||||
self.assert_field_group_scalar_int_type(&amount_type, input.amount.span());
|
||||
}
|
||||
Some(mapping_type) => {
|
||||
self.emit_err(TypeCheckerError::expected_one_type_of("mapping", mapping_type, input.mapping.span))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_iteration(&mut self, input: &'a IterationStatement) {
|
||||
let iter_type = &Some(input.type_.clone());
|
||||
self.assert_int_type(iter_type, input.variable.span);
|
||||
|
Loading…
Reference in New Issue
Block a user