git.delta.rocks / jrsonnet / refs/commits / d9acc2cd1f1d

difftreelog

feat peg parsing for types

Yaroslav Bolyukin2021-01-12parent: #fe95a60.patch.diff
in: master

3 files changed

modifiedcrates/jrsonnet-evaluator/src/typed.rsdiffbeforeafterboth
158 Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())158 Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())
159 }159 }
160 }160 }
161 ComplexValType::Array(elem_type) => match value {
162 Val::Arr(a) => {
163 for (i, item) in a.iter().enumerate() {
164 push_type(
165 &None,
166 || format!("array index {}", i),
167 || ValuePathItem::Index(i as u64),
168 || Ok(elem_type.check(&item.clone()?)?),
169 )?;
170 }
171 Ok(())
172 }
173 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
174 },
161 ComplexValType::ArrayRef(elem_type) => match value {175 ComplexValType::ArrayRef(elem_type) => match value {
162 Val::Arr(a) => {176 Val::Arr(a) => {
163 for (i, item) in a.iter().enumerate() {177 for (i, item) in a.iter().enumerate() {
192 }206 }
193 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),207 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
194 },208 },
209 ComplexValType::Union(types) => {
210 let mut errors = Vec::new();
211 for ty in types.iter() {
212 match ty.check(value) {
213 Ok(()) => {
214 return Ok(());
215 }
216 Err(e) => match e.error() {
217 Error::TypeError(e) => errors.push(e.clone()),
218 _ => return Err(e),
219 },
220 }
221 }
222 return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());
223 }
195 ComplexValType::UnionRef(types) => {224 ComplexValType::UnionRef(types) => {
196 let mut errors = Vec::new();225 let mut errors = Vec::new();
197 for ty in types.iter() {226 for ty in types.iter() {
207 }236 }
208 return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());237 return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());
209 }238 }
239 ComplexValType::Sum(types) => {
240 for ty in types.iter() {
241 ty.check(value)?
242 }
243 Ok(())
244 }
210 ComplexValType::SumRef(types) => {245 ComplexValType::SumRef(types) => {
211 for ty in types.iter() {246 for ty in types.iter() {
212 ty.check(value)?247 ty.check(value)?
modifiedcrates/jrsonnet-types/Cargo.tomldiffbeforeafterboth
5edition = "2018"5edition = "2018"
66
7[dependencies]7[dependencies]
88peg = "0.6.3"
modifiedcrates/jrsonnet-types/src/lib.rsdiffbeforeafterboth
110 Char,110 Char,
111 Simple(ValType),111 Simple(ValType),
112 BoundedNumber(Option<f64>, Option<f64>),112 BoundedNumber(Option<f64>, Option<f64>),
113 Array(Box<ComplexValType>),
113 ArrayRef(&'static ComplexValType),114 ArrayRef(&'static ComplexValType),
114 ObjectRef(&'static [(&'static str, ComplexValType)]),115 ObjectRef(&'static [(&'static str, ComplexValType)]),
116 Union(Vec<ComplexValType>),
115 UnionRef(&'static [ComplexValType]),117 UnionRef(&'static [ComplexValType]),
118 Sum(Vec<ComplexValType>),
116 SumRef(&'static [ComplexValType]),119 SumRef(&'static [ComplexValType]),
117}120}
118impl From<ValType> for ComplexValType {121impl From<ValType> for ComplexValType {
128) -> std::fmt::Result {131) -> std::fmt::Result {
129 for (i, v) in union.iter().enumerate() {132 for (i, v) in union.iter().enumerate() {
130 let should_add_braces = match v {133 let should_add_braces = match v {
131 ComplexValType::UnionRef(_) if !is_union => true,134 ComplexValType::UnionRef(_) | ComplexValType::Union(_) if !is_union => true,
132 _ => false,135 _ => false,
133 };136 };
134 if i != 0 {137 if i != 0 {
145 Ok(())148 Ok(())
146}149}
150
151fn print_array(a: &ComplexValType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
152 if *a == ComplexValType::Any {
153 write!(f, "array")?
154 } else {
155 write!(f, "Array<{}>", a)?
156 }
157 Ok(())
158}
147159
148impl Display for ComplexValType {160impl Display for ComplexValType {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),169 a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),
158 b.map(|e| e.to_string()).unwrap_or_else(|| "".into())170 b.map(|e| e.to_string()).unwrap_or_else(|| "".into())
159 )?,171 )?,
160 ComplexValType::ArrayRef(a) => {172 ComplexValType::ArrayRef(a) => print_array(a, f)?,
161 if **a == ComplexValType::Any {173 ComplexValType::Array(a) => print_array(a, f)?,
162 write!(f, "array")?
163 } else {
164 write!(f, "Array<{}>", a)?
165 }
166 }
167 ComplexValType::ObjectRef(fields) => {174 ComplexValType::ObjectRef(fields) => {
168 write!(f, "{{")?;175 write!(f, "{{")?;
169 for (i, (k, v)) in fields.iter().enumerate() {176 for (i, (k, v)) in fields.iter().enumerate() {
174 }181 }
175 write!(f, "}}")?;182 write!(f, "}}")?;
176 }183 }
184 ComplexValType::Union(v) => write_union(f, true, v)?,
177 ComplexValType::UnionRef(v) => write_union(f, true, v)?,185 ComplexValType::UnionRef(v) => write_union(f, true, v)?,
186 ComplexValType::Sum(v) => write_union(f, false, v)?,
178 ComplexValType::SumRef(v) => write_union(f, false, v)?,187 ComplexValType::SumRef(v) => write_union(f, false, v)?,
179 };188 };
180 Ok(())189 Ok(())
181 }190 }
182}191}
183192
193peg::parser!{
194pub grammar parser() for str {
195 rule number() -> f64
196 = n:$(['0'..='9']+) { n.parse().unwrap() }
197
198 rule any_ty() -> ComplexValType = "any" { ComplexValType::Any }
199 rule char_ty() -> ComplexValType = "character" { ComplexValType::Char }
200 rule bool_ty() -> ComplexValType = "boolean" { ComplexValType::Simple(ValType::Bool) }
201 rule null_ty() -> ComplexValType = "null" { ComplexValType::Simple(ValType::Null) }
202 rule str_ty() -> ComplexValType = "string" { ComplexValType::Simple(ValType::Str) }
203 rule num_ty() -> ComplexValType = "number" { ComplexValType::Simple(ValType::Num) }
204 rule simple_array_ty() -> ComplexValType = "array" { ComplexValType::Simple(ValType::Arr) }
205 rule simple_object_ty() -> ComplexValType = "object" { ComplexValType::Simple(ValType::Obj) }
206 rule simple_function_ty() -> ComplexValType = "function" { ComplexValType::Simple(ValType::Func) }
207
208 rule array_ty() -> ComplexValType
209 = "Array<" t:ty() ">" { ComplexValType::Array(Box::new(t)) }
210
211 rule bounded_number_ty() -> ComplexValType
212 = "BoundedNumber<" a:number() ", " b:number() ">" { ComplexValType::BoundedNumber(Some(a), Some(b)) }
213
214 rule ty_basic() -> ComplexValType
215 = any_ty()
216 / char_ty()
217 / bool_ty()
218 / null_ty()
219 / str_ty()
220 / num_ty()
221 / simple_array_ty()
222 / simple_object_ty()
223 / simple_function_ty()
224 / array_ty()
225 / bounded_number_ty()
226
227 pub rule ty() -> ComplexValType
228 = precedence! {
229 a:(@) " | " b:@ {
230 match a {
231 ComplexValType::Union(mut a) => {
232 a.push(b);
233 ComplexValType::Union(a)
234 }
235 _ => ComplexValType::Union(vec![a, b]),
236 }
237 }
238 --
239 a:(@) " & " b:@ {
240 match a {
241 ComplexValType::Sum(mut a) => {
242 a.push(b);
243 ComplexValType::Sum(a)
244 }
245 _ => ComplexValType::Sum(vec![a, b]),
246 }
247 }
248 --
249 "(" t:ty() ")" { t }
250 t:ty_basic() { t }
251 }
252}
253}
254
255#[cfg(test)]
256pub mod tests {
257 use super::parser;
258
259 #[test]
260 fn precedence() {
261 assert_eq!(parser::ty("(any & any) | (any | any) & any").unwrap().to_string(), "any & any | (any | any) & any");
262 }
263
264 #[test]
265 fn array() {
266 assert_eq!(parser::ty("Array<any>").unwrap().to_string(), "array");
267 assert_eq!(parser::ty("Array<number>").unwrap().to_string(), "Array<number>");
268 }
269 #[test]
270 fn bounded_number() {
271 assert_eq!(parser::ty("BoundedNumber<1, 2>").unwrap().to_string(), "BoundedNumber<1, 2>");
272 }
273}