ast/
expression.rs

1//! This module contains the AST representation for expressions in the SAP language.
2//!
3//! An expression is a combination of one or more values, variables, operators, and
4//! functions that evaluates to a single value. The AST nodes in this module represent the
5//! different types of expressions that are supported in the SAP language.
6//!
7//! Expressions are used in the language to perform calculations, make decisions, and
8//! manipulate data. They can be used as standalone statements, or as part of larger
9//! expressions or statements.
10//!
11//! Note: The `Box` type is used to indicate that the data enclosed is stored on the heap,
12//! rather than on the stack. This is necessary because otherwise the compiler needs to
13//! know the size of the expression at compile time, which is not possible for recursive
14//! data structures like the AST.
15use lexer::token::TokenKind;
16use serde::Serialize;
17use shared::span::{GetSpan, Span};
18
19use crate::literal::Literal;
20use crate::StatementList;
21
22/// Represents a single expression in the SAP language.
23#[derive(Debug, Serialize, PartialEq, Clone)]
24// Tell serde not to include this enum in the JSON output, since it only adds clutter and doesn't
25// provide any useful information.
26#[serde(untagged)]
27pub enum Expression {
28    Identifier(Identifier),
29    Unary(Unary),
30    Binary(Binary),
31    Selection(Selection),
32    FunctionCall(FunctionCall),
33    Array(Array),
34    Index(Index),
35    Literal(Literal),
36}
37
38impl GetSpan for Expression {
39    fn span(&self) -> &Span {
40        match self {
41            Expression::Identifier(identifier) => &identifier.span,
42            Expression::Unary(unary) => &unary.span,
43            Expression::Binary(binary) => &binary.span,
44            Expression::Selection(selection) => &selection.span,
45            Expression::FunctionCall(function_call) => &function_call.span,
46            Expression::Array(array) => &array.span,
47            Expression::Index(index) => &index.span,
48            Expression::Literal(literal) => literal.span(),
49        }
50    }
51}
52
53/// Represents an identifier in the SAP language.
54/// For example: `x`
55#[derive(Debug, Serialize, PartialEq, Clone)]
56#[serde(tag = "type")]
57pub struct Identifier {
58    pub name: String,
59    pub span: Span,
60}
61
62/// Represents a unary expression in the SAP language.
63/// For example: `-x`
64#[derive(Debug, Serialize, PartialEq, Clone)]
65#[serde(tag = "type")]
66pub struct Unary {
67    pub operator: TokenKind,
68    pub operand: Box<Expression>,
69    pub span: Span,
70}
71
72/// Represents a binary expression in the SAP language.
73/// For example: `x + 5`
74#[derive(Debug, Serialize, PartialEq, Clone)]
75#[serde(tag = "type")]
76pub struct Binary {
77    pub operator: TokenKind,
78    pub left: Box<Expression>,
79    pub right: Box<Expression>,
80    pub span: Span,
81}
82
83/// Represents a selection expression in the SAP language.
84/// For example:
85/// ```sap
86/// if x > 5 then
87///     display "x is greater than 5"
88/// otherwise
89///     display "x is less than or equal to 5"
90/// end
91/// ```
92#[derive(Debug, Serialize, PartialEq, Clone)]
93#[serde(tag = "type")]
94pub struct Selection {
95    pub condition: Box<Expression>,
96    pub conditional: StatementList,
97    pub else_conditional: Option<StatementList>,
98    pub span: Span,
99}
100
101/// Represents a function call expression in the SAP language.
102/// For example: `add(5, 10)`
103#[derive(Debug, Serialize, PartialEq, Clone)]
104#[serde(tag = "type")]
105pub struct FunctionCall {
106    /// The function being called. This can be an identifier or an expression which
107    /// evaluates to a function.
108    pub callee: Box<Expression>,
109    pub arguments: Vec<Expression>,
110    pub span: Span,
111}
112
113/// Represents an array expression in the SAP language.
114/// For example: `[1, 2, 3, 4, 5]`
115#[derive(Debug, Serialize, PartialEq, Clone)]
116#[serde(tag = "type")]
117pub struct Array {
118    pub elements: Vec<Expression>,
119    pub span: Span,
120}
121
122/// Represents an index expression in the SAP language.
123/// For example: `arr[0]`
124#[derive(Debug, Serialize, PartialEq, Clone)]
125#[serde(tag = "type")]
126pub struct Index {
127    pub object: Box<Expression>,
128    pub index: Box<Expression>,
129    pub span: Span,
130}