1use crate::core::Id;
2use crate::dsl::{Constant, DirectVariable};
3use std::cmp::Ordering;
4use std::fmt;
5
6#[derive(Debug, PartialEq, Clone)]
7pub enum Variable {
8 DirectVariable(DirectVariable),
9 SymbolicVariable(SymbolicVariable),
10 MultiElementVariable(Vec<Id>),
13}
14
15impl Variable {
16 pub fn symbolic(name: &str) -> Variable {
17 Variable::SymbolicVariable(SymbolicVariable {
18 name: Id::from(name),
19 })
20 }
21}
22
23#[derive(Debug, PartialEq, Clone)]
24pub struct SymbolicVariable {
25 pub name: Id,
26}
27
28#[derive(Debug, PartialEq, Clone)]
29pub struct Assignment {
30 pub target: Variable,
31 pub value: ExprKind,
32}
33
34#[derive(Debug, PartialEq, Clone)]
35pub struct FbCall {
36 pub var_name: Id,
39 pub params: Vec<ParamAssignment>,
40}
41
42#[derive(Debug, PartialEq, Clone)]
43pub enum StmtKind {
44 Assignment(Assignment),
45 If(If),
46 FbCall(FbCall),
47}
48
49impl StmtKind {
50 pub fn if_then(condition: ExprKind, body: Vec<StmtKind>) -> StmtKind {
51 StmtKind::If(If {
52 expr: condition,
53 body: body,
54 else_body: vec![],
55 })
56 }
57
58 pub fn if_then_else(
59 condition: ExprKind,
60 body: Vec<StmtKind>,
61 else_body: Vec<StmtKind>,
62 ) -> StmtKind {
63 StmtKind::If(If {
64 expr: condition,
65 body: body,
66 else_body: else_body,
67 })
68 }
69}
70
71#[derive(Debug, PartialEq, Clone)]
72pub struct If {
73 pub expr: ExprKind,
75 pub body: Vec<StmtKind>,
76 pub else_body: Vec<StmtKind>,
77}
78
79impl StmtKind {
80 pub fn fb_assign(fb_name: &str, inputs: Vec<&str>, output: &str) -> StmtKind {
81 let assignments = inputs
82 .into_iter()
83 .map(|input| ParamAssignment::positional(ExprKind::symbolic_variable(input)))
84 .collect::<Vec<ParamAssignment>>();
85
86 StmtKind::assignment(
87 Variable::symbolic(output),
88 ExprKind::Function {
89 name: Id::from(fb_name),
90 param_assignment: assignments,
91 },
92 )
93 }
94 pub fn fb_call_mapped(fb_name: &str, inputs: Vec<(&str, &str)>) -> StmtKind {
95 let assignments = inputs
96 .into_iter()
97 .map(|pair| {
98 ParamAssignment::named(pair.0, ExprKind::Variable(Variable::symbolic(pair.1)))
99 })
100 .collect::<Vec<ParamAssignment>>();
101
102 StmtKind::FbCall(FbCall {
103 var_name: Id::from(fb_name),
104 params: assignments,
105 })
106 }
107
108 pub fn assignment(target: Variable, value: ExprKind) -> StmtKind {
109 StmtKind::Assignment(Assignment {
110 target: target,
111 value: value,
112 })
113 }
114
115 pub fn simple_assignment(target: &str, src: Vec<&str>) -> StmtKind {
116 let variable = match src.len() {
117 1 => Variable::symbolic(src[0]),
118 _ => {
119 let src = src
120 .into_iter()
121 .map(|part| Id::from(part))
122 .collect::<Vec<Id>>();
123 Variable::MultiElementVariable(src)
124 }
125 };
126
127 StmtKind::Assignment(Assignment {
128 target: Variable::symbolic(target),
129 value: ExprKind::Variable(variable),
130 })
131 }
132}
133
134#[derive(Debug, PartialEq, Clone)]
135pub enum CompareOp {
136 Or,
137 Xor,
138 And,
139 Eq,
140 Ne,
141 Lt,
142 Gt,
143 LtEq,
144 GtEq,
145}
146
147#[derive(Debug, PartialEq, Clone)]
148pub enum Operator {
149 Add,
150 Sub,
151 Mul,
152 Div,
153 Mod,
154 Pow,
155}
156
157#[derive(Debug, PartialEq, Clone)]
158pub enum UnaryOp {
159 Neg,
160 Not,
161}
162
163#[derive(Debug, PartialEq, Clone)]
164pub enum ExprKind {
165 Compare {
166 op: CompareOp,
167 terms: Vec<ExprKind>,
168 },
169 BinaryOp {
170 ops: Vec<Operator>,
171 terms: Vec<ExprKind>,
172 },
173 UnaryOp {
174 op: UnaryOp,
175 term: Box<ExprKind>,
176 },
177 Const(Constant),
178 Variable(Variable),
179 Function {
180 name: Id,
181 param_assignment: Vec<ParamAssignment>,
182 },
183}
184
185impl ExprKind {
186 pub fn boxed_symbolic_variable(name: &str) -> Box<ExprKind> {
187 Box::new(ExprKind::symbolic_variable(name))
188 }
189
190 pub fn symbolic_variable(name: &str) -> ExprKind {
191 ExprKind::Variable(Variable::symbolic(name))
192 }
193
194 pub fn integer_literal(value: i128) -> ExprKind {
195 ExprKind::Const(Constant::IntegerLiteral(1))
196 }
197}
198#[derive(Debug, PartialEq, Clone)]
199pub struct PositionalInput {
200 pub expr: ExprKind,
201}
202
203#[derive(Debug, PartialEq, Clone)]
204pub struct NamedInput {
205 pub name: Id,
206 pub expr: ExprKind,
207}
208
209#[derive(Debug, PartialEq, Clone)]
210pub enum ParamAssignment {
211 PositionalInput(PositionalInput),
212 NamedInput(NamedInput),
213 Output { not: bool, src: Id, tgt: Variable },
214}
215
216impl ParamAssignment {
217 pub fn positional(expr: ExprKind) -> ParamAssignment {
218 ParamAssignment::PositionalInput(PositionalInput { expr: expr })
219 }
220
221 pub fn named(name: &str, expr: ExprKind) -> ParamAssignment {
222 ParamAssignment::NamedInput(NamedInput {
223 name: Id::from(name),
224 expr: expr,
225 })
226 }
227}
228
229pub struct InputParamAssignment {
230 pub name: Option<String>,
231 pub expr: ExprKind,
232}