1use std::fmt;
2use strum_macros::EnumString;
3use serde::{Deserialize, Serialize};
4
5#[derive(Default, PartialEq, Debug, Serialize, Deserialize, Clone, EnumString)]
6#[serde(tag="type")]
7pub enum AlephTree {
8 #[default]
9 Unit,
10 Break,
11 Continue,
12 Ellipsis,
13 #[serde(alias="Integer")]
14 Int{value:String},
15 Float{value:String},
16 Bool{value:String},
17 String{value:String},
18 Ident{value:String},
19 Bytes{elems: Vec<u8>},
20 Complex{real: String, imag: String},
21 Tuple {
22 elems: Vec<Box<AlephTree>>
23 },
24 Array {
25 elems: Vec<Box<AlephTree>>
26 },
27 Neg{
28 expr:Box<AlephTree>,
29 },
30 Not{
31 #[serde(alias="boolExpr")]
32 bool_expr:Box<AlephTree>,
33 },
34 And{
35 #[serde(alias="boolExpr1")]
36 bool_expr1:Box<AlephTree>,
37 #[serde(alias="boolExpr2")]
38 bool_expr2:Box<AlephTree>
39 },
40 Or{
41 #[serde(alias="boolExpr1")]
42 bool_expr1:Box<AlephTree>,
43 #[serde(alias="boolExpr2")]
44 bool_expr2:Box<AlephTree>
45 },
46 Add{
47 #[serde(alias="numberExpr1")]
48 number_expr1:Box<AlephTree>,
49 #[serde(alias="numberExpr2")]
50 number_expr2:Box<AlephTree>
51 },
52 Sub{
53 #[serde(alias="numberExpr1")]
54 number_expr1:Box<AlephTree>,
55 #[serde(alias="numberExpr2")]
56 number_expr2:Box<AlephTree>
57 },
58 Mul{
59 #[serde(alias="numberExpr1")]
60 number_expr1:Box<AlephTree>,
61 #[serde(alias="numberExpr2")]
62 number_expr2:Box<AlephTree>
63 },
64 Div{
65 #[serde(alias="numberExpr1")]
66 number_expr1:Box<AlephTree>,
67 #[serde(alias="numberExpr2")]
68 number_expr2:Box<AlephTree>
69 },
70 Eq{
71 expr1: Box<AlephTree>,
72 expr2: Box<AlephTree>,
73 },
74 LE{
75 expr1: Box<AlephTree>,
76 expr2: Box<AlephTree>,
77 },
78 In{
79 expr1: Box<AlephTree>,
80 expr2: Box<AlephTree>,
81 },
82 If{
83 condition: Box<AlephTree>,
84 then: Box<AlephTree>,
85 #[serde(alias="else")]
86 els: Box<AlephTree>
87 },
88 While{
89 #[serde(alias="initExpr")]
90 init_expr: Box<AlephTree>,
91 condition: Box<AlephTree>,
92 #[serde(alias="loopExpr")]
93 loop_expr: Box<AlephTree>,
94 #[serde(alias="postExpr")]
95 post_expr: Box<AlephTree>,
96 },
97 Let{
98 var: String,
99 #[serde(alias="isPointer")]
100 is_pointer: String,
101 value: Box<AlephTree>,
102 expr: Box<AlephTree>
103 },
104 LetRec{
105 name: String,
106 args: Vec<Box<AlephTree>>,
107 body: Box<AlephTree>
108 },
109 Get{
110 #[serde(alias="arrayName")]
111 array_name: String,
112 elem: Box<AlephTree>
113 },
114 Put{
115 #[serde(alias="arrayName")]
116 array_name: String,
117 elem: Box<AlephTree>,
118 value: Box<AlephTree>,
119 insert: String
120 },
121 Remove{
122 #[serde(alias="arrayName")]
123 array_name: String,
124 elem: Box<AlephTree>,
125 #[serde(alias="isValue")]
126 is_value: String,
127 },
128 Length{
129 var:String
130 },
131 Match{
132 expr: Box<AlephTree>,
133 #[serde(alias="caseList")]
134 case_list: Vec<Box<AlephTree>>
135 },
136 MatchLine {
137 condition: Box<AlephTree>,
138 #[serde(alias="caseExpr")]
139 case_expr: Box<AlephTree>
140 },
141 Var{
142 var: String,
143 #[serde(alias="isPointer")]
144 is_pointer: String,
145 },
146 App{
147 #[serde(alias="objectName")]
148 object_name: String,
149 fun: Box<AlephTree>,
150 #[serde(alias="paramList")]
151 param_list: Vec<Box<AlephTree>>
152 },
153 Stmts {
154 expr1: Box<AlephTree>,
155 expr2: Box<AlephTree>
156 },
157 #[serde(alias="Import")]
158 Iprt{
159 name: String
160 },
161 #[serde(alias="Class")]
162 Clss{
163 name: String,
164 #[serde(alias="attributList")]
165 attribute_list: Vec<String>,
166 body: Box<AlephTree>
167 },
168 #[serde(alias="Return")]
169 Return{
170 value: Box<AlephTree>
171 },
172 #[serde(alias="Comment")]
173 Comment{
174 value: String
175 },
176 #[serde(alias="CommentMulti")]
177 CommentMulti{
178 value: String
179 },
180 Assert {
181 condition: Box<AlephTree>,
182 message: Box<AlephTree>
183 }
184}
185
186pub fn json_parse(source: String) -> AlephTree {
187 serde_json::from_str(&source).unwrap()
188}
189
190pub fn to_json(ast: AlephTree) -> String {
191 serde_json::to_string_pretty(&ast).unwrap()
192}
193
194impl FromIterator<AlephTree> for Vec<Box<AlephTree>> {
195 fn from_iter<I: IntoIterator<Item=AlephTree>>(iter : I) -> Self {
196 let mut result: Vec<Box<AlephTree>> = Vec::new();
197 for node in iter {
198 result.push(Box::new(node));
199 }
200 result
201 }
202}
203
204impl fmt::Display for AlephTree {
205 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
206 match self {
207 e => write!(f, "{:?}", e),
208 }
209 }
210}
211
212impl AlephTree {
213 pub fn to_string_value(&self) -> String {
214 match self {
215 AlephTree::Bool { value } => value.to_string(),
216 AlephTree::Int { value } => value.to_string(),
217 AlephTree::Float { value } => value.to_string(),
218 AlephTree::String { value } => value.to_string(),
219 AlephTree::Ident { value } => value.to_string(),
220 AlephTree::Bytes { elems } => match std::str::from_utf8(elems) {
221 Ok(s) => s.to_string(),
222 Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
223 }
224 _ => {
225 println!("Can't evaluate to_string_value : {}", self);
226 panic!()
227 }
228 }
229 }
230}