opslang_ast/
lib.rs

1//! type definition of AST.
2
3use chrono::{DateTime, Utc};
4use std::ops::Range;
5
6#[derive(Debug, PartialEq)]
7pub struct Spanned<T> {
8    pub value: T,
9    pub span: Range<usize>,
10}
11
12impl<T> std::ops::Deref for Spanned<T> {
13    type Target = T;
14    fn deref(&self) -> &Self::Target {
15        &self.value
16    }
17}
18
19#[derive(Debug, PartialEq)]
20pub struct Row {
21    pub breaks: Option<()>,
22    pub content: Option<SingleStatement>,
23    pub comment_trailing: Option<Comment>,
24}
25pub type SRow = Spanned<Row>;
26
27#[derive(Debug, PartialEq)]
28pub struct Block {
29    pub default_receiver_component: Option<ReceiverComponent>,
30    pub delay: Option<Expr>,
31    pub rows: Vec<SRow>,
32    pub comment_first: Option<Comment>,
33    pub comment_last: Option<Comment>,
34}
35pub type SBlock = Spanned<Block>;
36
37#[derive(Debug, PartialEq)]
38pub struct Comment(pub String);
39
40/// reserved controls
41#[derive(Debug, PartialEq)]
42pub enum SingleStatement {
43    Call(Call),
44    Wait(Wait),
45    Assert(Assert),
46    AssertEq(AssertEq),
47    Command(Command),
48    Let(Let),
49    Print(Print),
50    Set(Set),
51    Return,
52}
53
54#[derive(Debug, PartialEq)]
55pub enum Statement {
56    Single(SRow),
57    Block(SBlock),
58}
59
60#[derive(Debug, PartialEq)]
61pub struct VariablePath {
62    pub raw: String,
63}
64
65#[derive(Debug, PartialEq)]
66pub struct FilePath {
67    pub full_name: String,
68}
69
70#[derive(Debug, PartialEq)]
71pub struct Assert {
72    pub condition: Expr,
73}
74
75#[derive(Debug, PartialEq)]
76pub struct AssertEq {
77    pub left: Expr,
78    pub right: Expr,
79    pub tolerance: Option<Expr>,
80}
81
82#[derive(Debug, PartialEq)]
83pub struct Command {
84    pub destination: DestinationSpec,
85    pub name: String,
86    pub args: Vec<Expr>,
87}
88
89#[derive(Debug, PartialEq)]
90pub struct DestinationSpec {
91    pub receiver_component: Option<ReceiverComponent>,
92    pub time_indicator: Option<Expr>,
93    pub executor_component: Option<ExecutorComponent>,
94}
95
96#[derive(Debug, PartialEq)]
97pub struct ReceiverComponent {
98    pub name: String,
99    pub exec_method: String,
100}
101
102#[derive(Debug, PartialEq)]
103pub struct ExecutorComponent {
104    pub name: String,
105}
106
107#[derive(Debug, PartialEq)]
108pub struct Call {
109    pub path: FilePath,
110}
111
112#[derive(Debug, PartialEq)]
113pub struct Wait {
114    pub condition: Expr,
115}
116
117#[derive(Debug, PartialEq)]
118pub struct WaitInc {
119    pub condition: Expr,
120}
121
122#[derive(Debug, PartialEq)]
123pub enum CompareOp {
124    BinOp(CompareBinOp),
125    In(CompareIn),
126}
127
128#[derive(Debug, PartialEq)]
129pub struct CompareBinOp {
130    pub method: CompareBinOpKind,
131    pub rhs: Expr,
132}
133
134#[derive(Debug, PartialEq)]
135pub enum CompareBinOpKind {
136    GreaterEq,
137    LessEq,
138    Greater,
139    Less,
140    NotEqual,
141    Equal,
142}
143
144#[derive(Debug, PartialEq)]
145pub struct CompareIn {
146    pub lo: Expr,
147    pub hi: Expr,
148}
149
150#[derive(Debug, PartialEq)]
151pub struct Ident {
152    pub raw: String,
153}
154
155#[derive(Debug, PartialEq)]
156pub struct Let {
157    pub variable: Ident,
158    pub rhs: Expr,
159}
160
161#[derive(Debug, PartialEq)]
162pub struct Print {
163    pub arg: Expr,
164}
165
166#[derive(Debug, PartialEq)]
167pub struct Set {
168    pub name: VariablePath,
169    pub expr: Expr,
170}
171
172/// an expression.
173///
174/// to implementer: you can use stack machine to express the evaluation of this tree structure.
175#[derive(Debug, PartialEq)]
176pub enum Expr {
177    Variable(VariablePath),
178    TlmRef(VariablePath),
179    Literal(Literal),
180    UnOp(UnOpKind, Box<Self>),
181    BinOp(BinOpKind, Box<Self>, Box<Self>),
182    FunCall(Box<Self>, Vec<Self>),
183}
184
185#[derive(Debug, PartialEq)]
186pub enum Literal {
187    Array(Vec<Expr>),
188    String(String),
189    Numeric(Numeric, Option<NumericSuffix>),
190    DateTime(DateTime<Utc>),
191    TlmId(String),
192    Bytes(Vec<u8>),
193}
194
195#[derive(Debug, PartialEq)]
196pub enum Numeric {
197    Integer(String, IntegerPrefix),
198    Float(String),
199}
200
201#[derive(Debug, PartialEq)]
202pub enum NumericSuffix {
203    Second,
204}
205
206#[derive(Debug, PartialEq)]
207pub enum IntegerPrefix {
208    Hexadecimal,
209    Decimal,
210    Octal,
211    Binary,
212}
213
214#[derive(Debug, PartialEq)]
215pub enum UnOpKind {
216    Neg,
217}
218
219#[derive(Debug, PartialEq)]
220pub enum BinOpKind {
221    Compare(CompareBinOpKind),
222    /// `a if b` means `b implies a`.
223    /// `a if b` will be represented as `Expr::BinOp(BinOpKind::If, a, b)`
224    If,
225    And,
226    Or,
227    In,
228    Mul,
229    Div,
230    Mod,
231    Add,
232    Sub,
233}