use crate::{
language::{parsed::CodeBlock, *},
type_system::TypeBinding,
TypeArgument, TypeInfo,
};
use sway_error::handler::ErrorEmitted;
use sway_types::{ident::Ident, Span, Spanned};
mod asm;
mod match_branch;
mod method_name;
mod scrutinee;
pub(crate) use asm::*;
pub(crate) use match_branch::MatchBranch;
pub use method_name::MethodName;
pub use scrutinee::*;
use sway_ast::intrinsics::Intrinsic;
#[derive(Debug, Clone)]
pub struct Expression {
pub kind: ExpressionKind,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct FunctionApplicationExpression {
pub call_path_binding: TypeBinding<CallPath>,
pub arguments: Vec<Expression>,
}
#[derive(Debug, Clone)]
pub struct LazyOperatorExpression {
pub op: LazyOp,
pub lhs: Box<Expression>,
pub rhs: Box<Expression>,
}
#[derive(Debug, Clone)]
pub struct TupleIndexExpression {
pub prefix: Box<Expression>,
pub index: usize,
pub index_span: Span,
}
#[derive(Debug, Clone)]
pub struct ArrayExpression {
pub contents: Vec<Expression>,
pub length_span: Option<Span>,
}
#[derive(Debug, Clone)]
pub struct StructExpression {
pub call_path_binding: TypeBinding<CallPath>,
pub fields: Vec<StructExpressionField>,
}
#[derive(Debug, Clone)]
pub struct IfExpression {
pub condition: Box<Expression>,
pub then: Box<Expression>,
pub r#else: Option<Box<Expression>>,
}
#[derive(Debug, Clone)]
pub struct MatchExpression {
pub value: Box<Expression>,
pub branches: Vec<MatchBranch>,
}
#[derive(Debug, Clone)]
pub struct MethodApplicationExpression {
pub method_name_binding: TypeBinding<MethodName>,
pub contract_call_params: Vec<StructExpressionField>,
pub arguments: Vec<Expression>,
}
#[derive(Debug, Clone)]
pub struct SubfieldExpression {
pub prefix: Box<Expression>,
pub field_to_access: Ident,
}
#[derive(Debug, Clone)]
pub struct AmbiguousSuffix {
pub before: Option<TypeBinding<Ident>>,
pub suffix: Ident,
}
impl Spanned for AmbiguousSuffix {
fn span(&self) -> Span {
if let Some(before) = &self.before {
Span::join(before.span(), self.suffix.span())
} else {
self.suffix.span()
}
}
}
#[derive(Debug, Clone)]
pub struct QualifiedPathRootTypes {
pub ty: TypeArgument,
pub as_trait: TypeInfo,
pub as_trait_span: Span,
}
#[derive(Debug, Clone)]
pub struct AmbiguousPathExpression {
pub qualified_path_root: Option<QualifiedPathRootTypes>,
pub call_path_binding: TypeBinding<CallPath<AmbiguousSuffix>>,
pub args: Vec<Expression>,
}
#[derive(Debug, Clone)]
pub struct DelineatedPathExpression {
pub call_path_binding: TypeBinding<CallPath>,
pub args: Option<Vec<Expression>>,
}
#[derive(Debug, Clone)]
pub struct AbiCastExpression {
pub abi_name: CallPath,
pub address: Box<Expression>,
}
#[derive(Debug, Clone)]
pub struct ArrayIndexExpression {
pub prefix: Box<Expression>,
pub index: Box<Expression>,
}
#[derive(Debug, Clone)]
pub struct StorageAccessExpression {
pub field_names: Vec<Ident>,
pub storage_keyword_span: Span,
}
#[derive(Debug, Clone)]
pub struct IntrinsicFunctionExpression {
pub name: Ident,
pub kind_binding: TypeBinding<Intrinsic>,
pub arguments: Vec<Expression>,
}
#[derive(Debug, Clone)]
pub struct WhileLoopExpression {
pub condition: Box<Expression>,
pub body: CodeBlock,
}
#[derive(Debug, Clone)]
pub struct ReassignmentExpression {
pub lhs: ReassignmentTarget,
pub rhs: Box<Expression>,
}
#[derive(Debug, Clone)]
pub enum ExpressionKind {
Error(Box<[Span]>, ErrorEmitted),
Literal(Literal),
AmbiguousPathExpression(Box<AmbiguousPathExpression>),
FunctionApplication(Box<FunctionApplicationExpression>),
LazyOperator(LazyOperatorExpression),
AmbiguousVariableExpression(Ident),
Variable(Ident),
Tuple(Vec<Expression>),
TupleIndex(TupleIndexExpression),
Array(ArrayExpression),
Struct(Box<StructExpression>),
CodeBlock(CodeBlock),
If(IfExpression),
Match(MatchExpression),
Asm(Box<AsmExpression>),
MethodApplication(Box<MethodApplicationExpression>),
Subfield(SubfieldExpression),
DelineatedPath(Box<DelineatedPathExpression>),
AbiCast(Box<AbiCastExpression>),
ArrayIndex(ArrayIndexExpression),
StorageAccess(StorageAccessExpression),
IntrinsicFunction(IntrinsicFunctionExpression),
WhileLoop(WhileLoopExpression),
Break,
Continue,
Reassignment(ReassignmentExpression),
Return(Box<Expression>),
}
#[derive(Debug, Clone)]
pub enum ReassignmentTarget {
VariableExpression(Box<Expression>),
}
#[derive(Debug, Clone)]
pub struct StructExpressionField {
pub name: Ident,
pub value: Expression,
pub(crate) span: Span,
}
impl Spanned for Expression {
fn span(&self) -> Span {
self.span.clone()
}
}
#[derive(Debug)]
pub(crate) struct Op {
pub span: Span,
pub op_variant: OpVariant,
}
impl Op {
pub fn to_var_name(&self) -> Ident {
Ident::new_with_override(self.op_variant.as_str().to_string(), self.span.clone())
}
}
#[derive(Debug)]
pub enum OpVariant {
Add,
Subtract,
Divide,
Multiply,
Modulo,
Or,
And,
Equals,
NotEquals,
Xor,
BinaryOr,
BinaryAnd,
GreaterThan,
LessThan,
GreaterThanOrEqualTo,
LessThanOrEqualTo,
}
impl OpVariant {
fn as_str(&self) -> &'static str {
use OpVariant::*;
match self {
Add => "add",
Subtract => "subtract",
Divide => "divide",
Multiply => "multiply",
Modulo => "modulo",
Or => "$or$",
And => "$and$",
Equals => "eq",
NotEquals => "neq",
Xor => "xor",
BinaryOr => "binary_or",
BinaryAnd => "binary_and",
GreaterThan => "gt",
LessThan => "lt",
LessThanOrEqualTo => "le",
GreaterThanOrEqualTo => "ge",
}
}
}