ucglib/build/opcode/
pointer.rs

1// Copyright 2019 Jeremy Wall
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use std::path::PathBuf;
15use std::rc::Rc;
16
17use crate::ast::Position;
18
19use super::translate::OpsMap;
20use super::{Error, Op};
21
22#[derive(Debug, PartialEq, Clone)]
23pub struct OpPointer {
24    pub pos_map: Rc<OpsMap>,
25    pub ptr: Option<usize>,
26    pub path: Option<PathBuf>,
27}
28
29impl OpPointer {
30    pub fn new(ops: Rc<OpsMap>) -> Self {
31        // If we load an empty program what happens?
32        Self {
33            pos_map: ops,
34            ptr: None,
35            path: None,
36        }
37    }
38
39    pub fn set_path(&mut self, path: PathBuf) {
40        self.path = Some(path);
41    }
42
43    pub fn next(&mut self) -> Option<&Op> {
44        if let Some(i) = self.ptr {
45            let nxt = i + 1;
46            if nxt < self.pos_map.len() {
47                self.ptr = Some(nxt);
48            } else {
49                return None;
50            }
51        } else if self.pos_map.len() != 0 {
52            self.ptr = Some(0);
53        }
54        self.op()
55    }
56
57    pub fn jump(&mut self, ptr: usize) -> Result<(), Error> {
58        if ptr < self.pos_map.len() {
59            self.ptr = Some(ptr);
60            return Ok(());
61        }
62        Err(Error::new(
63            format!("FAULT!!! Invalid Jump!"),
64            match self.pos() {
65                Some(pos) => pos.clone(),
66                None => Position::new(0, 0, 0),
67            },
68        ))
69    }
70
71    pub fn op(&self) -> Option<&Op> {
72        if let Some(i) = self.ptr {
73            return self.pos_map.ops.get(i);
74        }
75        None
76    }
77
78    pub fn pos(&self) -> Option<&Position> {
79        if let Some(i) = self.ptr {
80            return self.pos_map.pos.get(i);
81        }
82        None
83    }
84
85    pub fn idx(&self) -> Result<usize, Error> {
86        match self.ptr {
87            Some(ptr) => Ok(ptr),
88            None => Err(Error::new(
89                format!("FAULT!!! Position Check failure!"),
90                Position::new(0, 0, 0),
91            )),
92        }
93    }
94
95    pub fn snapshot(&self) -> Self {
96        Self {
97            pos_map: self.pos_map.clone(),
98            ptr: None,
99            path: self.path.clone(),
100        }
101    }
102}