pub(crate) fn verify_type_from_expression(
    expr: &YulExpression,
    function_table: &FunctionsTable,
) -> Result<Type, Diagnostic> {
    match expr {
        YulExpression::BoolLiteral(..) => Ok(Type::Bool),

        YulExpression::NumberLiteral(_, _, ty)
        | YulExpression::StringLiteral(_, _, ty)
        | YulExpression::YulLocalVariable(_, ty, _)
        | YulExpression::ConstantVariable(_, ty, ..)
        | YulExpression::SolidityLocalVariable(_, ty, None, _) => Ok(ty.clone()),

        YulExpression::SolidityLocalVariable(_, _, Some(_), _)
        | YulExpression::MemberAccess(..)
        | YulExpression::StorageVariable(..) => Ok(Type::Uint(256)),

        YulExpression::BuiltInCall(_, ty, _) => {
            let prototype = ty.get_prototype_info();
            if prototype.no_returns == 0 {
                Err(Diagnostic::error(
                    expr.loc(),
                    format!("builtin function '{}' returns nothing", prototype.name),
                ))
            } else if prototype.no_returns > 1 {
                Err(Diagnostic::error(
                    expr.loc(),
                    format!(
                        "builtin function '{}' has multiple returns and cannot be used in this scope",
                        prototype.name
                    ),
                ))
            } else {
                Ok(Type::Uint(256))
            }
        }

        YulExpression::FunctionCall(_, function_no, ..) => {
            let func = function_table.get(*function_no).unwrap();
            if func.returns.is_empty() {
                Err(Diagnostic::error(
                    expr.loc(),
                    format!("function '{}' returns nothing", func.id.name),
                ))
            } else if func.returns.len() > 1 {
                Err(Diagnostic::error(
                    expr.loc(),
                    format!(
                        "function '{}' has multiple returns and cannot be used in this scope",
                        func.id.name
                    ),
                ))
            } else {
                Ok(func.returns[0].ty.clone())
            }
        }
    }
}
/// Performs checks on whether it is possible to retrieve a type from an expression
Performs checks on whether it is possible to retrieve a type from an expression
Performs checks on whether it is possible to retrieve a type from an expression
pub(crate) fn verify_type_from_expression(
    expr: &YulExpression,
    function_table: &FunctionsTable,
) -> Result<Type, Diagnostic> {
    match expr {
        YulExpression::BoolLiteral(..) => Ok(Type::Bool),
        YulExpression::NumberLiteral(_, _, ty)
        | YulExpression::StringLiteral(_, _, ty)
        | YulExpression::YulLocalVariable(_, ty, _)
        | YulExpression::ConstantVariable(_, ty, ..)
        | YulExpression::SolidityLocalVariable(_, ty, None, _) => Ok(ty.clone()),
        YulExpression::SolidityLocalVariable(_, _, Some(_), _)
        | YulExpression::MemberAccess(..)
        | YulExpression::StorageVariable(..) => Ok(Type::Uint(256)),
        YulExpression::BuiltInCall(_, ty, _) => {
            let prototype = ty.get_prototype_info();
            if prototype.no_returns == 0 {
                Err(Diagnostic::error(
                    expr.loc(),
                    format!("builtin function '{}' returns nothing", prototype.name),
                ))
            } else if prototype.no_returns > 1 {
                Err(Diagnostic::error(
                    expr.loc(),
                    format!(
                        "builtin function '{}' has multiple returns and cannot be used in this scope",
                        prototype.name
                    ),
                ))
            } else {
                Ok(Type::Uint(256))
            }
        }
        YulExpression::FunctionCall(_, function_no, ..) => {
            let func = function_table.get(*function_no).unwrap();
            if func.returns.is_empty() {
                Err(Diagnostic::error(
                    expr.loc(),
                    format!("function '{}' returns nothing", func.id.name),
                ))
            } else if func.returns.len() > 1 {
                Err(Diagnostic::error(
                    expr.loc(),
                    format!(
                        "function '{}' has multiple returns and cannot be used in this scope",
                        func.id.name
                    ),
                ))
            } else {
                Ok(func.returns[0].ty.clone())
            }
        }
    }
}
pub ( crate ) fn verify_type_from_expression ( expr : & YulExpression , function_table : & FunctionsTable , ) -> Result < Type , Diagnostic > { match expr { YulExpression :: BoolLiteral ( .. ) => Ok ( Type :: Bool ) , YulExpression :: NumberLiteral ( _ , _ , ty ) | YulExpression :: StringLiteral ( _ , _ , ty ) | YulExpression :: YulLocalVariable ( _ , ty , _ ) | YulExpression :: ConstantVariable ( _ , ty , .. ) | YulExpression :: SolidityLocalVariable ( _ , ty , None , _ ) => Ok ( ty . clone ( ) ) , YulExpression :: SolidityLocalVariable ( _ , _ , Some ( _ ) , _ ) | YulExpression :: MemberAccess ( .. ) | YulExpression :: StorageVariable ( .. ) => Ok ( Type :: Uint ( 256 ) ) , YulExpression :: BuiltInCall ( _ , ty , _ ) => { let prototype = ty . get_prototype_info ( ) ; if prototype . no_returns == 0 { Err ( Diagnostic :: error ( expr . loc ( ) , format ! ( " " prototype name ) , ) ) } else if prototype . no_returns > 1 { Err ( Diagnostic :: error ( expr . loc ( ) , format ! ( " " prototype name ) , ) ) } else { Ok ( Type :: Uint ( 256 ) ) } } YulExpression :: FunctionCall ( _ , function_no , .. ) => { let func = function_table . get ( * function_no ) . unwrap ( ) ; if func . returns . is_empty ( ) { Err ( Diagnostic :: error ( expr . loc ( ) , format ! ( " " func id name ) , ) ) } else if func . returns . len ( ) > 1 { Err ( Diagnostic :: error ( expr . loc ( ) , format ! ( " " func id name ) , ) ) } else { Ok ( func . returns [ 0 ] . ty . clone ( ) ) } } } }
Performs checks on whether it is possible to retrieve a type from an expression
Performs checks on whether it is possible to retrieve a type from an expression
expr
&YulExpression
function_table
&FunctionsTable
expr
&YulExpression
function_table
&FunctionsTable