1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! # Abstract Syntax Tree (AST) Module
//!
//! The AST module contains the definitions for the abstract syntax tree (AST) nodes
//! generated by the parser. The AST nodes are used to represent the structure of the
//! source code in a tree-like format, which can be used to perform various analysis
//! and evaluation tasks on the code.
//!
//! The AST nodes are defined as Rust structs, and are serialisable to JSON using the
//! `serde` library. This allows the AST to be easily converted to a JSON string for
//! debugging and analysis purposes.
//!
//! The AST module is divided into sub-modules, each of which contains the definitions
//! for a specific type of AST node, such as expressions, statements, and literals.
//!
//! The AST module also contains a `Program` struct, which is the root node for all
//! syntax trees generated by the parser. The `Program` struct contains a list of
//! statements, which represent the top-level statements in the source code.
pub mod expression;
pub mod literal;
pub mod statement;
pub mod tostring;

use serde::Serialize;
use shared::span::Span;
use statement::Statement;

/// Converts an AST node to a JSON string representation.
///
/// # Arguments
///
/// * `node` - The AST node to convert.
///
/// # Returns
///
/// Returns a Result containing the JSON string representation of the AST node, or an
/// error if the conversion fails.
pub fn ast_to_json<T>(node: &T) -> Result<String, serde_json::error::Error>
where
    T: ?Sized + Serialize,
{
    serde_json::to_string_pretty(&node)
}

/// Represents a whole program source file in the SAP language. It is the root node for
/// all syntax trees generated by the parser.
#[derive(Debug, Serialize)]
#[serde(tag = "type")]
pub struct Program {
    pub statements: Vec<Statement>,
    pub span: Span,
}

impl Program {
    /// Creates a new instance of the Program struct.
    ///
    /// Note: `span.end` is set to 0
    pub fn new() -> Self {
        Self {
            statements: vec![],
            span: Span { start: 0, end: 0 },
        }
    }
}

/// Represents a list of statements. It is used to store a list of statements for an
/// entire program, or for a block of code within a function or selection statement.
#[derive(Debug, Serialize, PartialEq, Clone)]
pub struct StatementList {
    pub statements: Vec<Statement>,
    pub span: Span,
}

impl StatementList {
    /// Creates a new instance of the Block struct.
    ///
    /// Note: `span.end` is set to 0
    pub fn new() -> Self {
        Self {
            statements: vec![],
            span: Span { start: 0, end: 0 },
        }
    }
}