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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use ketos::{
Error,
Interpreter,
ModuleLoader,
FromValue,
};
use std::collections::HashSet;
use std::io::prelude::*;
use std::io::BufReader;
use std::fmt::Debug;
use std::fs::File;
use std::rc::Rc;
use std::cell::RefCell;
use tree::{
Tree,
Expression,
};
use treeerror::{
TreeError,
TreeErrorKind,
};
pub struct TreeBuilder {
kcode: String,
prologue: String,
epilogue: String,
}
impl TreeBuilder {
pub fn new(body: &str) -> TreeBuilder {
TreeBuilder {
kcode: body.to_string(),
prologue: "".to_string(),
epilogue: "".to_string(),
}
}
pub fn from_file(path: &str) -> Result<TreeBuilder, ::std::io::Error> {
let kf = File::open(path)?;
let mut reader = BufReader::new(kf);
let mut kfiledata = String::new();
reader.read_to_string(&mut kfiledata)?;
Ok(TreeBuilder {
kcode: kfiledata,
prologue: "".to_string(),
epilogue: "".to_string(),
})
}
pub fn set_prologue(&mut self, s: &str) {
self.prologue = s.to_string();
}
pub fn set_epilogue(&mut self, s: &str) {
self.epilogue = s.to_string();
}
pub fn use_box_and_name<T, B>(&self, cml: Box<B>, tree_name: &str) -> Result<(Tree<T>, HashSet<String>), Error>
where T: 'static + Clone + Debug,
B: 'static + ModuleLoader
{
self.use_opts(cml, None, tree_name)
}
pub fn use_box_set_and_name<T, B>(&self, cml: Box<B>, var_set: HashSet<String>, tree_name: &str) -> Result<(Tree<T>, HashSet<String>), Error>
where T: 'static + Clone + Debug,
B: 'static + ModuleLoader
{
self.use_opts(cml, Some(var_set), tree_name)
}
fn use_opts<T, B>(&self, cml: Box<B>, var_set: Option<HashSet<String>>, tree_name: &str) -> Result<(Tree<T>, HashSet<String>), Error>
where T: 'static + Clone + Debug,
B: 'static + ModuleLoader
{
let result: (Tree<T>, HashSet<String>);
{
let interp = Interpreter::with_loader(cml);
let vs = match var_set {
Some(vset) => vset,
None => HashSet::<String>::new(),
};
let varcont = Rc::new(RefCell::new(vs));
let varcontc = varcont.clone();
let var_fn = move |s: &str| -> Result<Tree<T>, Error> {
varcontc.borrow_mut().insert(s.to_string());
Ok(Tree::<T>::new(Expression::Variable(s.to_string())))
};
ketos_fn!{ interp.scope() => "var" => fn var_fn(s: &str) -> Tree<T> }
interp.run_code(&format!("{}\n{}\n{}", self.prologue, self.kcode, self.epilogue), None)?;
let m = Tree::from_value(match interp.get_value(tree_name) {
Some(n) => n,
None => { return Err(Error::custom(TreeError::create(TreeErrorKind::TreeNotInScope))); },
})?;
result = (m, varcont.borrow().clone());
}
Ok(result)
}
}