datex_core/compiler/
mod.rs1
2
3use crate::compiler::parser::DatexParser;
4use crate::compiler::parser::Rule;
5use crate::datex_values::Endpoint;
6use crate::generator::header::append_dxb_header;
7use crate::global::binary_codes::BinaryCode;
8use crate::global::dxb_block::DXBBlockType;
9use crate::global::dxb_block::DXBHeader;
10use crate::global::dxb_block::HeaderFlags;
11use crate::global::dxb_block::RoutingInfo;
12use crate::utils::buffers::append_f64;
13use crate::utils::buffers::append_i16;
14use crate::utils::buffers::append_i32;
15use crate::utils::buffers::append_i64;
16use crate::utils::buffers::append_i8;
17
18use crate::utils::buffers::append_u32;
19use crate::utils::buffers::append_u8;
20
21pub mod parser;
22use pest::Parser;
23use pest::error::Error;
24use pest::iterators::Pair;
25use pest::iterators::Pairs;
26use regex::Regex;
27
28pub fn compile(datex_script:&str) -> Result<Vec<u8>, pest::error::Error<Rule>> {
29
30 let body = compile_body(datex_script)?;
31
32 let header = DXBHeader {
33 version: 2,
34 size: 65535,
35 signed: true,
36 encrypted: true,
37
38 block_type: DXBBlockType::REQUEST,
39 scope_id: 22,
40 block_index: 1,
41 block_increment: 2,
42 timestamp: 1234,
43
44 flags: HeaderFlags {
45 end_of_scope: true,
46 allow_execute: true,
47 device_type: 0
48 },
49
50 routing: RoutingInfo {
51 ttl: 14,
52 priority: 40,
53 sender: Some(Endpoint::new_person("@theo", Endpoint::ANY_INSTANCE))
54 }
55 };
56
57 Ok(append_dxb_header(&header, &body))
58}
59
60
61struct CompilationScope<'a> {
62 index: usize,
63 buffer: &'a mut Vec<u8>
64}
65
66impl<'a> CompilationScope<'a> {
67
68 const MAX_INT_32:i64 = 2_147_483_647;
69 const MIN_INT_32:i64 = -2_147_483_648;
70
71 const MAX_INT_8:i64 = 127;
72 const MIN_INT_8:i64 = -128;
73
74 const MAX_INT_16:i64 = 32_767;
75 const MIN_INT_16:i64 = -32_768;
76
77 const MAX_UINT_16:i64 = 65_535;
78
79 const INT_8_BYTES: u8 = 1;
80 const INT_16_BYTES: u8 = 2;
81 const INT_32_BYTES: u8 = 4;
82 const INT_64_BYTES: u8 = 8;
83 const UINT_8_BYTES: u8 = 1;
84 const UINT_16_BYTES: u8 = 2;
85 const UINT_32_BYTES: u8 = 4;
86 const UINT_64_BYTES: u8 = 8;
87 const FLOAT_64_BYTES: u8 = 8;
88
89 fn insert_boolean(&mut self, boolean: bool) {
91 if boolean {
92 self.append_binary_code(BinaryCode::TRUE);
93 }
94 else {
95 self.append_binary_code(BinaryCode::FALSE);
96 }
97 }
98
99 fn insert_string(&mut self, string: &str) {
100
101 let unescaped_string = self.unescape_string(string);
102
103 let bytes = unescaped_string.as_bytes();
104 let len = bytes.len();
105
106 if len < 256 {
107 self.append_binary_code(BinaryCode::SHORT_TEXT);
108 self.append_u8(len as u8);
109 }
110
111 else {
112 self.append_binary_code(BinaryCode::TEXT);
113 self.append_u32(len as u32);
114 }
115
116 self.append_buffer(bytes);
117
118 }
119
120 fn unescape_string(&mut self, string: &str) -> String {
121 let re = Regex::new(r"\\(.)").unwrap();
122
123 re.replace_all(
125 &string
126 .replace("\\b", "\u{0008}")
127 .replace("\\f", "\u{000c}")
128 .replace("\\r", "\r")
129 .replace("\\t", "\t")
130 .replace("\\v", "\u{000b}")
131 .replace("\\n", "\n"),
132 "$1").into_owned()
133 }
134
135 fn insert_float64(&mut self, float64: f64) {
136 self.append_binary_code(BinaryCode::FLOAT_64);
137 self.append_f64(float64);
138 }
139
140 fn insert_int(&mut self, int: i64) {
141 if int<=CompilationScope::MAX_INT_8 && int>= CompilationScope::MIN_INT_8 {self.insert_int8(int as i8)}
142 else if int<=CompilationScope::MAX_INT_16 && int>=CompilationScope::MIN_INT_16 {self.insert_int16(int as i16)}
143 else if int<=CompilationScope::MAX_INT_32 && int>=CompilationScope::MIN_INT_32 {self.insert_int32(int as i32)}
144 else {self.insert_int64(int)}
145 }
146
147 fn insert_int8(&mut self, int8: i8) {
148 self.append_binary_code(BinaryCode::INT_8);
149 self.append_i8(int8);
150 }
151 fn insert_int16(&mut self, int16: i16) {
152 self.append_binary_code(BinaryCode::INT_16);
153 self.append_i16(int16);
154 }
155 fn insert_int32(&mut self, int32: i32) {
156 self.append_binary_code(BinaryCode::INT_32);
157 self.append_i32(int32);
158 }
159 fn insert_int64(&mut self, int64: i64) {
160 self.append_binary_code(BinaryCode::INT_64);
161 self.append_i64(int64);
162 }
163
164
165 fn append_u8(&mut self, u8: u8) {
167 append_u8(self.buffer, u8);
168 self.index += CompilationScope::UINT_8_BYTES as usize;
169 }
170 fn append_u32(&mut self, u32: u32) {
171 append_u32(self.buffer, u32);
172 self.index += CompilationScope::UINT_32_BYTES as usize;
173 }
174 fn append_i8(&mut self, i8: i8) {
175 append_i8(self.buffer, i8);
176 self.index += CompilationScope::INT_8_BYTES as usize;
177 }
178 fn append_i16(&mut self, i16: i16) {
179 append_i16(self.buffer, i16);
180 self.index += CompilationScope::INT_16_BYTES as usize;
181 }
182 fn append_i32(&mut self, i32: i32) {
183 append_i32(self.buffer, i32);
184 self.index += CompilationScope::INT_32_BYTES as usize;
185 }
186 fn append_i64(&mut self, i64: i64) {
187 append_i64(self.buffer, i64);
188 self.index += CompilationScope::INT_64_BYTES as usize;
189 }
190 fn append_f64(&mut self, f64: f64) {
191 append_f64(self.buffer, f64);
192 self.index += CompilationScope::FLOAT_64_BYTES as usize;
193 }
194 fn append_string_utf8(&mut self, string: &str) {
195 let bytes = string.as_bytes();
196 self.buffer.extend_from_slice(bytes);
197 self.index += bytes.len()
198 }
199 fn append_buffer(&mut self, buffer: &[u8]) {
200 self.buffer.extend_from_slice(buffer);
201 self.index += buffer.len()
202 }
203
204 fn append_binary_code(&mut self, binary_code: BinaryCode) {
205 self.append_u8(binary_code as u8);
206 }
207
208}
209
210pub fn compile_body(datex_script:&str) -> Result<Vec<u8>, Error<Rule>> {
211 let pairs = DatexParser::parse(Rule::datex, datex_script)?;let mut buffer = Vec::with_capacity(256);
216 let compilation_scope = CompilationScope {buffer: &mut buffer, index: 0};
217
218 parse_statements(compilation_scope, pairs);
219
220 Ok(buffer)
221}
222
223fn parse_statements(mut compilation_scope: CompilationScope, pairs: Pairs<'_, Rule>) {
224
225 for pair in pairs {
226 match pair.as_rule() {
227 Rule::statement => {
228 for inner in pair.into_inner() {
230 parse(&mut compilation_scope, inner)
231 }
232 compilation_scope.append_binary_code(BinaryCode::CLOSE_AND_STORE);
233 }
235 Rule::EOI => {
236 }
238 _ => {
239 panic!("Invalid rule, expected statement")
240 }
241 }
242
243 }
244}
245
246fn parse(compilation_scope: &mut CompilationScope, pair: Pair<'_, Rule>) {
247
248 let rule = pair.as_rule();
249 match rule {
250 Rule::integer => {
251 let int = pair.as_str().parse::<i64>().unwrap();
252 compilation_scope.insert_int(int);
253 }
254 Rule::decimal => {
255 let decimal = pair.as_str().parse::<f64>().unwrap();
256 compilation_scope.insert_float64(decimal);
257 }
258 Rule::string => {
259 let string = pair.as_str();
260 let inner_string = &string[1..string.len()-1];
261 compilation_scope.insert_string(inner_string);
262 }
263 _ => {
264 panic!("Rule not implemented")
265 }
266 }
267
268}