Skip to main content

oak_tcl/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2use core::range::Range;
3
4/// The root of a Tcl Abstract Syntax Tree.
5#[derive(Debug, Clone)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub struct TclRoot {
8    /// The span of the entire Tcl script in the source file.
9    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
10    pub span: Range<usize>,
11    /// The items (commands or comments) in the script.
12    pub items: Vec<TclItem>,
13}
14
15/// A top-level item in a Tcl script.
16#[derive(Debug, Clone)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum TclItem {
19    /// A Tcl command.
20    Command(TclCommand),
21    /// A Tcl comment.
22    Comment(TclComment),
23}
24
25/// A Tcl command.
26#[derive(Debug, Clone)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub struct TclCommand {
29    /// The span of the command in the source file.
30    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
31    pub span: Range<usize>,
32    /// The words (arguments) of the command.
33    pub words: Vec<TclWord>,
34}
35
36/// A Tcl word (an argument or command name).
37#[derive(Debug, Clone)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub enum TclWord {
40    /// A simple string word.
41    Simple(String),
42    /// A variable substitution word.
43    Variable(String),
44    /// A script substitution word.
45    Script(TclRoot),
46    /// A braced string word.
47    Braced(String),
48}
49
50/// A Tcl comment.
51#[derive(Debug, Clone)]
52#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
53pub struct TclComment {
54    /// The span of the comment in the source file.
55    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
56    pub span: Range<usize>,
57    /// The text of the comment.
58    pub text: String,
59}
60
61impl TclRoot {
62    /// Creates a new Tcl root node with the given span.
63    pub fn new(span: Range<usize>) -> Self {
64        Self { span, items: Vec::new() }
65    }
66}