pub(crate) fn resolve_yul_statement(
    statement: &pt::YulStatement,
    context: &ExprContext,
    reachable: bool,
    loop_scope: &mut LoopScopes,
    symtable: &mut Symtable,
    resolved_statements: &mut Vec<YulStatement>,
    function_table: &mut FunctionsTable,
    ns: &mut Namespace,
) -> Result<bool, ()> {
    match statement {
        pt::YulStatement::FunctionDefinition(_) => Ok(true),
        pt::YulStatement::FunctionCall(func_call) => {
            let data = resolve_top_level_function_call(
                func_call,
                reachable,
                function_table,
                context,
                symtable,
                ns,
            )?;
            resolved_statements.push(data.0);
            Ok(data.1)
        }

        pt::YulStatement::Block(block) => {
            let data = resolve_yul_block(
                &block.loc,
                &block.statements,
                context,
                reachable,
                loop_scope,
                function_table,
                symtable,
                ns,
            );
            resolved_statements.push(YulStatement::Block(Box::new(data.0)));
            Ok(data.1)
        }

        pt::YulStatement::VariableDeclaration(loc, variables, initializer) => {
            resolved_statements.push(resolve_variable_declaration(
                loc,
                variables,
                initializer,
                reachable,
                function_table,
                context,
                symtable,
                ns,
            )?);
            Ok(true)
        }

        pt::YulStatement::Assign(loc, lhs, rhs) => {
            resolved_statements.push(resolve_assignment(
                loc,
                lhs,
                rhs,
                context,
                reachable,
                function_table,
                symtable,
                ns,
            )?);
            Ok(true)
        }

        pt::YulStatement::If(loc, condition, body) => {
            resolved_statements.push(resolve_if_block(
                loc,
                condition,
                &body.statements,
                context,
                reachable,
                loop_scope,
                function_table,
                symtable,
                ns,
            )?);
            Ok(true)
        }

        pt::YulStatement::Switch(switch_statement) => {
            let resolved_switch = resolve_switch(
                switch_statement,
                context,
                reachable,
                function_table,
                loop_scope,
                symtable,
                ns,
            )?;
            resolved_statements.push(resolved_switch.0);
            Ok(resolved_switch.1)
        }

        pt::YulStatement::Break(loc) => {
            if loop_scope.do_break() {
                resolved_statements.push(YulStatement::Break(*loc, reachable));
                Ok(false)
            } else {
                ns.diagnostics.push(Diagnostic::error(
                    *loc,
                    "break statement outside a for loop".to_string(),
                ));
                Err(())
            }
        }

        pt::YulStatement::Continue(loc) => {
            if loop_scope.do_continue() {
                resolved_statements.push(YulStatement::Continue(*loc, reachable));
                Ok(false)
            } else {
                ns.diagnostics.push(Diagnostic::error(
                    *loc,
                    "continue statement outside a for loop".to_string(),
                ));
                Err(())
            }
        }

        pt::YulStatement::Leave(loc) => {
            if !context.yul_function {
                ns.diagnostics.push(Diagnostic::error(
                    *loc,
                    "leave statement cannot be used outside a function".to_string(),
                ));
                return Err(());
            }
            resolved_statements.push(YulStatement::Leave(*loc, reachable));
            Ok(false)
        }

        pt::YulStatement::For(for_statement) => {
            let resolved_for = resolve_for_loop(
                for_statement,
                context,
                reachable,
                loop_scope,
                symtable,
                function_table,
                ns,
            )?;
            resolved_statements.push(resolved_for.0);
            Ok(resolved_for.1)
        }
    }
}
/// Resolves an yul statement. Returns a boolean that indicates if the next statement is reachable.
Resolves an yul statement. Returns a boolean that indicates if the next statement is reachable.
Resolves an yul statement . Returns a boolean that indicates if the next statement is reachable .
pub(crate) fn resolve_yul_statement(
    statement: &pt::YulStatement,
    context: &ExprContext,
    reachable: bool,
    loop_scope: &mut LoopScopes,
    symtable: &mut Symtable,
    resolved_statements: &mut Vec<YulStatement>,
    function_table: &mut FunctionsTable,
    ns: &mut Namespace,
) -> Result<bool, ()> {
    match statement {
        pt::YulStatement::FunctionDefinition(_) => Ok(true),
        pt::YulStatement::FunctionCall(func_call) => {
            let data = resolve_top_level_function_call(
                func_call,
                reachable,
                function_table,
                context,
                symtable,
                ns,
            )?;
            resolved_statements.push(data.0);
            Ok(data.1)
        }
        pt::YulStatement::Block(block) => {
            let data = resolve_yul_block(
                &block.loc,
                &block.statements,
                context,
                reachable,
                loop_scope,
                function_table,
                symtable,
                ns,
            );
            resolved_statements.push(YulStatement::Block(Box::new(data.0)));
            Ok(data.1)
        }
        pt::YulStatement::VariableDeclaration(loc, variables, initializer) => {
            resolved_statements.push(resolve_variable_declaration(
                loc,
                variables,
                initializer,
                reachable,
                function_table,
                context,
                symtable,
                ns,
            )?);
            Ok(true)
        }
        pt::YulStatement::Assign(loc, lhs, rhs) => {
            resolved_statements.push(resolve_assignment(
                loc,
                lhs,
                rhs,
                context,
                reachable,
                function_table,
                symtable,
                ns,
            )?);
            Ok(true)
        }
        pt::YulStatement::If(loc, condition, body) => {
            resolved_statements.push(resolve_if_block(
                loc,
                condition,
                &body.statements,
                context,
                reachable,
                loop_scope,
                function_table,
                symtable,
                ns,
            )?);
            Ok(true)
        }
        pt::YulStatement::Switch(switch_statement) => {
            let resolved_switch = resolve_switch(
                switch_statement,
                context,
                reachable,
                function_table,
                loop_scope,
                symtable,
                ns,
            )?;
            resolved_statements.push(resolved_switch.0);
            Ok(resolved_switch.1)
        }
        pt::YulStatement::Break(loc) => {
            if loop_scope.do_break() {
                resolved_statements.push(YulStatement::Break(*loc, reachable));
                Ok(false)
            } else {
                ns.diagnostics.push(Diagnostic::error(
                    *loc,
                    "break statement outside a for loop".to_string(),
                ));
                Err(())
            }
        }
        pt::YulStatement::Continue(loc) => {
            if loop_scope.do_continue() {
                resolved_statements.push(YulStatement::Continue(*loc, reachable));
                Ok(false)
            } else {
                ns.diagnostics.push(Diagnostic::error(
                    *loc,
                    "continue statement outside a for loop".to_string(),
                ));
                Err(())
            }
        }
        pt::YulStatement::Leave(loc) => {
            if !context.yul_function {
                ns.diagnostics.push(Diagnostic::error(
                    *loc,
                    "leave statement cannot be used outside a function".to_string(),
                ));
                return Err(());
            }
            resolved_statements.push(YulStatement::Leave(*loc, reachable));
            Ok(false)
        }
        pt::YulStatement::For(for_statement) => {
            let resolved_for = resolve_for_loop(
                for_statement,
                context,
                reachable,
                loop_scope,
                symtable,
                function_table,
                ns,
            )?;
            resolved_statements.push(resolved_for.0);
            Ok(resolved_for.1)
        }
    }
}
pub ( crate ) fn resolve_yul_statement ( statement : & pt :: YulStatement , context : & ExprContext , reachable : bool , loop_scope : & mut LoopScopes , symtable : & mut Symtable , resolved_statements : & mut Vec < YulStatement > , function_table : & mut FunctionsTable , ns : & mut Namespace , ) -> Result < bool , ( ) > { match statement { pt :: YulStatement :: FunctionDefinition ( _ ) => Ok ( true ) , pt :: YulStatement :: FunctionCall ( func_call ) => { let data = resolve_top_level_function_call ( func_call , reachable , function_table , context , symtable , ns , ) ? ; resolved_statements . push ( data . 0 ) ; Ok ( data . 1 ) } pt :: YulStatement :: Block ( block ) => { let data = resolve_yul_block ( & block . loc , & block . statements , context , reachable , loop_scope , function_table , symtable , ns , ) ; resolved_statements . push ( YulStatement :: Block ( Box :: new ( data . 0 ) ) ) ; Ok ( data . 1 ) } pt :: YulStatement :: VariableDeclaration ( loc , variables , initializer ) => { resolved_statements . push ( resolve_variable_declaration ( loc , variables , initializer , reachable , function_table , context , symtable , ns , ) ? ) ; Ok ( true ) } pt :: YulStatement :: Assign ( loc , lhs , rhs ) => { resolved_statements . push ( resolve_assignment ( loc , lhs , rhs , context , reachable , function_table , symtable , ns , ) ? ) ; Ok ( true ) } pt :: YulStatement :: If ( loc , condition , body ) => { resolved_statements . push ( resolve_if_block ( loc , condition , & body . statements , context , reachable , loop_scope , function_table , symtable , ns , ) ? ) ; Ok ( true ) } pt :: YulStatement :: Switch ( switch_statement ) => { let resolved_switch = resolve_switch ( switch_statement , context , reachable , function_table , loop_scope , symtable , ns , ) ? ; resolved_statements . push ( resolved_switch . 0 ) ; Ok ( resolved_switch . 1 ) } pt :: YulStatement :: Break ( loc ) => { if loop_scope . do_break ( ) { resolved_statements . push ( YulStatement :: Break ( * loc , reachable ) ) ; Ok ( false ) } else { ns . diagnostics . push ( Diagnostic :: error ( * loc , " " . to_string ( ) , ) ) ; Err ( ( ) ) } } pt :: YulStatement :: Continue ( loc ) => { if loop_scope . do_continue ( ) { resolved_statements . push ( YulStatement :: Continue ( * loc , reachable ) ) ; Ok ( false ) } else { ns . diagnostics . push ( Diagnostic :: error ( * loc , " " . to_string ( ) , ) ) ; Err ( ( ) ) } } pt :: YulStatement :: Leave ( loc ) => { if ! context . yul_function { ns . diagnostics . push ( Diagnostic :: error ( * loc , " " . to_string ( ) , ) ) ; return Err ( ( ) ) ; } resolved_statements . push ( YulStatement :: Leave ( * loc , reachable ) ) ; Ok ( false ) } pt :: YulStatement :: For ( for_statement ) => { let resolved_for = resolve_for_loop ( for_statement , context , reachable , loop_scope , symtable , function_table , ns , ) ? ; resolved_statements . push ( resolved_for . 0 ) ; Ok ( resolved_for . 1 ) } } }
Resolves an yul statement.
Resolves an yul statement .
statement
&pt::YulStatement
context
&ExprContext
reachable
bool
loop_scope
&mut LoopScopes
symtable
&mut Symtable
resolved_statements
&mut Vec<YulStatement>
function_table
&mut FunctionsTable
ns
&mut Namespace
statement
&pt::YulStatement
context
&ExprContext
reachable
bool
loop_scope
&mut LoopScopes
symtable
&mut Symtable
resolved_statements
&mut Vec<YulStatement>
function_table
&mut FunctionsTable
ns
&mut Namespace