1use std::io;
4use std::io::{ Read, Write };
5use std::collections::HashMap;
6use std::borrow::Cow;
7
8use options;
9
10use {
11 Options,
12 Call,
13 Constant,
14 Binding,
15 Instruction,
16 Cond,
17 Mem,
18 Execute,
19 Fingerprint,
20 LittleValue,
21 Template,
22 Build,
23 Function,
24 BuildError,
25 LittleError,
26 LittleResult,
27};
28
29const MAX_VALUES: usize = 500000;
30
31pub struct Interpreter;
33
34impl Interpreter {
35 pub fn new() -> Interpreter {
36 Interpreter
37 }
38}
39
40impl<'a, V: LittleValue + 'a> Build<'a, V> for Interpreter {
41 type Output = Executable<'a, V>;
42
43 fn build(
47 &'a mut self,
48 id: &str,
49 template: Template<V>,
50 calls: &'a HashMap<&'a str, &'a (Function<V> + 'a)>
51 ) -> LittleResult<Executable<V>> {
52 Ok(Executable::<V> {
53 id: id.into(),
54 instructions: template.instructions,
55 constants: template.constants,
56 calls: match template.calls_template.build(calls) {
57 Ok(built) => built,
58 Err(options::Error::ParameterMissing(s)) => return Err(BuildError::FunctionNotFound { required: s }.into()),
59 },
60 })
61 }
62
63 fn load(&'a mut self, id: &str, env: Fingerprint, calls: &'a Vec<&'a (Function<V> + 'a)>)
65 -> LittleResult<Self::Output>
66 {
67 unreachable!("interpreter load is not implemented");
68 }
69}
70
71pub struct Executable<'a, V: 'a> {
72 id: String,
73 instructions: Vec<Instruction>,
74 constants: Options<Constant, V>,
75 calls: Options<Call, &'a Function<V>>,
76}
77
78impl<'a, V: LittleValue + 'a> Execute<'a, V> for Executable<'a, V> {
79 type Stream = InterpreterStream<'a, V>;
80
81 fn execute(&'a self, data: V) -> InterpreterStream<'a, V> {
82 InterpreterStream {
83 pc: 0,
84 buf: Vec::new(),
85 values: Values {
86 stack: Vec::new(),
87 values: Vec::new(),
88 executable: self,
89 parameters: data,
90 }
91 }
92 }
93
94 fn get_id<'r>(&'r self) -> &'r str {
95 &self.id
96 }
97
98 fn identify_env(&self) -> Fingerprint {
99 Fingerprint::empty()
100 }
101}
102
103pub struct InterpreterStream<'a, V: 'a> {
104 pc: usize,
105 buf: Vec<u8>,
106 values: Values<'a, V>,
107}
108
109enum ExecutionResult {
110 Done,
111 Continue,
112 Interupt,
113}
114
115impl<'a, V: LittleValue> InterpreterStream<'a, V> {
116 pub fn peek_stack<'r>(&'r self, slice_size: usize) -> Option<&'r [V]> {
120 let stack_len = self.values.stack.len();
121
122 if stack_len < slice_size {
123 return None;
124 }
125
126 Some(&self.values.stack[stack_len - slice_size as usize .. stack_len])
127 }
128
129 fn execute(&mut self) -> Result<ExecutionResult, LittleError> {
130 match self.values.executable.instructions.get(self.pc) {
131 Some(i) => {
132 match *i {
133 Instruction::Output { ref location } => {
134 try!(write!(self.buf, "{}", try!(self.values.get_mem_value(location))))
135 },
136 Instruction::Property { mut name } => {
137 unreachable!("execute Property not implemented")
138 },
139 Instruction::Pop { mut times } => while times > 0 {
140 if let None = self.values.stack.pop() {
141 return Err(LittleError::StackUnderflow);
142 }
143 times -= 1;
144 },
145 Instruction::Push { ref location } => {
146 let value = try!(self.values.get_mem_value(location)).into_owned();
147 self.values.stack.push(value);
148 },
149 Instruction::Load { binding, ref location } => {
150 let value = try!(self.values.get_mem_value(location)).into_owned();
151 self.values.set(binding, value);
152 },
153 Instruction::Jump { pc } => {
154 self.pc = pc as usize;
155 return Ok(ExecutionResult::Continue);
156 },
157 Instruction::CondJump { pc, ref location, test } => {
158 let value = try!(self.values.get_mem_value(location));
159 let value_ref = value.as_ref();
160 let stack = match self.values.stack.last() {
161 Some(value) => value,
162 None => return Err(LittleError::StackUnderflow),
163 };
164 let should_jump = match test {
165 Cond::Eq => stack == value_ref,
166 Cond::Gt => stack > value_ref,
167 Cond::Gte => stack >= value_ref,
168 Cond::Lt => stack < value_ref,
169 Cond::Lte => stack <= value_ref,
170 Cond::Ne => stack != value_ref,
171 };
172 if should_jump {
173 self.pc = pc as usize;
174 return Ok(ExecutionResult::Continue);
175 }
176 },
177 Instruction::Call { call, argc, push_result_to_stack } => {
178 let fun = match self.values.executable.calls.get(call) {
179 Some(f) => f,
180 None => return Err(LittleError::CallMissing(call)),
181 };
182
183 let stack_len = self.values.stack.len();
184 let result = fun.invoke(&self.values.stack[stack_len - argc as usize .. stack_len]);
185
186 if push_result_to_stack {
187 self.values.stack.push(result.unwrap());
188 }
189 },
190 Instruction::Interupt => {
191 self.pc += 1;
192 return Ok(ExecutionResult::Interupt);
193 }
194 };
195 self.pc += 1;
196 Ok(ExecutionResult::Continue)
197 },
198 None => Ok(ExecutionResult::Done),
199 }
200 }
201
202 #[cfg(feature="nightly")]
203 fn consume_buf(&mut self, buf: &mut [u8]) -> io::Result<usize> {
204 let self_buf_len = self.buf.len();
205 if self_buf_len >= buf.len() {
206 for (i, o) in self.buf.drain(..buf.len()).zip(buf.iter_mut()) {
207 *o = i
208 }
209 Ok(buf.len())
210 } else {
211 for (i, o) in self.buf.drain(..).zip(&mut buf[..self_buf_len]) {
212 *o = i
213 }
214 Ok(self_buf_len)
215 }
216 }
217
218 #[cfg(not(feature="nightly"))]
219 fn consume_buf(&mut self, buf: &mut [u8]) -> io::Result<usize> {
220 let self_buf_len = self.buf.len();
221 if self_buf_len >= buf.len() {
222 for (_, o) in (0..buf.len()).zip(buf.iter_mut()) {
223 *o = self.buf.remove(0);
224 }
225 Ok(buf.len())
226 } else {
227 for (_, o) in (0..self_buf_len).zip(&mut buf[..self_buf_len]) {
228 *o = self.buf.remove(0)
229 }
230 Ok(self_buf_len)
231 }
232 }
233}
234
235impl<'a, V: LittleValue> io::Read for InterpreterStream<'a, V> {
236 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
237 loop {
238 if self.buf.len() >= buf.len() {
239 break;
240 }
241
242 match self.execute() {
243 Ok(res) => match res {
244 ExecutionResult::Done => return self.consume_buf(buf),
245 ExecutionResult::Continue => (),
246 ExecutionResult::Interupt => return Err(io::Error::new(io::ErrorKind::Other, LittleError::Interupt)),
247 },
248 Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidInput, e)),
249 }
250 }
251
252 self.consume_buf(buf)
253 }
254}
255
256struct Values<'a, V: 'a> {
257 stack: Vec<V>,
258 values: Vec<V>,
259 parameters: V,
260 executable: &'a Executable<'a, V>,
261}
262
263impl<'a, V: LittleValue> Values<'a, V> {
264 fn get_mem_value(&self, mem: &Mem) -> Result<Cow<V>, LittleError> {
265 Ok(match *mem {
266 Mem::Binding(i) => self.get(i),
267 Mem::Parameter { name } => {
268 unreachable!("get_mem_value Parameter not implemented")
269 },
278 Mem::Parameters => { Cow::Borrowed(&self.parameters) },
279 Mem::Const(i) => match self.executable.constants.get(i) {
280 Some(value) => Cow::Borrowed(value),
281 None => return Err(LittleError::ConstantMissing(i)),
282 },
283 Mem::StackTop1 => match self.stack.last() {
284 Some(value) => Cow::Borrowed(value),
285 None => return Err(LittleError::StackUnderflow),
286 },
287 Mem::StackTop2 => match self.stack.get(self.stack.len() - 2) {
288 Some(value) => Cow::Borrowed(value),
289 None => return Err(LittleError::StackUnderflow),
290 },
291 })
292 }
293
294 fn set(&mut self, Binding(index): Binding, value: V) {
295 let i = index as usize;
296 self.ensure_capacity_for_index(i);
297 * unsafe { self.values.get_unchecked_mut(i) } = value;
298 }
299
300 fn get<'r>(&'r self, Binding(index): Binding) -> Cow<'r, V> {
301 let i = index as usize;
302 if i >= self.values.len() {
303 Cow::Owned(V::default())
304 } else {
305 Cow::Borrowed(self.values.get(i).unwrap())
306 }
307 }
308
309 #[cfg(feature="nightly")]
310 fn ensure_capacity_for_index(&mut self, index: usize) {
311 let required_len = index + 1;
312 if required_len > MAX_VALUES {
313 panic!("maximum number of values {} reached!", MAX_VALUES);
314 }
315 if required_len > self.values.len() {
316 self.values.resize(required_len, V::default());
317 }
318 }
319
320 #[cfg(not(feature="nightly"))]
321 fn ensure_capacity_for_index(&mut self, index: usize) {
322 use std::iter;
323
324 let required_len = index + 1;
325 if required_len > MAX_VALUES {
326 panic!("maximum number of values {} reached!", MAX_VALUES);
327 }
328 if required_len > self.values.len() {
329 let missing_len = required_len - self.values.len();
330 self.values.reserve(missing_len);
331 self.values.extend(iter::repeat(V::default()).take(missing_len));
332 }
333 }
334}