1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::io::{self, Read, Write};
use std::cell::RefCell;
use std::rc::Rc;
use sindra::Identifier;
use sindra::log::LogListener;
use sindra::scope::{MemoryScope, SymbolStore};
use Symbol;
use PType;
use value::Value;
use visitor::interp::StdFuncTable;
use psk_std::Environment;
pub struct State {
pub scope: Rc<RefCell<MemoryScope<Symbol, Value>>>,
pub global: Rc<RefCell<MemoryScope<Symbol, Value>>>,
pub logger: LogListener<String, io::Stdout, io::Stderr>,
pub std_funcs: StdFuncTable,
pub std_env: Environment,
pub io: Io,
pub loop_depth: usize,
}
impl Default for State {
fn default() -> State {
let global = Rc::new(RefCell::new(MemoryScope::default()));
let env = Environment::default();
let std_funcs = StdFuncTable::new(&mut *global.borrow_mut());
let mut state = State {
scope: Rc::clone(&global),
global: global,
logger: LogListener::new(io::stdout(), io::stderr()),
std_funcs: std_funcs,
std_env: env,
io: Io::default(),
loop_depth: 0,
};
state.define_builtins();
state
}
}
impl State {
pub fn define_builtins(&mut self) {
let mut sc = self.scope.borrow_mut();
sc.define(Identifier("int".to_string()), Symbol::builtin(Identifier("int".to_string()),
PType::Int));
sc.define(Identifier("float".to_string()), Symbol::builtin(Identifier("float".to_string()),
PType::Float));
sc.define(Identifier("bool".to_string()), Symbol::builtin(Identifier("bool".to_string()),
PType::Boolean));
sc.define(Identifier("complex".to_string()),
Symbol::builtin(Identifier("complex".to_string()), PType::Boolean));
sc.define(Identifier("string".to_string()),
Symbol::builtin(Identifier("string".to_string()), PType::String));
}
}
pub struct Io {
stdin: Box<Read>,
stdout: Box<Write>,
stderr: Box<Write>,
}
impl Default for Io {
fn default() -> Io {
Io {
stdin: Box::new(io::stdin()),
stdout: Box::new(io::stdout()),
stderr: Box::new(io::stderr()),
}
}
}
impl Io {
pub fn set_stdin<R: 'static + Read>(&mut self, input: R) {
self.stdin = Box::new(input);
}
pub fn set_stdout<W: 'static + Write>(&mut self, out: W) {
self.stdout = Box::new(out);
}
pub fn set_stderr<W: 'static + Write>(&mut self, err: W) {
self.stderr = Box::new(err);
}
pub fn stdin(&mut self) -> &mut Read { self.stdin.as_mut() }
pub fn stdout(&mut self) -> &mut Write { self.stdout.as_mut() }
pub fn stderr(&mut self) -> &mut Write { self.stderr.as_mut() }
}