datex_core/compiler/
mod.rs

1
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	// value insert functions
90	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		// TODO: escape, unicode, hex, octal?
124		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	// buffer functions
166	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)?;//.next().unwrap();
212
213	// println!("{:}", res);
214
215	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				// println!("statement {:#?}", pair);
229				for inner in pair.into_inner() {
230					parse(&mut compilation_scope, inner)
231				}
232				compilation_scope.append_binary_code(BinaryCode::CLOSE_AND_STORE);
233				// compilation_scope.buffer.push(BinaryCode::STD_TYPE_MAP as u8);
234			}
235			Rule::EOI => {
236				//
237			}
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}