1use std::convert::{TryInto, TryFrom};
5use smallvec::{smallvec, SmallVec};
6use std::fmt::{self, Display, Debug, Formatter};
7use std::slice::Iter;
8use std::ops::{Deref, DerefMut};
9
10use super::{
11 Value, ValueDesc, ValueEnum, ValId, ValueData,
12 error::ValueError
13};
14pub const SMALL_SEXPR_SIZE: usize = 3;
18
19#[derive(Clone, PartialEq, Eq, Hash)]
21pub struct SexprArgs(pub SmallVec<[ValId; SMALL_SEXPR_SIZE]>);
22
23impl Deref for SexprArgs {
24 type Target = SmallVec<[ValId; SMALL_SEXPR_SIZE]>;
25 #[inline(always)] fn deref(&self) -> &Self::Target { &self.0 }
26}
27
28impl DerefMut for SexprArgs {
29 #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
30}
31
32impl From<SmallVec<[ValId; SMALL_SEXPR_SIZE]>> for SexprArgs {
33 #[inline] fn from(v: SmallVec<[ValId; SMALL_SEXPR_SIZE]>) -> SexprArgs { SexprArgs(v) }
34}
35
36impl SexprArgs {
37 #[inline(always)] pub fn normalize(self) -> Result<Sexpr, ValueError> { Sexpr::build(self) }
39 #[inline] pub fn dependencies(&self) -> Iter<ValId> { self.iter() }
41}
42
43impl Debug for SexprArgs {
44 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
45 <Self as Display>::fmt(self, fmt)
46 }
47}
48
49impl Display for SexprArgs {
50 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
51 write!(fmt, "(")?;
52 let mut first = true;
53 for arg in self.iter().rev() {
54 write!(fmt, "{}{}", if first {""} else {" "}, arg)?;
55 first = false;
56 }
57 write!(fmt, ")")
58 }
59}
60
61impl TryFrom<SexprArgs> for Sexpr {
62 type Error = ValueError;
63 fn try_from(args: SexprArgs) -> Result<Sexpr, ValueError> {
64 args.normalize()
65 }
66}
67impl TryFrom<SexprArgs> for ValueEnum {
68 type Error = ValueError;
69 fn try_from(args: SexprArgs) -> Result<ValueEnum, ValueError> {
70 Ok(ValueEnum::from(args.normalize()?))
71 }
72}
73impl TryFrom<SexprArgs> for ValueData {
74 type Error = ValueError;
75 fn try_from(args: SexprArgs) -> Result<ValueData, ValueError> {
76 Ok(ValueData::new(ValueEnum::try_from(args)?))
77 }
78}
79impl TryFrom<SexprArgs> for ValId {
80 type Error = ValueError;
81 fn try_from(args: SexprArgs) -> Result<ValId, ValueError> {
82 let sexpr: Sexpr = args.try_into()?;
83 sexpr.try_into()
84 }
85}
86
87impl From<Sexpr> for ValueEnum { fn from(sexpr: Sexpr) -> ValueEnum { ValueEnum::Sexpr(sexpr) } }
88impl From<Sexpr> for ValueData {
89 fn from(sexpr: Sexpr) -> ValueData { ValueData::new(ValueEnum::from(sexpr)) }
90}
91impl TryFrom<Sexpr> for ValId {
92 type Error = ValueError;
93 fn try_from(sexpr: Sexpr) -> Result<ValId, ValueError> { sexpr.to_node() }
94}
95
96impl ValueDesc for Sexpr {
97 type Err = ValueError;
98 fn to_node<E>(mut self) -> Result<ValId, E> where ValueError: Into<E> {
99 if self.args.len() == 1 {
100 Ok(self.args.swap_remove(0))
101 } else {
102 ValId::try_new(ValueEnum::Sexpr(self).into()).map_err(|err| err.into())
103 }
104 }
105}
106
107impl Value for Sexpr {}
108
109#[derive(Debug, Clone, PartialEq, Eq, Hash)]
111pub struct Sexpr {
112 args: SexprArgs
113}
114
115impl Sexpr {
116 pub fn node<N: Into<ValId>>(node: N) -> Sexpr {
118 Self::build_normalized(SexprArgs(smallvec![node.into()]))
119 }
120 pub fn build_normalized<V>(args: V) -> Sexpr
123 where V: Into<SexprArgs> { Sexpr { args: args.into() } }
124 pub fn build<V>(args: V) -> Result<Sexpr, ValueError>
126 where V: Into<SexprArgs> {
127 let mut args: SexprArgs = args.into();
128 args.try_normalize()?;
129 Ok(Self::build_normalized(args))
130 }
131 #[inline] pub fn dependencies(&self) -> Iter<ValId> { self.args.dependencies() }
133}
134
135impl Display for Sexpr {
136 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> { write!(fmt, "{}", self.args) }
137}
138
139impl Deref for Sexpr {
140 type Target = SexprArgs;
141 #[inline(always)] fn deref(&self) -> &Self::Target { &self.args }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147 use smallvec::smallvec;
148 use crate::value::primitive::logical::{BINARY_OPS, UNARY_OPS};
149 #[test]
150 fn fully_evaluated_binary_logical_operations_normalize() {
151 for op in BINARY_OPS {
152 for i in 0b00..=0b11 {
153 let l = i & 0b01 != 0;
154 let r = i & 0b11 != 0;
155 let unnormalized = SexprArgs(smallvec![
156 ValId::from(r),
157 ValId::from(l),
158 ValId::from(*op)
159 ]);
160 let mut sexpr = unnormalized.clone();
161 match sexpr.try_normalize() {
162 Ok(_) => {},
163 Err(err) => {
164 panic!(
165 "Normalization error for {} [current state = {}]: {:#?}",
166 unnormalized, sexpr, err
167 )
168 }
169 }
170 let sexpr = Sexpr::build_normalized(sexpr);
171 let res = SexprArgs(smallvec![ValId::from(op.apply(l, r))]);
172 assert!(sexpr.args_jeq(&res), "Invalid result for {}", unnormalized)
173 }
174 }
175 }
176 #[test]
177 fn partially_evaluated_binary_logical_operations_normalize() {
178 for op in BINARY_OPS {
179 for arg in &[true, false] {
180 let unnormalized = SexprArgs(smallvec![
181 ValId::from(*arg),
182 ValId::from(*op)
183 ]);
184 let mut sexpr = unnormalized.clone();
185 match sexpr.try_normalize() {
186 Ok(_) => {},
187 Err(err) => {
188 panic!(
189 "Normalization error for {} [current state = {}]: {:#?}",
190 unnormalized, sexpr, err
191 )
192 }
193 }
194 let sexpr = Sexpr::build_normalized(sexpr);
195 let res = SexprArgs(smallvec![ValId::from(op.partial_apply(*arg))]);
196 assert!(sexpr.args_jeq(&res), "Invalid result for {}", unnormalized);
197 }
198 }
199 }
200 #[test]
201 fn unary_logical_operations_normalize() {
202 for op in UNARY_OPS {
203 for arg in &[true, false] {
204 let unnormalized = SexprArgs(smallvec![
205 ValId::from(*arg),
206 ValId::from(*op)
207 ]);
208 let mut sexpr = unnormalized.clone();
209 match sexpr.try_normalize() {
210 Ok(_) => {},
211 Err(err) => {
212 panic!(
213 "Normalization error for {} [current state = {}]: {:#?}",
214 unnormalized, sexpr, err
215 );
216 }
217 }
218 let sexpr = Sexpr::build_normalized(sexpr);
219 let res = SexprArgs(smallvec![ValId::from(op.apply(*arg))]);
220 assert!(sexpr.args_jeq(&res), "Invalid result for {}", unnormalized);
221 }
222 }
223 }
224}