1use std::error::Error;
25use displaystr::display;
26pub mod utils;
27pub mod parser;
28pub mod funcs;
29
30pub enum DataType {
34 DATA8,
36 DATA16,
38 DATA32,
40 DATAF,
42 DATAN(usize), DATAS(usize)
46}
47
48pub enum Encoding<'a> {
60 LC0(i8),
62 LC1(i8),
64 LC2(i16),
66 LC4(i32),
68 LCF(f32),
70 LV0(u8),
72 LV1(u8),
74 GV0(u8),
76 GV1(u8),
78 GV2(u16),
80 LCS(&'a str),
82}
83
84pub struct Command {
95 pub id: u16,
97 pub reply: bool,
99 allocation: u16,
100 pub bytecode: Vec<u8>,
102}
103
104pub const VID: u16 = 0x0694;
107pub const PID: u16 = 0x0005;
109
110#[allow(non_snake_case)]
111pub struct Port {
113 pub A: i8,
114 pub B: i8,
115 pub C: i8,
116 pub D: i8,
117 pub ALL: i8
118}
119pub const PORT: Port = Port { A: 1, B: 2, C: 4, D: 8, ALL: 15};
121
122#[derive(Debug)]
123#[display]
124pub enum ValError {
126 PosOverflow(u32, u32) = "Encode Error: Value {_0} overflowed {_1}",
129 NegOverflow(i32, i32) = "Encode Error: Value {_0} overflowed {_1}",
131 MemOverflow(u16, u16, u16, String) = "Allocation Error: Cannot allocate data with size {_0}. Allocated {_3} byte(s). Memory: {_1}/{_2}",
134 InvalidRange(i32, i32, i32) = "Invalid Range: Expect {_1} - {_2} got {_0}",
136 InvalidValue(i32, i32) = "Invalid Value: Expect {_1} got {_0}"
138}
139
140impl Error for ValError {}
141
142impl Command {
143 pub fn new() -> Self { Command::default() }
144 pub fn gen_bytes(&self) -> Vec<u8> {
146 let mut packet: Vec<u8> = vec![0x00, 0x00];
147 packet.extend(self.id.to_le_bytes());
148 packet.push(match self.reply {
149 true => 0x00,
150 false => 0x80,
151 });
152 packet.extend(self.allocation.to_le_bytes());
153 packet.extend(&self.bytecode);
154 let ln = ((5 + self.bytecode.len()) as u16).to_le_bytes();
155 packet[0] = ln[0];
156 packet[1] = ln[1];
157 packet
158 }
159 pub fn reserved_bytes(&self) -> usize {
162 ((self.allocation >> 10) + (self.allocation & ((1 << 10) - 1))) as usize
163 }
164 pub fn mem_free(&mut self) {
167 self.allocation = 0;
168 }
169}
170
171pub fn encode(encoding: Encoding) -> Result<Vec<u8>, ValError> {
181let mut bytes: Vec<u8> = vec![];
182 let mut head: u8 = 0;
183 match encoding {
184 Encoding::LC0(val) => {
185 if val > 31 { return Err(ValError::PosOverflow(val as u32, 31)) }
186 if val < -31 { return Err(ValError::NegOverflow(val as i32, -31)) }
187 if val < 0 { head += 1 << 5;}
188 head += (val.abs() & 0b11111) as u8
189 }
190 Encoding::GV0(val) | Encoding::LV0(val) => {
191 if val > 31 { return Err(ValError::PosOverflow(val as u32, 31)) }
192 head += 1 << 6;
193 if let Encoding::GV0(_) = encoding { head += 1 << 5; }
194 head += val & 0b11111;
195 }
196 Encoding::LCS(_) => {
197 head += 0b10000100;
198 }
199 _ => { head += 1 << 7; }
200 }
201 bytes.push(head);
202 let res: Result<Vec<u8>, ValError> = match encoding {
203 Encoding::LC1(val) => {
204 head += 1;
205 if val == i8::MIN { return Err(ValError::NegOverflow(val as i32, i8::MIN as i32)) }
206 if val < 0 { head += 1 << 5; }
207 Ok((val.abs() & i8::MAX).to_le_bytes().to_vec())
208 }
209 Encoding::LC2(val) => {
210 head += 2;
211 if val == i16::MIN { return Err(ValError::NegOverflow(val as i32, i16::MIN as i32)) }
212 if val < 0 { head += 1 << 5; }
213 Ok((val.abs() & i16::MAX).to_le_bytes().to_vec())
214 }
215 Encoding::LC4(val) => {
216 head += 3;
217 if val == i32::MIN { return Err(ValError::NegOverflow(val, i32::MIN)) }
218 if val < 0 { head += 1 << 5; }
219 Ok((val.abs() & i32::MAX).to_le_bytes().to_vec())
220 }
221 Encoding::LV1(val) | Encoding::GV1(val) => {
222 head += (1 << 5) + 1;
223 Ok(val.to_le_bytes().to_vec())
224 }
225 Encoding::GV2(val) => {
226 head += (1 << 5) + 2;
227 Ok(val.to_le_bytes().to_vec())
228 }
229 Encoding::LCS(val) => {
230 let mut tmp = val.as_bytes().to_vec();
231 tmp.push(0);
232 Ok(tmp)
233 }
234 Encoding::LCF(val) => {
235 head += 3;
236 Ok(val.to_le_bytes().to_vec())
237 }
238 _ => Ok(vec![]),
239 };
240 bytes.extend(res?);
241 bytes[0] = head;
242 Ok(bytes)
243}
244
245impl Command {
246 pub fn allocate(&mut self, data: DataType, global: bool) -> Result<Vec<u8>, ValError> {
249 let local: u8 = (self.allocation >> 10) as u8;
250 let glob: u16 = self.allocation & ((1 << 10) - 1);
251 let address: u16 = if global { local.into() } else { glob };
252 let mem: u16 = match data {
253 DataType::DATA8 => 1,
254 DataType::DATA16 => 2,
255 DataType::DATA32 | DataType::DATAF => 4,
256 DataType::DATAN(length) => u16::try_from(length).unwrap(),
257 DataType::DATAS(length) => u16::try_from(length + 1).unwrap()
258 };
259 if local + (mem as u8) > (1 << 7) - 1 { return Err(ValError::MemOverflow(mem, local as u16, (1 << 7) - 1, "local".to_string())); }
260 if glob + mem > (1 << 10) - 1 { return Err(ValError::MemOverflow(mem, glob, (1 << 10) - 1, "global".to_string())); }
261 self.allocation += if global { mem } else { mem << 10 };
262 match address {
263 0..=31 => {
264 if global {
265 encode(Encoding::GV0(address as u8))
266 } else {
267 encode(Encoding::LV0(address as u8))
268 }
269 }
270 32..=254 => {
271 if global {
272 encode(Encoding::GV1(address as u8))
273 } else {
274 encode(Encoding::LV1(address as u8))
275 }
276 }
277 _ => {
278 if global {
279 encode(Encoding::GV2(address))
280 }else {
281 Err(ValError::PosOverflow(mem.into(), (1 << 7) - 1)) }
283 }
284 }
285 }
286}
287
288impl Default for Command {
289 fn default() -> Self {
290 Command {
291 id: 170,
292 reply: true,
293 allocation: 0,
294 bytecode: vec![],
295 }
296 }
297}