1use std::convert::Infallible;
5use std::borrow::Borrow;
6use smallvec::{smallvec, SmallVec};
7use std::hash::Hash;
8use super::symbol_table::SymbolTable;
9use super::ast::{Expr, Sexpr, Path, Let, Pattern, SimpleAssignment, Scope};
10use crate::value::{
11 ValueDesc, ValId,
12 error::ValueError,
13 expr::SexprArgs
14};
15
16#[derive(Debug, Clone)]
18pub struct Builder<S: Eq + Hash> {
19 symbols: SymbolTable<S, ValId>
20}
21
22#[derive(Debug, Clone)]
24pub enum BuilderError<'a> {
25 ValueError(ValueError),
27 SymbolUndefined(&'a str),
29 BuildNotImplemented
31}
32
33impl<'a> From<ValueError> for BuilderError<'a> {
34 fn from(err: ValueError) -> BuilderError<'a> { BuilderError::ValueError(err) }
35}
36
37impl<'a> From<Infallible> for BuilderError<'a> {
38 fn from(err: Infallible) -> BuilderError<'a> { match err {} }
39}
40
41impl<'a> BuilderError<'a> {
42 pub fn val<E: Into<ValueError>>(err: E) -> BuilderError<'a>
44 { BuilderError::ValueError(err.into()) }
45}
46
47pub const SMALL_DEFINITIONS: usize = 1;
49
50#[derive(Debug, Clone)]
52pub struct Definition<'a> {
53 pub name: &'a str,
55 pub value: ValId,
57 pub previous: Option<ValId>
59}
60
61impl<'a, S: Eq + Hash + From<&'a str> + Borrow<str>> Builder<S> {
62 pub fn new() -> Builder<S> {
64 Builder {
65 symbols: SymbolTable::new()
66 }
67 }
68 pub fn build_let(&mut self, let_statement: &Let<'a>) ->
71 Result<SmallVec<[Definition<'a>; SMALL_DEFINITIONS]>, BuilderError<'a>> {
72 self.assign_pattern(&let_statement.pattern, &let_statement.expr)
73 }
74 pub fn assign_pattern(&mut self, pattern: &Pattern<'a>, expr: &Expr<'a>) ->
77 Result<SmallVec<[Definition<'a>; SMALL_DEFINITIONS]>, BuilderError<'a>> {
78 match pattern {
79 Pattern::Simple(simple_assignment) =>
80 self.build_simple_assign(simple_assignment, expr)
81 .map(|assigned| smallvec![assigned])
82 }
83 }
84 pub fn build_simple_assign(&mut self, simple: &SimpleAssignment<'a>, expr: &Expr<'a>)
86 -> Result<Definition<'a>, BuilderError<'a>> {
87 let name = simple.name;
89 let value = self.build_expr(expr)?;
90 let previous = self.symbols.def(S::from(name), value.clone());
91 Ok(Definition{ name, value, previous })
92 }
93 pub fn build_expr(&mut self, expr: &Expr<'a>) -> Result<ValId, BuilderError<'a>> {
95 use Expr::*;
96 match expr {
97 Bool(b) => b.to_node(),
98 BoolTy(b) => b.to_node(),
99 LogicalOp(l) => l.to_node(),
100 Path(p) => self.lookup_path(p),
101 Sexpr(s) => self.build_sexpr(s),
102 Scope(s) => self.build_scope(s),
103 _ => Err(BuilderError::BuildNotImplemented)
104 }
105 }
106 pub fn build_scope(&mut self, scope: &Scope<'a>) -> Result<ValId, BuilderError<'a>> {
108 self.symbols.push(); for def in scope.definitions.iter() { self.build_let(def)?; }
111 let res = if let Some(value) = &scope.value {
113 self.build_expr(value)
114 } else {
115 Err(BuilderError::BuildNotImplemented)
117 };
118 self.symbols.pop(); res
120 }
121 pub fn lookup_path(&self, path: &Path<'a>) -> Result<ValId, BuilderError<'a>> {
123 if path.names.len() == 1 {
124 let name = path.names[0];
125 self.symbols.get(name).cloned().ok_or(BuilderError::SymbolUndefined(name))
126 } else {
127 Err(BuilderError::BuildNotImplemented)
128 }
129 }
130 pub fn build_sexpr(&mut self, sexpr: &Sexpr<'a>) -> Result<ValId, BuilderError<'a>> {
132 let args = self.build_sexpr_args(sexpr)?;
133 let sexpr = args.normalize().map_err(BuilderError::ValueError)?;
134 sexpr.to_node()
135 }
136 pub fn build_sexpr_args(&mut self, sexpr: &Sexpr<'a>) -> Result<SexprArgs, BuilderError<'a>> {
138 let mut ops = SmallVec::new();
139 for op in sexpr.ops.iter().map(|op| self.build_expr(op)) {
140 match op {
141 Ok(op) => ops.push(op),
142 Err(err) => return Err(err)
143 }
144 }
145 Ok(SexprArgs(ops))
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152 use crate::parser::{parse_expr, parse_statement};
153
154 #[test]
155 fn simple_logical_expressions_build_properly() {
156 let mut builder = Builder::<&str>::new();
157 let t = &ValId::from(true);
158 let f = &ValId::from(false);
159 let logical_expressions = [
160 ("(#and #true #false)", f),
161 ("(#or #true #false)", t),
162 ("(#not #true)", f),
163 ("(#not #false)", t),
164 ("(#xor #true #true)", f),
165 ("(#or (#or #false #true) (#xor #false #false))", t)
166 ];
167 for (expr, result) in logical_expressions.iter() {
168 let expr = match parse_expr(expr) {
169 Ok((rest, expr)) => {
170 assert_eq!(
171 rest, "",
172 "Did not parse all of valid expression \"{}\": remainder = {:?}",
173 expr, rest
174 );
175 expr
176 },
177 Err(err) => panic!("Got parse error {:?} for valid expression \"{}\"", err, expr)
178 };
179 let built = match builder.build_expr(&expr) {
180 Ok(built) => built,
181 Err(err) => panic!("Valid expression \"{}\" gives build error: {:#?}", expr, err)
182 };
183 assert_eq!(&built, *result);
184 }
185 }
186
187 #[test]
188 fn simple_assignments_build_properly() {
189 let mut builder = Builder::<&str>::new();
190 let program = [
191 "let false = (#or #false #false);",
192 "let true = (#and #true (#and #true #true));",
193 "let x = (#xor true false);",
194 "let y = (#xor true true);"
195 ];
196 for line in program.iter() {
197 let l = match parse_statement(line) {
198 Ok((rest, l)) => {
199 assert_eq!(
200 rest, "",
201 "Unparsed portion {:?} of valid let \"{}\"",
202 rest, line
203 );
204 l
205 },
206 Err(err) =>
207 panic!("Valid let \"{}\" gives parse error: {:#?}", line, err)
208 };
209 match builder.build_let(&l) {
210 Ok(_) => {},
211 Err(err) => panic!("Valid let \"{}\" gives build error: {:#?}", line, err)
212 };
213 }
214 let t = &ValId::from(true);
215 let f = &ValId::from(false);
216 let variables = [
217 ("true", t), ("false", f), ("x", t), ("y", f)
218 ];
219 for (variable, value) in variables.iter() {
220 match builder.build_expr(&parse_expr(variable).expect("Valid identifier").1) {
221 Ok(built) => assert_eq!(
222 &built, *value,
223 "Invalid variable assignment {} = {} != {}", variable, built, value),
224 Err(err) => panic!("Error looking up variable {}: {:#?}", variable, err)
225 }
226 }
227 }
228}