mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 11:12:48 +03:00
Add support for expression statements in compiler passes
This commit is contained in:
parent
a7795b72db
commit
40ff47882f
@ -276,6 +276,7 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Fix to allow zero or multiple outputs.
|
||||||
fn visit_call(&mut self, input: &'a CallExpression) -> (String, String) {
|
fn visit_call(&mut self, input: &'a CallExpression) -> (String, String) {
|
||||||
let mut call_instruction = match &input.external {
|
let mut call_instruction = match &input.external {
|
||||||
Some(external) => format!(" call {external}.aleo/{} ", input.function),
|
Some(external) => format!(" call {external}.aleo/{} ", input.function),
|
||||||
|
@ -18,8 +18,8 @@ use crate::CodeGenerator;
|
|||||||
|
|
||||||
use leo_ast::{
|
use leo_ast::{
|
||||||
AssignStatement, Block, ConditionalStatement, ConsoleFunction, ConsoleStatement, DecrementStatement,
|
AssignStatement, Block, ConditionalStatement, ConsoleFunction, ConsoleStatement, DecrementStatement,
|
||||||
DefinitionStatement, Expression, FinalizeStatement, IncrementStatement, IterationStatement, Mode, Output,
|
DefinitionStatement, Expression, ExpressionStatement, FinalizeStatement, IncrementStatement, IterationStatement,
|
||||||
ReturnStatement, Statement,
|
Mode, Output, ReturnStatement, Statement,
|
||||||
};
|
};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
@ -34,6 +34,7 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
Statement::Console(stmt) => self.visit_console(stmt),
|
Statement::Console(stmt) => self.visit_console(stmt),
|
||||||
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
||||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||||
|
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||||
Statement::Finalize(stmt) => self.visit_finalize(stmt),
|
Statement::Finalize(stmt) => self.visit_finalize(stmt),
|
||||||
Statement::Increment(stmt) => self.visit_increment(stmt),
|
Statement::Increment(stmt) => self.visit_increment(stmt),
|
||||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||||
@ -110,6 +111,13 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
unreachable!("DefinitionStatement's should not exist in SSA form.")
|
unreachable!("DefinitionStatement's should not exist in SSA form.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) -> String {
|
||||||
|
match input.expression {
|
||||||
|
Expression::Call(_) => self.visit_expression(&input.expression).1,
|
||||||
|
_ => unreachable!("ExpressionStatement's can only contain CallExpression's."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_increment(&mut self, input: &'a IncrementStatement) -> String {
|
fn visit_increment(&mut self, input: &'a IncrementStatement) -> String {
|
||||||
let (index, mut instructions) = self.visit_expression(&input.index);
|
let (index, mut instructions) = self.visit_expression(&input.index);
|
||||||
let (amount, amount_instructions) = self.visit_expression(&input.amount);
|
let (amount, amount_instructions) = self.visit_expression(&input.amount);
|
||||||
|
@ -18,8 +18,8 @@ use crate::{RenameTable, StaticSingleAssigner};
|
|||||||
|
|
||||||
use leo_ast::{
|
use leo_ast::{
|
||||||
AssignStatement, Block, ConditionalStatement, ConsoleFunction, ConsoleStatement, DecrementStatement,
|
AssignStatement, Block, ConditionalStatement, ConsoleFunction, ConsoleStatement, DecrementStatement,
|
||||||
DefinitionStatement, Expression, ExpressionConsumer, FinalizeStatement, Identifier, IncrementStatement,
|
DefinitionStatement, Expression, ExpressionConsumer, ExpressionStatement, FinalizeStatement, Identifier,
|
||||||
IterationStatement, ReturnStatement, Statement, StatementConsumer, TernaryExpression,
|
IncrementStatement, IterationStatement, ReturnStatement, Statement, StatementConsumer, TernaryExpression,
|
||||||
};
|
};
|
||||||
use leo_span::Symbol;
|
use leo_span::Symbol;
|
||||||
|
|
||||||
@ -234,6 +234,20 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
|||||||
statements
|
statements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consumes the expressions associated with `ExpressionStatement`, returning the simplified `ExpressionStatement`.
|
||||||
|
fn consume_expression_statement(&mut self, input: ExpressionStatement) -> Self::Output {
|
||||||
|
// Process the expression associated with the `ExpressionStatement`.
|
||||||
|
let (expression, mut statements) = self.consume_expression(input.expression);
|
||||||
|
|
||||||
|
// Add the `ExpressionStatement` to the list of produced statements.
|
||||||
|
statements.push(Statement::Expression(ExpressionStatement {
|
||||||
|
expression,
|
||||||
|
span: input.span,
|
||||||
|
}));
|
||||||
|
|
||||||
|
statements
|
||||||
|
}
|
||||||
|
|
||||||
/// Consumes the expressions associated with the `FinalizeStatement`, returning the simplified `FinalizeStatement`.
|
/// Consumes the expressions associated with the `FinalizeStatement`, returning the simplified `FinalizeStatement`.
|
||||||
fn consume_finalize(&mut self, input: FinalizeStatement) -> Self::Output {
|
fn consume_finalize(&mut self, input: FinalizeStatement) -> Self::Output {
|
||||||
let mut statements = Vec::new();
|
let mut statements = Vec::new();
|
||||||
|
@ -34,6 +34,7 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
Statement::Console(stmt) => self.visit_console(stmt),
|
Statement::Console(stmt) => self.visit_console(stmt),
|
||||||
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
||||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||||
|
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||||
Statement::Finalize(stmt) => self.visit_finalize(stmt),
|
Statement::Finalize(stmt) => self.visit_finalize(stmt),
|
||||||
Statement::Increment(stmt) => self.visit_increment(stmt),
|
Statement::Increment(stmt) => self.visit_increment(stmt),
|
||||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||||
@ -224,6 +225,19 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) {
|
||||||
|
// Expression statements can only be function calls.
|
||||||
|
if !matches!(input.expression, Expression::Call(_)) {
|
||||||
|
self.emit_err(TypeCheckerError::expression_statement_must_be_function_call(
|
||||||
|
input.span(),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
// Check the expression.
|
||||||
|
// TODO: Should the output type be restricted to unit types?
|
||||||
|
self.visit_expression(&input.expression, &None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_finalize(&mut self, input: &'a FinalizeStatement) {
|
fn visit_finalize(&mut self, input: &'a FinalizeStatement) {
|
||||||
if self.is_finalize {
|
if self.is_finalize {
|
||||||
self.emit_err(TypeCheckerError::finalize_in_finalize(input.span()));
|
self.emit_err(TypeCheckerError::finalize_in_finalize(input.span()));
|
||||||
|
@ -512,4 +512,11 @@ create_messages!(
|
|||||||
msg: format!("A finalize statement cannot contain tuple expressions."),
|
msg: format!("A finalize statement cannot contain tuple expressions."),
|
||||||
help: None,
|
help: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@formatted
|
||||||
|
expression_statement_must_be_function_call {
|
||||||
|
args: (),
|
||||||
|
msg: format!("An expression statement must be a function call."),
|
||||||
|
help: None,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user