mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 18:52:58 +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) {
|
||||
let mut call_instruction = match &input.external {
|
||||
Some(external) => format!(" call {external}.aleo/{} ", input.function),
|
||||
|
@ -18,8 +18,8 @@ use crate::CodeGenerator;
|
||||
|
||||
use leo_ast::{
|
||||
AssignStatement, Block, ConditionalStatement, ConsoleFunction, ConsoleStatement, DecrementStatement,
|
||||
DefinitionStatement, Expression, FinalizeStatement, IncrementStatement, IterationStatement, Mode, Output,
|
||||
ReturnStatement, Statement,
|
||||
DefinitionStatement, Expression, ExpressionStatement, FinalizeStatement, IncrementStatement, IterationStatement,
|
||||
Mode, Output, ReturnStatement, Statement,
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
@ -34,6 +34,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
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::Finalize(stmt) => self.visit_finalize(stmt),
|
||||
Statement::Increment(stmt) => self.visit_increment(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.")
|
||||
}
|
||||
|
||||
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 {
|
||||
let (index, mut instructions) = self.visit_expression(&input.index);
|
||||
let (amount, amount_instructions) = self.visit_expression(&input.amount);
|
||||
|
@ -18,8 +18,8 @@ use crate::{RenameTable, StaticSingleAssigner};
|
||||
|
||||
use leo_ast::{
|
||||
AssignStatement, Block, ConditionalStatement, ConsoleFunction, ConsoleStatement, DecrementStatement,
|
||||
DefinitionStatement, Expression, ExpressionConsumer, FinalizeStatement, Identifier, IncrementStatement,
|
||||
IterationStatement, ReturnStatement, Statement, StatementConsumer, TernaryExpression,
|
||||
DefinitionStatement, Expression, ExpressionConsumer, ExpressionStatement, FinalizeStatement, Identifier,
|
||||
IncrementStatement, IterationStatement, ReturnStatement, Statement, StatementConsumer, TernaryExpression,
|
||||
};
|
||||
use leo_span::Symbol;
|
||||
|
||||
@ -234,6 +234,20 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
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`.
|
||||
fn consume_finalize(&mut self, input: FinalizeStatement) -> Self::Output {
|
||||
let mut statements = Vec::new();
|
||||
|
@ -34,6 +34,7 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
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::Finalize(stmt) => self.visit_finalize(stmt),
|
||||
Statement::Increment(stmt) => self.visit_increment(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) {
|
||||
if self.is_finalize {
|
||||
self.emit_err(TypeCheckerError::finalize_in_finalize(input.span()));
|
||||
|
@ -512,4 +512,11 @@ create_messages!(
|
||||
msg: format!("A finalize statement cannot contain tuple expressions."),
|
||||
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