1use std::cell::RefCell;
8use std::cmp::{Ord, Ordering};
9use std::collections::{HashMap, HashSet};
10use std::convert::{From, TryInto};
11use std::env;
12use std::fmt::{self, Write};
13use std::fs::{canonicalize, File};
14use std::io::{self, BufRead, BufReader, Cursor, Error, ErrorKind, Read, Result};
15use std::path::{Path, PathBuf};
16use std::rc::Rc;
17use std::result::Result as StdResult;
18
19use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime};
20use lazy_static::lazy_static;
21use num_complex::Complex64;
22use regex::{Captures, Regex};
23
24const UTF8_ACCEPT: u32 = 0;
29const UTF8_REJECT: u32 = 12;
30
31lazy_static! {
32 static ref UTF8_LOOKUP: [u8; 364] = {
68 let mut map = [0u8; 364];
69 for i in 128..144 {
70 map[i] = 1;
71 }
72 for i in 144..160 {
73 map[i] = 9;
74 }
75 for i in 160..192 {
76 map[i] = 7;
77 }
78 map[192] = 8;
79 map[193] = 8;
80 for i in 194..224 {
81 map[i] = 2;
82 }
83 map[224] = 10;
84 for i in 225..240 {
85 map[i] = 3;
86 }
87 map[237] = 4;
88 map[240] = 11;
89 for i in 241..244 {
90 map[i] = 6;
91 }
92 map[244] = 5;
93 for i in 245..256 {
94 map[i] = 8;
95 }
96 for i in 256..260 {
97 map[i] = ((i - 256) * 12) as u8;
98 }
99 map[260] = 60;
100 map[261] = 96;
101 map[262] = 84;
102 for i in 263..364 {
103 map[i] = 12;
104 }
105 map[266] = 48;
106 map[267] = 72;
107 map[281] = 0;
108 map[287] = 0;
109 map[289] = 0;
110 map[293] = 24;
111 map[299] = 24;
112 map[301] = 24;
113 map[311] = 24;
114 map[317] = 24;
115 map[325] = 24;
116 map[335] = 36;
117 map[337] = 36;
118 map[341] = 36;
119 map[347] = 36;
120 map[349] = 36;
121 map[353] = 36;
122 map
123 };
124
125 static ref PUNCTUATION: HashMap<char, TokenKind> = {
126 let mut map = HashMap::new();
127
128 map.insert(':', TokenKind::Colon);
129 map.insert('-', TokenKind::Minus);
130 map.insert('+', TokenKind::Plus);
131 map.insert('*', TokenKind::Star);
132 map.insert('/', TokenKind::Slash);
133 map.insert('%', TokenKind::Modulo);
134 map.insert(',', TokenKind::Comma);
135 map.insert('{', TokenKind::LeftCurly);
136 map.insert('}', TokenKind::RightCurly);
137 map.insert('[', TokenKind::LeftBracket);
138 map.insert(']', TokenKind::RightBracket);
139 map.insert('(', TokenKind::LeftParenthesis);
140 map.insert(')', TokenKind::RightParenthesis);
141 map.insert('@', TokenKind::At);
142 map.insert('$', TokenKind::Dollar);
143 map.insert('<', TokenKind::LessThan);
144 map.insert('>', TokenKind::GreaterThan);
145 map.insert('!', TokenKind::Not);
146 map.insert('~', TokenKind::BitwiseComplement);
147 map.insert('&', TokenKind::BitwiseAnd);
148 map.insert('|', TokenKind::BitwiseOr);
149 map.insert('^', TokenKind::BitwiseXor);
150 map.insert('.', TokenKind::Dot);
151 map
152 };
153
154 static ref KEYWORDS: HashMap<String, TokenKind> = {
155 let mut map = HashMap::new();
156
157 map.insert("true".to_string(), TokenKind::True);
158 map.insert("false".to_string(), TokenKind::False);
159 map.insert("null".to_string(), TokenKind::None);
160 map.insert("is".to_string(), TokenKind::Is);
161 map.insert("in".to_string(), TokenKind::In);
162 map.insert("not".to_string(), TokenKind::Not);
163 map.insert("and".to_string(), TokenKind::And);
164 map.insert("or".to_string(), TokenKind::Or);
165 map
166 };
167
168 static ref KEYWORD_VALUES: HashMap<String, ScalarValue> = {
169 let mut map = HashMap::new();
170
171 map.insert("true".to_string(), ScalarValue::Bool(true));
172 map.insert("false".to_string(), ScalarValue::Bool(false));
173 map.insert("null".to_string(), ScalarValue::Null);
174 map
175 };
176
177 static ref EXPRESSION_STARTERS: HashSet<TokenKind> = {
178 let mut set = HashSet::new();
179
180 set.insert(TokenKind::LeftCurly);
181 set.insert(TokenKind::LeftCurly);
182 set.insert(TokenKind::LeftBracket);
183 set.insert(TokenKind::LeftParenthesis);
184 set.insert(TokenKind::At);
185 set.insert(TokenKind::Dollar);
186 set.insert(TokenKind::BackTick);
187 set.insert(TokenKind::Plus);
188 set.insert(TokenKind::Minus);
189 set.insert(TokenKind::BitwiseComplement);
190 set.insert(TokenKind::Number);
191 set.insert(TokenKind::Complex);
192 set.insert(TokenKind::True);
193 set.insert(TokenKind::False);
194 set.insert(TokenKind::None);
195 set.insert(TokenKind::Not);
196 set.insert(TokenKind::String);
197 set.insert(TokenKind::Word);
198 set
199 };
200
201 static ref VALUE_STARTERS: HashSet<TokenKind> = {
202 let mut set = HashSet::new();
203
204 set.insert(TokenKind::Word);
205 set.insert(TokenKind::Number);
206 set.insert(TokenKind::Complex);
207 set.insert(TokenKind::String);
208 set.insert(TokenKind::BackTick);
209 set.insert(TokenKind::None);
210 set.insert(TokenKind::True);
211 set.insert(TokenKind::False);
212 set
213 };
214
215 static ref COMPARISON_OPERATORS: HashSet<TokenKind> = {
216 let mut set = HashSet::new();
217
218 set.insert(TokenKind::LessThan);
219 set.insert(TokenKind::LessThanOrEqual);
220 set.insert(TokenKind::GreaterThan);
221 set.insert(TokenKind::GreaterThanOrEqual);
222 set.insert(TokenKind::Equal);
223 set.insert(TokenKind::Unequal);
224 set.insert(TokenKind::AltUnequal);
225 set.insert(TokenKind::Is);
226 set.insert(TokenKind::In);
227 set.insert(TokenKind::Not);
228 set
229 };
230
231 static ref ESCAPES: HashMap<char, char> = {
232 let mut map = HashMap::new();
233
234 map.insert('a', '\u{0007}');
235 map.insert('b', '\u{0008}');
236 map.insert('f', '\u{000C}');
237 map.insert('n', '\n');
238 map.insert('r', '\r');
239 map.insert('t', '\t');
240 map.insert('v', '\u{000B}');
241 map.insert('\\', '\\');
242 map.insert('\'', '\'');
243 map.insert('"', '"');
244 map
245 };
246
247 static ref TOKEN_TEXT: HashMap<TokenKind, String> = {
248 let mut map = HashMap::new();
249
250 map.insert(TokenKind::EOF, "EOF".to_string());
251 map.insert(TokenKind::Word, "<an identifier>".to_string());
252 map.insert(TokenKind::Number, "<a number>".to_string());
253 map.insert(TokenKind::String, "<a literal string>".to_string());
254 map.insert(TokenKind::Newline, "<a newline>".to_string());
255 map.insert(TokenKind::LeftCurly, "'{'".to_string());
256 map.insert(TokenKind::RightCurly, "'}'".to_string());
257 map.insert(TokenKind::LeftBracket, "'['".to_string());
258 map.insert(TokenKind::RightBracket, "']'".to_string());
259 map.insert(TokenKind::LeftParenthesis, "'('".to_string());
260 map.insert(TokenKind::RightParenthesis, "')'".to_string());
261 map.insert(TokenKind::LessThan, "'<'".to_string());
262 map.insert(TokenKind::GreaterThan, "'>'".to_string());
263 map.insert(TokenKind::LessThanOrEqual, "'<='".to_string());
264 map.insert(TokenKind::GreaterThanOrEqual, "'>='".to_string());
265 map.insert(TokenKind::Assign, "'='".to_string());
266 map.insert(TokenKind::Equal, "'=='".to_string());
267 map.insert(TokenKind::Unequal, "'!='".to_string());
268 map.insert(TokenKind::AltUnequal, "'<>'".to_string());
269 map.insert(TokenKind::LeftShift, "'<<'".to_string());
270 map.insert(TokenKind::RightShift, "'>>'".to_string());
271 map.insert(TokenKind::Dot, "'.'".to_string());
272 map.insert(TokenKind::Comma, "','".to_string());
273 map.insert(TokenKind::Colon, "':'".to_string());
274 map.insert(TokenKind::At, "'@'".to_string());
275 map.insert(TokenKind::Plus, "'+'".to_string());
276 map.insert(TokenKind::Minus, "'-'".to_string());
277 map.insert(TokenKind::Star, "'*'".to_string());
278 map.insert(TokenKind::Power, "'**'".to_string());
279 map.insert(TokenKind::Slash, "'/'".to_string());
280 map.insert(TokenKind::SlashSlash, "'//'".to_string());
281 map.insert(TokenKind::Modulo, "'%'".to_string());
282 map.insert(TokenKind::BackTick, "'`'".to_string());
283 map.insert(TokenKind::Dollar, "'$'".to_string());
284 map.insert(TokenKind::True, "<true>".to_string());
285 map.insert(TokenKind::False, "<false>".to_string());
286 map.insert(TokenKind::None, "<none>".to_string());
287 map.insert(TokenKind::Is, "'is'".to_string());
288 map.insert(TokenKind::In, "'in'".to_string());
289 map.insert(TokenKind::Not, "'not'".to_string());
290 map.insert(TokenKind::And, "'and'".to_string());
291 map.insert(TokenKind::Or, "'or'".to_string());
292 map.insert(TokenKind::BitwiseAnd, "'&'".to_string());
293 map.insert(TokenKind::BitwiseOr, "'|'".to_string());
294 map.insert(TokenKind::BitwiseXor, "'^'".to_string());
295 map.insert(TokenKind::BitwiseComplement, "'~'".to_string());
296 map.insert(TokenKind::Complex, "<complex>".to_string());
297 map.insert(TokenKind::IsNot, "'is not'".to_string());
298 map.insert(TokenKind::NotIn, "'not in'".to_string());
299 map
300 };
301
302 static ref IDENTIFIER_PATTERN: Regex = Regex::new(r"^[\pL_](\w*)$").expect("couldn't compile regex");
303 static ref ISO_DATETIME_PATTERN: Regex = Regex::new(r"^(\d{4})-(\d{2})-(\d{2})(([ T])(((\d{2}):(\d{2}):(\d{2}))(\.\d{1,6})?(([+-])(\d{2}):(\d{2})(:(\d{2})(\.\d{1,6})?)?)?))?$").expect("couldn't compile regex");
304 static ref ENV_VALUE_PATTERN: Regex = Regex::new(r"^\$(\w+)(\|(.*))?$").expect("couldn't compile regex");
305 static ref INTERPOLATION_PATTERN: Regex = Regex::new(r"\$\{([^}]+)\}").expect("couldn't compile regex");
306
307 static ref NOT_STRING: &'static str = "configuration value is not a string";
308 static ref NOT_INTEGER: &'static str = "configuration value is not an integer";
309 static ref NOT_FLOAT: &'static str = "configuration value is not a floating-point value";
310 static ref NOT_COMPLEX: &'static str = "configuration value is not a complex number value";
311 static ref NOT_DATE: &'static str = "configuration value is not a date value";
312 static ref NOT_DATETIME: &'static str = "configuration value is not a date/time value";
313}
314
315#[derive(Debug)]
316pub(crate) enum DecoderError {
317 InvalidBytes(Vec<u8>),
318 Io(io::Error),
319}
320
321impl fmt::Display for DecoderError {
322 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
323 match self {
324 DecoderError::InvalidBytes(b) => write!(f, "invalid bytes: {:?}", b),
325 DecoderError::Io(e) => write!(f, "I/O error: {:?}", e),
326 }
327 }
328}
329
330impl std::error::Error for DecoderError {}
332
333#[derive(Debug)]
334pub(crate) enum DecodeResult {
335 EOF,
336 Error(DecoderError),
337 Char(char, Vec<u8>),
338}
339
340pub(crate) struct Decoder<'a> {
341 reader: Box<dyn BufRead + 'a>,
342 pub(crate) bytes_read: usize,
343 log: bool,
344}
345
346impl<'a> Decoder<'a> {
347 pub(crate) fn new<R: Read + 'a>(r: R) -> Self {
348 let boxed = Box::new(r);
349 let br = BufReader::new(boxed);
350
351 Self {
352 reader: Box::new(br),
353 bytes_read: 0,
354 log: false,
355 }
356 }
357
358 pub(crate) fn decode(&mut self) -> DecodeResult {
359 let mut pos: usize;
360 let mut code_point: u32 = 0;
361 let mut state = UTF8_ACCEPT;
362 let mut the_bytes = vec![];
363
364 loop {
365 let reader = &mut self.reader;
366 {
370 let r = reader.fill_buf();
371 let length: usize;
372 let buf: &[u8];
373
374 match r {
375 Ok(buffer) => {
376 buf = buffer;
377 length = buffer.len();
378 if self.log {
379 println!("Buffer is {} long", length);
380 }
381 if length == 0 {
382 return if state == UTF8_ACCEPT {
383 DecodeResult::EOF
384 } else {
385 DecodeResult::Error(DecoderError::InvalidBytes(the_bytes))
386 };
387 }
388 pos = 0;
389 }
390 Err(e) => {
391 return DecodeResult::Error(DecoderError::Io(e));
392 }
393 }
394 while pos < length {
395 let byte = buf[pos];
396 let kind: u32 = UTF8_LOOKUP[byte as usize] as u32;
397
398 the_bytes.push(byte);
399 code_point = if state != UTF8_ACCEPT {
400 (byte & 0x3F) as u32 | (code_point << 6)
401 } else {
402 (0xFF >> kind) & (byte as u32)
403 };
404 state = UTF8_LOOKUP[(256 + state + kind) as usize] as u32;
405 if self.log {
406 println!("byte = {}, kind = {}, state = {}", byte, kind, state);
407 }
408 if state == UTF8_REJECT {
409 break;
410 } else {
411 pos += 1;
412 if state == UTF8_ACCEPT {
413 break;
414 }
415 }
416 }
417 } reader.consume(pos);
419 self.bytes_read += pos;
420
421 if state == UTF8_REJECT || state == UTF8_ACCEPT {
422 break;
423 }
424 } if self.log {
426 println!("exited loop, state = {}", state);
427 }
428 assert!(state == UTF8_REJECT || state == UTF8_ACCEPT);
429 if state == UTF8_REJECT {
430 DecodeResult::Error(DecoderError::InvalidBytes(the_bytes))
431 } else {
432 match std::char::from_u32(code_point) {
433 Some(c) => DecodeResult::Char(c, the_bytes),
434 None => DecodeResult::Error(DecoderError::InvalidBytes(the_bytes)),
435 }
436 }
437 }
438}
439
440#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq, PartialOrd)]
445pub struct Location {
446 pub line: u16,
448 pub column: u16,
450}
451
452impl Location {
453 pub(crate) fn next_line(&mut self) {
454 self.line += 1;
455 self.column = 1;
456 }
457
458 pub(crate) fn update(&mut self, other: &Self) {
459 *self = *other;
460 }
461}
462
463impl fmt::Display for Location {
464 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
465 write!(f, "({}, {})", self.line, self.column)
466 }
467}
468
469impl Ord for Location {
470 fn cmp(&self, other: &Self) -> Ordering {
471 let result = self.line.cmp(&other.column);
472
473 if result != Ordering::Equal {
474 return result;
475 }
476 self.column.cmp(&other.column)
477 }
478}
479
480#[derive(Debug, PartialEq)]
483pub enum RecognizerError {
484 Io(Location),
486 UnexpectedCharacter(char, Location),
488 InvalidCharacter(char, Location),
490 InvalidNumber(Location),
492 UnterminatedString(Location),
494 InvalidString(Location),
497 UnexpectedToken(String, String, Location),
500 ValueExpected(String, Location),
502 AtomExpected(String, Location),
504 KeyExpected(String, Location),
506 KeyValueSeparatorExpected(String, Location),
508 ContainerExpected(String, Location),
510 InvalidEscapeSequence(usize, Location),
512 UnexpectedListSize(Location),
514 TrailingText(Location),
516}
517
518#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq)]
522pub enum TokenKind {
523 EOF = 0,
525 Word,
527 Number,
529 String,
531 Newline,
533 LeftCurly,
535 RightCurly,
537 LeftBracket,
539 RightBracket,
541 LeftParenthesis,
543 RightParenthesis,
545 LessThan,
547 GreaterThan,
549 LessThanOrEqual,
551 GreaterThanOrEqual,
553 Assign,
555 Equal,
557 Unequal,
559 AltUnequal,
561 LeftShift,
563 RightShift,
565 Dot,
567 Comma,
569 Colon,
571 At,
573 Plus,
575 Minus,
577 Star,
579 Power,
581 Slash,
583 SlashSlash,
585 Modulo,
587 BackTick,
589 Dollar,
591 True,
593 False,
595 None,
597 Is,
599 In,
601 Not,
603 And,
605 Or,
607 BitwiseAnd,
609 BitwiseOr,
611 BitwiseXor,
613 BitwiseComplement,
615 Complex,
617 IsNot,
619 NotIn,
621}
622
623#[derive(Debug, Clone, PartialEq)]
625pub enum ScalarValue {
626 None,
628 Null,
633 Bool(bool),
635 Identifier(String),
637 String(String),
639 Integer(i64),
641 Float(f64),
643 Complex(Complex64),
645 Date(NaiveDate),
647 DateTime(DateTime<FixedOffset>),
649}
650
651impl fmt::Display for ScalarValue {
652 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
653 match self {
654 ScalarValue::None => write!(f, "<None>"),
655 ScalarValue::Bool(b) => write!(f, "{}", b),
656 ScalarValue::Null => write!(f, "null"),
657 ScalarValue::Integer(i) => write!(f, "{}", i),
658 ScalarValue::Identifier(s) => write!(f, "{}", s),
659 ScalarValue::String(s) => write!(f, "{}", s),
660 ScalarValue::Float(fv) => write!(f, "{}", fv),
661 ScalarValue::Complex(c) => {
662 if c.re != 0f64 && c.im != 0f64 {
663 write!(f, "{} + {}j", c.re, c.im)
664 } else if c.re == 0f64 {
665 write!(f, "{}j", c.im)
666 } else {
667 write!(f, "{}", c.re)
668 }
669 }
670 ScalarValue::Date(d) => write!(f, "Date<{}>", d),
671 ScalarValue::DateTime(dt) => write!(f, "DateTime<{}>", dt),
672 }
673 }
674}
675
676#[derive(Debug, Clone, PartialEq)]
678pub struct Token {
679 pub kind: TokenKind,
681 pub text: String,
683 pub value: ScalarValue,
685 pub start: Location,
687 pub end: Location,
689}
690
691impl fmt::Display for Token {
692 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
693 write!(
694 f,
695 "Token[{}, {}]({:?}:{}:{})",
696 self.start.line, self.start.column, self.kind, self.text, self.value
697 )
698 }
699}
700
701#[derive(Debug, Clone, PartialEq)]
703pub struct UnaryNode {
704 pub(crate) kind: TokenKind,
706 pub(crate) operand: Box<ASTValue>,
708 pub start: Location,
710}
711
712impl fmt::Display for UnaryNode {
713 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
714 write!(
715 f,
716 "UnaryNode[{}, {}]({:?}, {})",
717 self.start.line, self.start.column, self.kind, self.operand
718 )
719 }
720}
721
722#[derive(Debug, Clone, PartialEq)]
724pub struct BinaryNode {
725 pub(crate) kind: TokenKind,
727 pub(crate) left: Box<ASTValue>,
729 pub(crate) right: Box<ASTValue>,
731 pub start: Location,
733}
734
735impl fmt::Display for BinaryNode {
736 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
737 write!(
738 f,
739 "BinaryNode[{}, {}]({:?}, {}, {})",
740 self.start.line, self.start.column, self.kind, self.left, self.right
741 )
742 }
743}
744
745#[derive(Debug, Clone, PartialEq)]
747pub enum ASTValue {
748 TokenValue(Token),
750 Unary(UnaryNode),
752 Binary(BinaryNode),
754 List(Vec<ASTValue>),
756 Mapping(Vec<(Token, ASTValue)>),
758 Slice(
760 Location,
761 Box<Option<ASTValue>>,
762 Box<Option<ASTValue>>,
763 Box<Option<ASTValue>>,
764 ),
765}
766
767impl fmt::Display for ASTValue {
768 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
769 match self {
770 ASTValue::TokenValue(t) => write!(f, "{}", t),
771 ASTValue::Unary(u) => write!(f, "{}", u),
772 ASTValue::Binary(b) => write!(f, "{}", b),
773 ASTValue::List(lv) => {
774 let mut s = "[".to_string();
775 for e in lv {
776 write!(s, "{}", e).unwrap();
777 write!(s, ", ").unwrap();
778 }
779 s.pop();
781 s.pop();
782 write!(s, "]").unwrap();
783 write!(f, "{}", s)
784 }
785 ASTValue::Mapping(mv) => {
786 let mut s = "{".to_string();
787 for e in mv {
788 write!(s, "{}", e.0).unwrap();
789 write!(s, ":").unwrap();
790 write!(s, "{}", e.1).unwrap();
791 write!(s, ", ").unwrap();
792 }
793 s.pop();
795 s.pop();
796 write!(s, "}}").unwrap();
797 write!(f, "{}", s)
798 }
799 ASTValue::Slice(loc, start, stop, step) => {
800 write!(f, "Slice[{}, {}](", loc.line, loc.column).unwrap();
801 match &**start {
802 None => write!(f, "None").unwrap(),
803 Some(v) => write!(f, "{}", v).unwrap(),
804 };
805 write!(f, ", ").unwrap();
806 match &**stop {
807 None => write!(f, "None").unwrap(),
808 Some(v) => write!(f, "{}", v).unwrap(),
809 };
810 write!(f, ", ").unwrap();
811 match &**step {
812 None => write!(f, "None").unwrap(),
813 Some(v) => write!(f, "{}", v).unwrap(),
814 };
815 write!(f, ")")
816 }
818 }
819 }
820}
821
822struct PushBackInfo {
823 pub(crate) c: char,
824 pub(crate) location: Location,
825}
826
827pub(crate) struct Tokenizer<'a> {
828 reader: Decoder<'a>,
829 char_location: Location,
830 location: Location,
831 pushed_back: Vec<PushBackInfo>,
832 log: bool,
833}
834
835macro_rules! get_char {
836 ($self: expr) => {{
837 let r = $self.get_char();
838
839 match r {
840 Err(_) => {
841 return Err(RecognizerError::Io($self.char_location.clone()));
842 }
843 Ok(c) => c,
844 }
845 }};
846}
847
848macro_rules! append_char {
849 ($self: expr, $text: expr, $c: expr, $endloc: expr) => {{
850 $text.push($c);
851 $endloc.update(&$self.char_location);
852 }};
853}
854
855pub(crate) fn is_identifier(s: &str) -> bool {
856 IDENTIFIER_PATTERN.is_match(s)
857}
858
859fn find_in_slice(text: &[char], c: char) -> isize {
860 let mut result = -1;
861
862 for (i, ch) in text.iter().enumerate() {
863 if *ch == c {
864 result = i as isize;
865 break;
866 }
867 }
868 result
869}
870
871macro_rules! loc {
872 ($line:expr, $column:expr) => {{
873 Location {
874 line: $line,
875 column: $column,
876 }
877 }};
878}
879
880impl<'a> Tokenizer<'a> {
881 pub(crate) fn new(r: Box<dyn Read + 'a>) -> Self {
882 let br = BufReader::new(r);
883 let b = Box::new(br);
884 Self {
885 reader: Decoder::new(b),
886 char_location: loc!(1, 1),
887 location: loc!(1, 1),
888 pushed_back: vec![],
889 log: false,
890 }
891 }
892
893 pub(crate) fn push_back(&mut self, c: char) {
894 let push_back_info = PushBackInfo {
895 c,
896 location: self.char_location,
897 };
898 self.pushed_back.push(push_back_info);
899 }
900
901 pub(crate) fn get_char(&mut self) -> Result<Option<char>> {
902 let result;
903
904 if let Some(push_back_info) = self.pushed_back.pop() {
905 result = Ok(Some(push_back_info.c));
906 self.char_location.update(&push_back_info.location);
907 self.location.update(&push_back_info.location); } else {
909 self.char_location.update(&self.location);
910 match self.reader.decode() {
911 DecodeResult::Char(c, _) => {
912 result = Ok(Some(c));
913 }
914 DecodeResult::EOF => {
915 result = Ok(Option::None);
916 }
917 DecodeResult::Error(e) => match e {
918 DecoderError::Io(e) => result = Err(e),
919 e => {
920 result = Err(Error::new(ErrorKind::InvalidData, e));
921 }
922 },
923 }
924 }
925 if let Ok(v) = &result {
926 if let Some(c) = v {
927 self.location.column += 1;
928 if *c == '\n' {
929 self.location.next_line();
930 }
931 }
932 }
933 result
934 }
935
936 fn get_number(
937 &mut self,
938 text: &mut Vec<char>,
939 start_location: Location,
940 end_location: &mut Location,
941 ) -> StdResult<(TokenKind, ScalarValue), RecognizerError> {
942 let mut kind = TokenKind::Number;
943 let mut value = ScalarValue::None;
944 let mut in_exponent = false;
945 let mut radix = 0;
946 let mut dot_seen = text.contains(&'.');
947 let mut last_was_digit = match text.last() {
948 None => false,
949 Some(c) => c.is_ascii_hexdigit(),
950 };
951 let mut fail_location: Option<Location> = Option::None;
952 let mut lastc;
953
954 fn ends_with(text: &[char], c: char) -> bool {
955 match text.last() {
956 None => false,
957 Some(ch) => *ch == c,
958 }
959 }
960
961 loop {
962 let c = get_char!(self);
963
964 lastc = c;
965 match c {
966 None => break,
967 Some(ch) => {
968 if ch == '.' {
969 dot_seen = true;
970 }
971 if ch == '_' {
972 if last_was_digit {
973 append_char!(self, text, ch, end_location);
974 last_was_digit = false;
975 continue;
976 }
977 fail_location = Some(self.char_location);
978 }
979 last_was_digit = false; if ((radix == 0) && (ch >= '0') && (ch <= '9'))
981 || ((radix == 2) && (ch >= '0') && (ch <= '1'))
982 || ((radix == 8) && (ch >= '0') && (ch <= '7'))
983 || ((radix == 16) && ch.is_ascii_hexdigit())
984 {
985 append_char!(self, text, ch, end_location);
986 last_was_digit = true;
987 } else if ((ch == 'o')
988 || (ch == 'O')
989 || (ch == 'x')
990 || (ch == 'X')
991 || (ch == 'b')
992 || (ch == 'B'))
993 && (text.len() == 1)
994 && (text[0] == '0')
995 {
996 if (ch == 'o') || (ch == 'O') {
997 radix = 8;
998 } else if (ch == 'x') || (ch == 'X') {
999 radix = 16;
1000 } else {
1001 radix = 2;
1002 }
1003 append_char!(self, text, ch, end_location);
1004 } else if (radix == 0) && (ch == '.') && !in_exponent && !text.contains(&ch) {
1005 append_char!(self, text, ch, end_location);
1006 } else if (radix == 0)
1007 && (ch == '-')
1008 && !text[1..].contains(&'-')
1009 && in_exponent
1010 {
1011 append_char!(self, text, ch, end_location);
1012 } else if (radix == 0)
1013 && ((ch == 'e') || (ch == 'E'))
1014 && !text.contains(&'e')
1015 && !text.contains(&'E')
1016 {
1017 if ends_with(text, '_') {
1018 fail_location = Some(self.char_location);
1019 break;
1020 } else {
1021 append_char!(self, text, ch, end_location);
1022 in_exponent = true;
1023 }
1024 } else {
1025 break;
1026 }
1027 }
1028 }
1029 }
1030 if ends_with(text, '_') {
1031 if fail_location.is_none() {
1032 let mut loc = self.char_location;
1033
1034 loc.column -= 1;
1035 fail_location = Some(loc);
1036 }
1037 } else {
1038 match lastc {
1039 None => {}
1040 Some(ch) => {
1041 if (radix == 0) && ((ch == 'j') || (ch == 'J')) {
1042 append_char!(self, text, ch, end_location);
1043 kind = TokenKind::Complex;
1044 } else {
1045 if (ch != '.') && !ch.is_alphanumeric() {
1047 self.push_back(ch);
1048 } else {
1049 fail_location = Some(self.char_location);
1050 }
1051 }
1052 }
1053 }
1054 }
1055 if fail_location.is_none() {
1056 let s = text.iter().cloned().collect::<String>().replace("_", "");
1057 if radix != 0 {
1058 match i64::from_str_radix(&s[2..], radix) {
1059 Ok(v) => value = ScalarValue::Integer(v),
1060 Err(_) => fail_location = Some(start_location),
1061 }
1062 } else if kind == TokenKind::Complex {
1063 match s[..s.len() - 1].parse::<f64>() {
1064 Ok(v) => value = ScalarValue::Complex(Complex64::new(0.0, v)),
1065 Err(_) => fail_location = Some(start_location),
1066 }
1067 } else if in_exponent || dot_seen {
1068 match s.parse::<f64>() {
1069 Ok(v) => value = ScalarValue::Float(v),
1070 Err(_) => fail_location = Some(start_location),
1071 }
1072 } else {
1073 radix = if text[0] == '0' { 8 } else { 10 };
1074 match i64::from_str_radix(&s, radix) {
1075 Ok(v) => value = ScalarValue::Integer(v),
1076 Err(_) => fail_location = Some(start_location),
1077 }
1078 }
1079 }
1080 match fail_location {
1081 Some(loc) => Err(RecognizerError::InvalidNumber(loc)),
1082 None => Ok((kind, value)),
1083 }
1084 }
1085
1086 fn parse_escapes(
1087 &self,
1088 mut text: &[char],
1089 loc: Location,
1090 ) -> StdResult<String, RecognizerError> {
1091 let result;
1092 let mut i = find_in_slice(text, '\\');
1093
1094 if i < 0 {
1095 result = text.iter().cloned().collect::<String>();
1096 } else {
1097 let mut out: Vec<char> = vec![];
1098 let mut failed = false;
1099
1100 while i >= 0 {
1101 let n = text.len();
1102 let mut u = i as usize;
1103
1104 if i > 0 {
1105 out.extend_from_slice(&text[..u]);
1106 }
1107 let c = text[i as usize + 1];
1108 if ESCAPES.contains_key(&c) {
1109 out.push(ESCAPES[&c]);
1110 u += 2;
1111 } else if c == 'x' || c == 'X' || c == 'u' || c == 'U' {
1112 let slen = if c == 'x' || c == 'X' {
1113 4
1114 } else if c == 'u' {
1115 6
1116 } else {
1117 10
1118 };
1119
1120 if u + slen > n {
1121 failed = true;
1122 break;
1123 }
1124 let p = text[u + 2..u + slen].iter().cloned().collect::<String>();
1125 match u32::from_str_radix(&p, 16) {
1126 Ok(v) => match std::char::from_u32(v) {
1127 Some(c) => {
1128 out.push(c);
1129 u += slen;
1130 }
1131 None => {
1132 failed = true;
1133 break;
1134 }
1135 },
1136 Err(_) => {
1137 failed = true;
1138 break;
1139 }
1140 }
1141 } else {
1142 failed = true;
1143 break;
1144 }
1145 text = &text[u..];
1146 i = find_in_slice(text, '\\');
1147 }
1148 if failed {
1149 return Err(RecognizerError::InvalidEscapeSequence(i as usize, loc));
1150 }
1151 out.extend(text);
1152 result = out.iter().cloned().collect::<String>();
1153 }
1154 Ok(result)
1155 }
1156
1157 pub(crate) fn get_token(&mut self) -> StdResult<Token, RecognizerError> {
1158 let mut kind;
1159 let mut value = ScalarValue::None;
1160 let mut text: Vec<char> = vec![];
1161 let mut start_location = loc!(1, 1);
1162 let mut end_location = loc!(1, 1);
1163 let mut s = String::new();
1164
1165 loop {
1166 let mut c = get_char!(self);
1167
1168 start_location.update(&self.char_location);
1169 end_location.update(&self.char_location);
1172
1173 match c {
1174 None => {
1175 kind = TokenKind::EOF;
1176 break;
1177 }
1178 Some('#') => {
1179 text.push('#');
1180 kind = TokenKind::Newline;
1181 loop {
1182 let ch = get_char!(self);
1183 match ch {
1184 None => break,
1185 Some(c) => {
1186 text.push(c);
1187 if c == '\n' {
1188 break;
1189 }
1190 }
1191 }
1192 }
1193 end_location.update(&self.location);
1195 break;
1196 }
1197 Some('\n') => {
1198 append_char!(self, text, '\n', end_location);
1199 kind = TokenKind::Newline;
1200 end_location.update(&self.location);
1201 end_location.column -= 1;
1202 break;
1203 }
1204 Some('\r') => {
1205 let nc = get_char!(self);
1206
1207 match nc {
1208 None => {}
1209 Some('\n') => {}
1210 Some(c) => self.push_back(c),
1211 }
1212 kind = TokenKind::Newline;
1213 end_location.update(&self.location);
1214 end_location.column -= 1;
1215 break;
1216 }
1217 Some('\\') => {
1218 let nc = get_char!(self);
1219
1220 match nc {
1221 None => {}
1222 Some('\n') => {
1223 end_location.update(&self.location);
1224 continue;
1225 }
1226 Some('\r') => {
1227 let nnc = get_char!(self);
1228
1229 match nnc {
1230 None => {}
1231 Some('\n') => {
1232 end_location.update(&self.location);
1233 continue;
1234 }
1235 Some(c) => {
1236 return Err(RecognizerError::UnexpectedCharacter(
1237 c,
1238 self.char_location,
1239 ));
1240 }
1241 }
1242 }
1243 Some(c) => {
1244 return Err(RecognizerError::UnexpectedCharacter(
1245 c,
1246 self.char_location,
1247 ));
1248 }
1249 }
1250 }
1251 Some(ch) if ch.is_whitespace() => continue,
1252 Some(ch) if ch.is_alphabetic() || ch == '_' => {
1253 kind = TokenKind::Word;
1254
1255 append_char!(self, text, ch, end_location);
1256 loop {
1257 c = get_char!(self);
1258 match c {
1259 None => break,
1260 Some(c) if c.is_alphanumeric() || c == '_' => {
1261 append_char!(self, text, c, end_location)
1262 }
1263 Some(c) => {
1264 self.push_back(c);
1265 break;
1266 }
1267 }
1268 }
1269 s = text.iter().cloned().collect::<String>();
1270 if self.log {
1271 println!("word: {}", s);
1272 }
1273 if !KEYWORDS.contains_key(&s) {
1274 value = ScalarValue::Identifier(s.clone());
1275 } else {
1276 kind = KEYWORDS[&s];
1277 if KEYWORD_VALUES.contains_key(&s) {
1278 value = KEYWORD_VALUES[&s].clone();
1279 }
1280 }
1281 break;
1282 }
1283 Some('`') => {
1284 let mut unterminated = false;
1285
1286 kind = TokenKind::BackTick;
1287 append_char!(self, text, '`', end_location);
1288 loop {
1289 let c = get_char!(self);
1290
1291 match c {
1292 None => {
1293 unterminated = true;
1294 break;
1295 }
1296 Some(ch) if !ch.is_control() => {
1297 append_char!(self, text, ch, end_location);
1298 if ch == '`' {
1299 break;
1300 }
1301 }
1302 Some(_ch) => {
1303 return Err(RecognizerError::InvalidString(self.char_location));
1304 }
1305 }
1306 }
1307 if self.char_location.column > 1 {
1308 self.char_location.column -= 1;
1309 }
1310 if unterminated {
1311 return Err(RecognizerError::UnterminatedString(self.char_location));
1312 }
1313 value = ScalarValue::String(
1314 self.parse_escapes(&text[1..text.len() - 1], start_location)?,
1315 );
1316 break;
1317 }
1318 Some(ch) if ch == '\'' || ch == '"' => {
1319 kind = TokenKind::String;
1320
1321 let quote = ch;
1322 let mut multi_line = false;
1323 let mut escaped = false;
1324 let mut unterminated = false;
1325
1326 append_char!(self, text, ch, end_location);
1327 let c1 = get_char!(self);
1328 let c1_loc = self.char_location;
1329
1330 match c1 {
1331 None => unterminated = true,
1332 Some(ch1) => {
1333 if ch1 != quote {
1334 self.push_back(ch1);
1335 } else {
1336 let c2 = get_char!(self);
1337
1338 match c2 {
1339 Some(ch2) => {
1340 if ch2 != quote {
1341 self.push_back(ch2);
1342 self.push_back(ch1);
1343 } else {
1344 multi_line = true;
1345 text.push(quote);
1346 append_char!(self, text, quote, end_location);
1347 }
1348 }
1349 None => {
1350 self.char_location.update(&c1_loc);
1351 self.push_back(ch1);
1352 }
1353 }
1354 }
1355 }
1356 }
1357 if self.char_location.column > 1 {
1358 self.char_location.column -= 1;
1359 }
1360 if unterminated {
1361 return Err(RecognizerError::UnterminatedString(self.char_location));
1362 }
1363 let quoter_len = text.len();
1364 loop {
1365 let c = get_char!(self);
1366
1367 match c {
1368 None => {
1369 unterminated = true;
1370 break;
1371 }
1372 Some(ch) => {
1373 append_char!(self, text, ch, end_location);
1374 if ch == quote && !escaped {
1375 let n = text.len();
1376 if !multi_line
1377 || (n >= 6)
1378 && (text[n - 3..n] == text[..3])
1379 && text[n - 4] != '\\'
1380 {
1381 break;
1382 }
1383 }
1384 escaped = if ch == '\\' { !escaped } else { false };
1385 }
1386 }
1387 }
1388 if self.char_location.column > 1 {
1389 self.char_location.column -= 1;
1390 }
1391 if unterminated {
1392 return Err(RecognizerError::UnterminatedString(self.char_location));
1393 }
1394 value = ScalarValue::String(self.parse_escapes(
1395 &text[quoter_len..text.len() - quoter_len],
1396 start_location,
1397 )?);
1398 break;
1399 }
1400 Some(ch) if ch.is_numeric() => {
1401 append_char!(self, text, ch, end_location);
1402 let (k, v) = self.get_number(&mut text, start_location, &mut end_location)?;
1404 kind = k;
1405 value = v;
1406 break;
1407 }
1408 Some('=') => {
1409 let nc = get_char!(self);
1410
1411 match nc {
1412 Some('=') => {
1413 kind = TokenKind::Equal;
1414 text.push('=');
1415 append_char!(self, text, '=', end_location);
1416 break;
1417 }
1418 Some(nch) => {
1419 kind = TokenKind::Assign;
1420 append_char!(self, text, '=', end_location);
1421 self.push_back(nch);
1422 break;
1423 }
1424 None => {
1425 kind = TokenKind::Assign;
1426 append_char!(self, text, '=', end_location);
1427 break;
1428 }
1429 }
1430 }
1431 Some(ch) if PUNCTUATION.contains_key(&ch) => {
1432 kind = PUNCTUATION[&ch];
1433 append_char!(self, text, ch, end_location);
1434 match ch {
1435 '-' => {
1436 let nc = get_char!(self);
1437 match nc {
1438 None => break,
1439 Some(nch) if nch.is_numeric() || (nch == '.') => {
1440 append_char!(self, text, nch, end_location);
1441 let (k, v) = self.get_number(
1443 &mut text,
1444 start_location,
1445 &mut end_location,
1446 )?;
1447 kind = k;
1448 value = v;
1449 }
1450 Some(nch) => self.push_back(nch),
1451 }
1452 }
1453 '.' => {
1454 let nc = get_char!(self);
1455
1456 match nc {
1457 None => break,
1458 Some(nch) if nch.is_numeric() => {
1459 append_char!(self, text, nch, end_location);
1460 let (k, v) = self.get_number(
1462 &mut text,
1463 start_location,
1464 &mut end_location,
1465 )?;
1466 kind = k;
1467 value = v;
1468 }
1469 Some(nch) => self.push_back(nch),
1470 }
1471 }
1472 '<' => {
1473 let nc = get_char!(self);
1474
1475 match nc {
1476 None => {}
1477 Some(nch) => {
1478 if "=<>".contains(nch) {
1479 append_char!(self, text, nch, end_location);
1480 }
1481 match nch {
1482 '=' => kind = TokenKind::LessThanOrEqual,
1483 '<' => kind = TokenKind::LeftShift,
1484 '>' => kind = TokenKind::AltUnequal,
1485 _ => self.push_back(nch),
1486 }
1487 }
1488 }
1489 break;
1490 }
1491 '>' => {
1492 let nc = get_char!(self);
1493
1494 match nc {
1495 None => {}
1496 Some(nch) => {
1497 if "=>".contains(nch) {
1498 append_char!(self, text, nch, end_location);
1499 }
1500 match nch {
1501 '=' => kind = TokenKind::GreaterThanOrEqual,
1502 '>' => kind = TokenKind::RightShift,
1503 _ => self.push_back(nch),
1504 }
1505 }
1506 }
1507 break;
1508 }
1509 '!' => {
1510 let nc = get_char!(self);
1511
1512 match nc {
1513 None => {}
1514 Some(nch) => match nch {
1515 '=' => {
1516 append_char!(self, text, nch, end_location);
1517 kind = TokenKind::Unequal;
1518 }
1519 _ => self.push_back(nch),
1520 },
1521 }
1522 break;
1523 }
1524 '*' => {
1525 let nc = get_char!(self);
1526
1527 match nc {
1528 None => {}
1529 Some(nch) => match nch {
1530 '*' => {
1531 append_char!(self, text, nch, end_location);
1532 kind = TokenKind::Power;
1533 }
1534 _ => self.push_back(nch),
1535 },
1536 }
1537 break;
1538 }
1539 '/' => {
1540 let nc = get_char!(self);
1541
1542 match nc {
1543 None => {}
1544 Some(nch) => match nch {
1545 '/' => {
1546 append_char!(self, text, nch, end_location);
1547 kind = TokenKind::SlashSlash;
1548 }
1549 _ => self.push_back(nch),
1550 },
1551 }
1552 break;
1553 }
1554 '&' | '|' => {
1555 let nc = get_char!(self);
1556
1557 match nc {
1558 None => {}
1559 Some(nch) => {
1560 if nch == ch {
1561 append_char!(self, text, nch, end_location);
1562 kind = if ch == '&' {
1563 TokenKind::And
1564 } else {
1565 TokenKind::Or
1566 }
1567 }
1568 }
1569 }
1570 break;
1571 }
1572 _ => {}
1573 }
1574 break;
1575 }
1576 Some(ch) => {
1577 return Err(RecognizerError::UnexpectedCharacter(ch, self.char_location));
1578 }
1579 }
1580 }
1581 if self.log {
1582 println!("{}, {}, {:?}", kind as i32, s, value);
1583 }
1584 if s.is_empty() {
1585 s = text.iter().cloned().collect::<String>();
1586 }
1587 Ok(Token {
1588 kind,
1589 text: s,
1590 value,
1591 start: start_location,
1592 end: end_location,
1593 })
1594 }
1595}
1596
1597pub struct Parser<'a> {
1599 tokenizer: Tokenizer<'a>,
1600 next_token: Token,
1601}
1602
1603pub(crate) fn token_text(k: TokenKind) -> String {
1604 TOKEN_TEXT[&k].clone()
1605}
1606
1607impl<'a> Parser<'a> {
1608 pub fn new(r: Box<dyn Read + 'a>) -> StdResult<Self, RecognizerError> {
1611 let mut tokenizer = Tokenizer::new(r);
1612 let t = tokenizer.get_token();
1613 match t {
1614 Err(e) => Err(e),
1615 Ok(token) => Ok(Self {
1616 tokenizer,
1617 next_token: token,
1618 }),
1619 }
1620 }
1621
1622 pub fn at_end(&self) -> bool {
1624 self.next_token.kind == TokenKind::EOF
1625 }
1626
1627 pub fn location(&self) -> Location {
1629 self.next_token.start
1630 }
1631
1632 fn advance(&mut self) -> StdResult<TokenKind, RecognizerError> {
1633 let r = self.tokenizer.get_token();
1634
1635 match r {
1636 Err(e) => Err(e),
1637 Ok(token) => {
1638 let k = token.kind;
1639
1640 self.next_token = token;
1641 Ok(k)
1642 }
1643 }
1644 }
1645
1646 fn expect(&mut self, kind: TokenKind) -> StdResult<Token, RecognizerError> {
1647 if self.next_token.kind != kind {
1648 Err(RecognizerError::UnexpectedToken(
1649 token_text(kind),
1650 token_text(self.next_token.kind),
1651 self.next_token.start,
1652 ))
1653 } else {
1654 let curr = self.next_token.clone();
1655 let r = self.advance();
1656
1657 match r {
1658 Err(e) => Err(e),
1659 Ok(_) => Ok(curr),
1660 }
1661 }
1662 }
1663
1664 pub(crate) fn consume_new_lines(&mut self) -> StdResult<TokenKind, RecognizerError> {
1665 let mut result = self.next_token.kind;
1666
1667 while result == TokenKind::Newline {
1668 result = self.advance()?;
1669 }
1670 Ok(result)
1671 }
1672
1673 pub(crate) fn strings(&mut self) -> StdResult<Token, RecognizerError> {
1674 let mut result = self.next_token.clone();
1675 let k = self.advance()?;
1676
1677 if k == TokenKind::String {
1678 let mut all_text: Vec<char> = vec![];
1679 let start = result.start;
1680 let mut end = self.next_token.end;
1681
1682 match &result.value {
1683 ScalarValue::String(s) => all_text.extend(s.chars()),
1684 e => panic!("string value expected, but found {:?}", e),
1685 }
1686 loop {
1687 match &self.next_token.value {
1688 ScalarValue::String(s) => all_text.extend(s.chars()),
1689 e => panic!("string value expected, but found {:?}", e),
1690 }
1691 let k = self.advance()?;
1692 if k == TokenKind::String {
1693 end = self.next_token.end;
1694 } else {
1695 break;
1696 }
1697 }
1698 let s = all_text.iter().collect::<String>();
1700 result = Token {
1701 kind: result.kind,
1702 text: s.clone(),
1703 value: ScalarValue::String(s),
1704 start,
1705 end,
1706 }
1707 }
1708 Ok(result)
1709 }
1710
1711 pub(crate) fn value(&mut self) -> StdResult<Token, RecognizerError> {
1712 let kind = self.next_token.kind;
1713
1714 if !VALUE_STARTERS.contains(&kind) {
1715 Err(RecognizerError::ValueExpected(
1716 token_text(kind),
1717 self.next_token.start,
1718 ))
1719 } else {
1720 let t;
1721
1722 if kind == TokenKind::String {
1723 t = self.strings();
1724 } else {
1725 t = Ok(self.next_token.clone());
1726 self.advance()?;
1727 }
1728 t
1729 }
1730 }
1731
1732 pub(crate) fn atom(&mut self) -> StdResult<ASTValue, RecognizerError> {
1733 let kind = self.next_token.kind;
1734
1735 match kind {
1736 TokenKind::LeftCurly => self.mapping(),
1737 TokenKind::LeftBracket => self.list(),
1738 TokenKind::LeftParenthesis => match self.expect(TokenKind::LeftParenthesis) {
1739 Err(e) => Err(e),
1740 Ok(_) => {
1741 let result = self.expr();
1742
1743 match self.expect(TokenKind::RightParenthesis) {
1744 Err(e) => Err(e),
1745 _ => result,
1746 }
1747 }
1748 },
1749 TokenKind::Dollar => {
1750 let spos = self.next_token.start;
1751 match self.advance() {
1752 Err(e) => Err(e),
1753 Ok(_) => match self.expect(TokenKind::LeftCurly) {
1754 Err(e) => Err(e),
1755 Ok(_) => match self.primary() {
1756 Err(e) => Err(e),
1757 Ok(v) => match self.expect(TokenKind::RightCurly) {
1758 Err(e) => Err(e),
1759 _ => Ok(ASTValue::Unary(UnaryNode {
1760 kind,
1761 operand: Box::new(v),
1762 start: spos,
1763 })),
1764 },
1765 },
1766 },
1767 }
1768 }
1769 v => {
1770 if VALUE_STARTERS.contains(&v) {
1771 match self.value() {
1772 Err(e) => Err(e),
1773 Ok(v) => Ok(ASTValue::TokenValue(v)),
1774 }
1775 } else {
1776 Err(RecognizerError::AtomExpected(
1777 token_text(v),
1778 self.next_token.start,
1779 ))
1780 }
1781 }
1782 }
1783 }
1784
1785 fn list_element(&mut self) -> StdResult<ASTValue, RecognizerError> {
1786 let loc = self.next_token.start;
1787 let result;
1788 let v = self.list_body()?;
1789
1790 match v {
1791 ASTValue::List(lv) => {
1792 let n = lv.len();
1793
1794 if n != 1 {
1795 return Err(RecognizerError::UnexpectedListSize(loc));
1796 }
1797 result = lv[0].clone();
1798 }
1799 _ => {
1800 panic!("unexpected when parsing list: {:?}", v);
1801 }
1802 }
1803 Ok(result)
1804 }
1805
1806 pub(crate) fn trailer(&mut self) -> StdResult<(TokenKind, ASTValue), RecognizerError> {
1807 let mut kind = self.next_token.kind;
1808 let result;
1809
1810 if kind != TokenKind::LeftBracket {
1811 self.expect(TokenKind::Dot)?;
1812 result = ASTValue::TokenValue(self.expect(TokenKind::Word)?);
1813 } else {
1814 kind = self.advance()?;
1815
1816 let spos = self.next_token.start;
1817 let is_slice;
1818 let mut start: Option<ASTValue> = None;
1819
1820 if kind == TokenKind::Colon {
1821 is_slice = true;
1823 } else {
1824 start = Some(self.list_element()?);
1825 is_slice = self.next_token.kind == TokenKind::Colon;
1826 }
1827 if !is_slice {
1828 kind = TokenKind::LeftBracket;
1829 result = start.unwrap();
1830 } else {
1831 let mut stop: Option<ASTValue> = None;
1832 let mut step: Option<ASTValue> = None;
1833 let mut tk = self.advance()?;
1834
1835 if tk == TokenKind::Colon {
1836 tk = self.advance()?;
1838 if tk != TokenKind::RightBracket {
1839 step = Some(self.list_element()?);
1840 }
1841 } else if tk != TokenKind::RightBracket {
1842 stop = Some(self.list_element()?);
1843 if self.next_token.kind == TokenKind::Colon {
1844 let tk = self.advance()?;
1845
1846 if tk != TokenKind::RightBracket {
1847 step = Some(self.list_element()?);
1848 }
1849 }
1850 }
1851 kind = TokenKind::Colon;
1852 result = ASTValue::Slice(spos, Box::new(start), Box::new(stop), Box::new(step));
1853 }
1854 self.expect(TokenKind::RightBracket)?;
1855 }
1856 Ok((kind, result))
1857 }
1858
1859 pub(crate) fn primary(&mut self) -> StdResult<ASTValue, RecognizerError> {
1860 let mut result = self.atom();
1861
1862 if result.is_err() {
1863 return result;
1864 }
1865 let mut kind = self.next_token.kind;
1866
1867 while kind == TokenKind::Dot || kind == TokenKind::LeftBracket {
1868 let rhs;
1869 let spos = self.next_token.start;
1870 let (k, r) = self.trailer()?;
1871
1872 kind = k;
1873 rhs = r;
1874 result = Ok(ASTValue::Binary(BinaryNode {
1875 kind,
1876 left: Box::new(result.expect("a valid LHS was expected")),
1877 right: Box::new(rhs),
1878 start: spos,
1879 }));
1880 kind = self.next_token.kind;
1881 }
1882 result
1883 }
1884
1885 pub(crate) fn list_body(&mut self) -> StdResult<ASTValue, RecognizerError> {
1886 match self.consume_new_lines() {
1887 Err(e) => Err(e),
1888 Ok(mut k) => {
1889 let mut result = vec![];
1890
1891 while EXPRESSION_STARTERS.contains(&k) {
1892 result.push(self.expr()?);
1893 k = self.next_token.kind;
1894 if k != TokenKind::Newline && k != TokenKind::Comma {
1895 break;
1896 }
1897 self.advance()?;
1898 k = self.consume_new_lines()?;
1899 }
1900 Ok(ASTValue::List(result))
1901 }
1902 }
1903 }
1904
1905 pub(crate) fn list(&mut self) -> StdResult<ASTValue, RecognizerError> {
1906 match self.expect(TokenKind::LeftBracket) {
1907 Err(e) => Err(e),
1908 Ok(_) => match self.list_body() {
1909 Err(e) => Err(e),
1910 Ok(lb) => match self.expect(TokenKind::RightBracket) {
1911 Err(e) => Err(e),
1912 Ok(_) => Ok(lb),
1913 },
1914 },
1915 }
1916 }
1917
1918 pub(crate) fn object_key(&mut self) -> StdResult<Token, RecognizerError> {
1919 let result;
1920
1921 if self.next_token.kind == TokenKind::String {
1922 self.strings()
1923 } else {
1924 result = Ok(self.next_token.clone());
1925 match self.advance() {
1926 Err(e) => Err(e),
1927 Ok(_) => result,
1928 }
1929 }
1930 }
1931
1932 pub(crate) fn mapping_body(&mut self) -> StdResult<ASTValue, RecognizerError> {
1933 match self.consume_new_lines() {
1934 Err(e) => Err(e),
1935 Ok(mut k) => {
1936 if k == TokenKind::RightCurly || k == TokenKind::EOF {
1937 Ok(ASTValue::Mapping(vec![]))
1939 } else if k != TokenKind::Word && k != TokenKind::String {
1940 Err(RecognizerError::KeyExpected(
1941 token_text(k),
1942 self.next_token.start,
1943 ))
1944 } else {
1945 let mut result = vec![];
1946
1947 while k == TokenKind::Word || k == TokenKind::String {
1948 let key = self.object_key()?;
1949
1950 k = self.next_token.kind;
1951 if k != TokenKind::Colon && k != TokenKind::Assign {
1952 return Err(RecognizerError::KeyValueSeparatorExpected(
1953 token_text(k),
1954 self.next_token.start,
1955 ));
1956 } else {
1957 self.advance()?;
1958 self.consume_new_lines()?;
1959 }
1960 result.push((key, self.expr()?));
1961 k = self.next_token.kind;
1962 if k == TokenKind::Newline || k == TokenKind::Comma {
1963 self.advance()?;
1964 k = self.consume_new_lines()?;
1965 } else if k != TokenKind::RightCurly && k != TokenKind::EOF {
1966 let s = format!(
1967 "{} or {}",
1968 token_text(TokenKind::RightCurly),
1969 token_text(TokenKind::EOF)
1970 );
1971 return Err(RecognizerError::UnexpectedToken(
1972 s,
1973 token_text(self.next_token.kind),
1974 self.next_token.start,
1975 ));
1976 }
1977 }
1978 Ok(ASTValue::Mapping(result))
1979 }
1980 }
1981 }
1982 }
1983
1984 pub(crate) fn mapping(&mut self) -> StdResult<ASTValue, RecognizerError> {
1985 match self.expect(TokenKind::LeftCurly) {
1986 Err(e) => Err(e),
1987 Ok(_) => match self.mapping_body() {
1988 Err(e) => Err(e),
1989 Ok(mb) => match self.expect(TokenKind::RightCurly) {
1990 Err(e) => Err(e),
1991 Ok(_) => Ok(mb),
1992 },
1993 },
1994 }
1995 }
1996
1997 pub fn container(&mut self) -> StdResult<ASTValue, RecognizerError> {
2000 match self.consume_new_lines() {
2001 Err(e) => Err(e),
2002 Ok(k) => {
2003 if k == TokenKind::LeftCurly {
2004 match self.mapping() {
2005 Err(e) => Err(e),
2006 Ok(mv) => match self.consume_new_lines() {
2007 Err(e) => Err(e),
2008 Ok(_) => Ok(mv),
2009 },
2010 }
2011 } else if k == TokenKind::LeftBracket {
2012 match self.list() {
2013 Err(e) => Err(e),
2014 Ok(lv) => match self.consume_new_lines() {
2015 Err(e) => Err(e),
2016 Ok(_) => Ok(lv),
2017 },
2018 }
2019 } else if k == TokenKind::Word || k == TokenKind::String {
2020 match self.mapping_body() {
2021 Err(e) => Err(e),
2022 Ok(lv) => match self.consume_new_lines() {
2023 Err(e) => Err(e),
2024 Ok(_) => Ok(lv),
2025 },
2026 }
2027 } else {
2028 Err(RecognizerError::ContainerExpected(
2029 token_text(k),
2030 self.next_token.start,
2031 ))
2032 }
2033 }
2034 }
2035 }
2036
2037 pub(crate) fn power(&mut self) -> StdResult<ASTValue, RecognizerError> {
2038 match self.primary() {
2039 Err(e) => Err(e),
2040 Ok(mut lhs) => {
2041 while self.next_token.kind == TokenKind::Power {
2042 let spos = self.next_token.start;
2043
2044 self.advance()?;
2045
2046 let ue = self.unary_expr()?;
2047
2048 lhs = ASTValue::Binary(BinaryNode {
2049 kind: TokenKind::Power,
2050 left: Box::new(lhs),
2051 right: Box::new(ue),
2052 start: spos,
2053 })
2054 }
2055 Ok(lhs)
2056 }
2057 }
2058 }
2059
2060 pub(crate) fn unary_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2061 let kind = self.next_token.kind;
2062 let spos = self.next_token.start;
2063
2064 if kind != TokenKind::Plus
2065 && kind != TokenKind::Minus
2066 && kind != TokenKind::BitwiseComplement
2067 && kind != TokenKind::At
2068 {
2069 self.power()
2070 } else {
2071 match self.advance() {
2072 Err(e) => Err(e),
2073 Ok(_) => match self.not_expr() {
2074 Err(e) => Err(e),
2075 Ok(v) => Ok(ASTValue::Unary(UnaryNode {
2076 kind,
2077 operand: Box::new(v),
2078 start: spos,
2079 })),
2080 },
2081 }
2082 }
2083 }
2084
2085 pub(crate) fn mul_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2086 match self.unary_expr() {
2087 Err(e) => Err(e),
2088 Ok(mut lhs) => {
2089 let mut kind = self.next_token.kind;
2090
2091 while kind == TokenKind::Star
2092 || kind == TokenKind::Slash
2093 || kind == TokenKind::SlashSlash
2094 || kind == TokenKind::Modulo
2095 {
2096 let spos = self.next_token.start;
2097
2098 self.advance()?;
2099
2100 let ue = self.unary_expr()?;
2101
2102 lhs = ASTValue::Binary(BinaryNode {
2103 kind,
2104 left: Box::new(lhs),
2105 right: Box::new(ue),
2106 start: spos,
2107 });
2108 kind = self.next_token.kind;
2109 }
2110 Ok(lhs)
2111 }
2112 }
2113 }
2114
2115 pub(crate) fn add_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2116 match self.mul_expr() {
2117 Err(e) => Err(e),
2118 Ok(mut lhs) => {
2119 let mut kind = self.next_token.kind;
2120
2121 while kind == TokenKind::Plus || kind == TokenKind::Minus {
2122 let spos = self.next_token.start;
2123
2124 self.advance()?;
2125
2126 let me = self.mul_expr()?;
2127
2128 lhs = ASTValue::Binary(BinaryNode {
2129 kind,
2130 left: Box::new(lhs),
2131 right: Box::new(me),
2132 start: spos,
2133 });
2134 kind = self.next_token.kind;
2135 }
2136 Ok(lhs)
2137 }
2138 }
2139 }
2140
2141 pub(crate) fn shift_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2142 match self.add_expr() {
2143 Err(e) => Err(e),
2144 Ok(mut lhs) => {
2145 let mut kind = self.next_token.kind;
2146
2147 while kind == TokenKind::LeftShift || kind == TokenKind::RightShift {
2148 let spos = self.next_token.start;
2149
2150 self.advance()?;
2151
2152 let ae = self.add_expr()?;
2153
2154 lhs = ASTValue::Binary(BinaryNode {
2155 kind,
2156 left: Box::new(lhs),
2157 right: Box::new(ae),
2158 start: spos,
2159 });
2160 kind = self.next_token.kind;
2161 }
2162 Ok(lhs)
2163 }
2164 }
2165 }
2166
2167 pub(crate) fn bitand_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2168 match self.shift_expr() {
2169 Err(e) => Err(e),
2170 Ok(mut lhs) => {
2171 while self.next_token.kind == TokenKind::BitwiseAnd {
2172 let spos = self.next_token.start;
2173
2174 self.advance()?;
2175
2176 let se = self.shift_expr()?;
2177
2178 lhs = ASTValue::Binary(BinaryNode {
2179 kind: TokenKind::BitwiseAnd,
2180 left: Box::new(lhs),
2181 right: Box::new(se),
2182 start: spos,
2183 })
2184 }
2185 Ok(lhs)
2186 }
2187 }
2188 }
2189
2190 pub(crate) fn bitxor_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2191 match self.bitand_expr() {
2192 Err(e) => Err(e),
2193 Ok(mut lhs) => {
2194 while self.next_token.kind == TokenKind::BitwiseXor {
2195 let spos = self.next_token.start;
2196
2197 self.advance()?;
2198
2199 let bae = self.bitand_expr()?;
2200
2201 lhs = ASTValue::Binary(BinaryNode {
2202 kind: TokenKind::BitwiseXor,
2203 left: Box::new(lhs),
2204 right: Box::new(bae),
2205 start: spos,
2206 })
2207 }
2208 Ok(lhs)
2209 }
2210 }
2211 }
2212
2213 pub(crate) fn bitor_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2214 match self.bitxor_expr() {
2215 Err(e) => Err(e),
2216 Ok(mut lhs) => {
2217 while self.next_token.kind == TokenKind::BitwiseOr {
2218 let spos = self.next_token.start;
2219
2220 self.advance()?;
2221
2222 let bxe = self.bitxor_expr()?;
2223
2224 lhs = ASTValue::Binary(BinaryNode {
2225 kind: TokenKind::BitwiseOr,
2226 left: Box::new(lhs),
2227 right: Box::new(bxe),
2228 start: spos,
2229 })
2230 }
2231 Ok(lhs)
2232 }
2233 }
2234 }
2235
2236 pub(crate) fn comparison_operator(&mut self) -> StdResult<TokenKind, RecognizerError> {
2237 let mut should_advance = false;
2238 let mut result = self.next_token.kind;
2239
2240 match self.advance() {
2241 Err(e) => Err(e),
2242 Ok(k) => {
2243 if result == TokenKind::Is && k == TokenKind::Not {
2244 result = TokenKind::IsNot;
2245 should_advance = true;
2246 } else if result == TokenKind::Not && k == TokenKind::In {
2247 result = TokenKind::NotIn;
2248 should_advance = true;
2249 }
2250 if !should_advance {
2251 Ok(result)
2252 } else {
2253 match self.advance() {
2254 Err(e) => Err(e),
2255 Ok(_) => Ok(result),
2256 }
2257 }
2258 }
2259 }
2260 }
2261
2262 pub(crate) fn comparison(&mut self) -> StdResult<ASTValue, RecognizerError> {
2263 match self.bitor_expr() {
2264 Err(e) => Err(e),
2265 Ok(mut lhs) => {
2266 while COMPARISON_OPERATORS.contains(&self.next_token.kind) {
2267 let spos = self.next_token.start;
2268 let k = self.comparison_operator()?;
2269 let boe = self.bitor_expr()?;
2270
2271 lhs = ASTValue::Binary(BinaryNode {
2272 kind: k,
2273 left: Box::new(lhs),
2274 right: Box::new(boe),
2275 start: spos,
2276 })
2277 }
2278 Ok(lhs)
2279 }
2280 }
2281 }
2282
2283 pub(crate) fn not_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2284 if self.next_token.kind != TokenKind::Not {
2285 self.comparison()
2286 } else {
2287 let spos = self.next_token.start;
2288
2289 match self.advance() {
2290 Err(e) => Err(e),
2291 Ok(_) => match self.not_expr() {
2292 Err(e) => Err(e),
2293 Ok(v) => Ok(ASTValue::Unary(UnaryNode {
2294 kind: TokenKind::Not,
2295 operand: Box::new(v),
2296 start: spos,
2297 })),
2298 },
2299 }
2300 }
2301 }
2302
2303 pub(crate) fn and_expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2304 match self.not_expr() {
2305 Err(e) => Err(e),
2306 Ok(mut lhs) => {
2307 while self.next_token.kind == TokenKind::And {
2308 let spos = self.next_token.start;
2309
2310 self.advance()?;
2311
2312 let ne = self.not_expr()?;
2313
2314 lhs = ASTValue::Binary(BinaryNode {
2315 kind: TokenKind::And,
2316 left: Box::new(lhs),
2317 right: Box::new(ne),
2318 start: spos,
2319 })
2320 }
2321 Ok(lhs)
2322 }
2323 }
2324 }
2325
2326 pub fn expr(&mut self) -> StdResult<ASTValue, RecognizerError> {
2328 match self.and_expr() {
2329 Err(e) => Err(e),
2330 Ok(mut lhs) => {
2331 while self.next_token.kind == TokenKind::Or {
2332 let spos = self.next_token.start;
2333
2334 self.advance()?;
2335
2336 let ae = self.and_expr()?;
2337
2338 lhs = ASTValue::Binary(BinaryNode {
2339 kind: TokenKind::Or,
2340 left: Box::new(lhs),
2341 right: Box::new(ae),
2342 start: spos,
2343 })
2344 }
2345 Ok(lhs)
2346 }
2347 }
2348 }
2349}
2350
2351struct StringConverter(fn(&str, &Config) -> Option<Value>);
2355
2356impl PartialEq for StringConverter {
2357 fn eq(&self, other: &Self) -> bool {
2358 self.0 as usize == other.0 as usize
2359 }
2360}
2361
2362impl Clone for StringConverter {
2363 fn clone(&self) -> Self {
2364 Self(self.0)
2365 }
2366}
2367
2368impl fmt::Debug for StringConverter {
2369 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2370 write!(f, "StringConverter({:x})", self.0 as usize)
2371 }
2372}
2373
2374#[derive(Debug, Clone, PartialEq)]
2376pub enum Value {
2377 Base(ScalarValue),
2379 List(Vec<Value>),
2381 Mapping(HashMap<String, Value>),
2383 Config(Config),
2385}
2386
2387impl From<bool> for Value {
2388 fn from(value: bool) -> Self {
2389 Value::Base(ScalarValue::Bool(value))
2390 }
2391}
2392
2393impl From<i64> for Value {
2394 fn from(value: i64) -> Self {
2395 Value::Base(ScalarValue::Integer(value))
2396 }
2397}
2398
2399impl From<f64> for Value {
2400 fn from(value: f64) -> Self {
2401 Value::Base(ScalarValue::Float(value))
2402 }
2403}
2404
2405impl From<String> for Value {
2406 fn from(value: String) -> Self {
2407 Value::Base(ScalarValue::String(value))
2408 }
2409}
2410
2411impl From<&str> for Value {
2412 fn from(value: &str) -> Self {
2413 Value::Base(ScalarValue::String(value.to_string()))
2414 }
2415}
2416
2417impl From<Complex64> for Value {
2418 fn from(value: Complex64) -> Self {
2419 Value::Base(ScalarValue::Complex(value))
2420 }
2421}
2422
2423impl From<NaiveDate> for Value {
2424 fn from(value: NaiveDate) -> Self {
2425 Value::Base(ScalarValue::Date(value))
2426 }
2427}
2428
2429impl From<DateTime<FixedOffset>> for Value {
2430 fn from(value: DateTime<FixedOffset>) -> Self {
2431 Value::Base(ScalarValue::DateTime(value))
2432 }
2433}
2434
2435impl TryInto<i64> for Value {
2436 type Error = &'static str;
2437
2438 fn try_into(self) -> StdResult<i64, Self::Error> {
2439 match self {
2440 Value::Base(b) => match b {
2441 ScalarValue::Integer(i) => Ok(i),
2442 _ => Err(&NOT_INTEGER),
2443 },
2444 _ => Err(&NOT_INTEGER),
2445 }
2446 }
2447}
2448
2449impl TryInto<String> for Value {
2450 type Error = &'static str;
2451
2452 fn try_into(self) -> StdResult<String, Self::Error> {
2453 match self {
2454 Value::Base(b) => match b {
2455 ScalarValue::String(s) => Ok(s),
2456 _ => Err(&NOT_STRING),
2457 },
2458 _ => Err(&NOT_STRING),
2459 }
2460 }
2461}
2462
2463impl TryInto<f64> for Value {
2464 type Error = &'static str;
2465
2466 fn try_into(self) -> StdResult<f64, Self::Error> {
2467 match self {
2468 Value::Base(b) => match b {
2469 ScalarValue::Float(f) => Ok(f),
2470 _ => Err(&NOT_FLOAT),
2471 },
2472 _ => Err(&NOT_FLOAT),
2473 }
2474 }
2475}
2476
2477impl TryInto<Complex64> for Value {
2478 type Error = &'static str;
2479
2480 fn try_into(self) -> StdResult<Complex64, Self::Error> {
2481 match self {
2482 Value::Base(b) => match b {
2483 ScalarValue::Complex(c) => Ok(c),
2484 _ => Err(&NOT_COMPLEX),
2485 },
2486 _ => Err(&NOT_COMPLEX),
2487 }
2488 }
2489}
2490
2491impl TryInto<NaiveDate> for Value {
2492 type Error = &'static str;
2493
2494 fn try_into(self) -> StdResult<NaiveDate, Self::Error> {
2495 match self {
2496 Value::Base(b) => match b {
2497 ScalarValue::Date(nd) => Ok(nd),
2498 _ => Err(&NOT_DATE),
2499 },
2500 _ => Err(&NOT_DATE),
2501 }
2502 }
2503}
2504
2505impl TryInto<DateTime<FixedOffset>> for Value {
2506 type Error = &'static str;
2507
2508 fn try_into(self) -> StdResult<DateTime<FixedOffset>, Self::Error> {
2509 match self {
2510 Value::Base(b) => match b {
2511 ScalarValue::DateTime(dt) => Ok(dt),
2512 _ => Err(&NOT_DATETIME),
2513 },
2514 _ => Err(&NOT_DATETIME),
2515 }
2516 }
2517}
2518
2519impl fmt::Display for Value {
2520 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2521 match self {
2522 Value::Base(b) => write!(f, "{}", b),
2523 Value::List(lv) => {
2524 let mut parts = vec![];
2525
2526 for item in lv {
2527 parts.push(format!("{}", item));
2528 }
2529 let s = parts.join(", ");
2530 write!(f, "[{}]", s)
2531 }
2532 Value::Mapping(mv) => {
2533 let mut parts = vec![];
2534
2535 for (k, v) in mv.iter() {
2536 parts.push(format!("{}: {}", k, v));
2537 }
2538 let s = parts.join(", ");
2539 write!(f, "{{{}}}", s)
2540 }
2541 Value::Config(cv) => write!(f, "{}", cv),
2542 }
2543 }
2544}
2545
2546impl Value {
2547 pub fn as_string(&self) -> String {
2552 let mut result: Option<String> = None;
2553
2554 if let Value::Base(sv) = self {
2555 if let ScalarValue::String(s) = sv {
2556 result = Some(s.clone());
2557 }
2558 }
2559 match result {
2560 None => panic!("expected string value but got {:?}", self),
2561 Some(v) => v,
2562 }
2563 }
2564
2565 pub fn as_i64(&self) -> i64 {
2567 let mut result: Option<i64> = None;
2568
2569 if let Value::Base(sv) = self {
2570 if let ScalarValue::Integer(i) = sv {
2571 result = Some(*i);
2572 }
2573 }
2574 match result {
2575 None => panic!("expected integer value but got {:?}", self),
2576 Some(v) => v,
2577 }
2578 }
2579
2580 pub fn as_f64(&self) -> f64 {
2582 let mut result: Option<f64> = None;
2583
2584 if let Value::Base(sv) = self {
2585 if let ScalarValue::Float(f) = sv {
2586 result = Some(*f);
2587 }
2588 }
2589 match result {
2590 None => panic!("expected floating-point value but got {:?}", self),
2591 Some(v) => v,
2592 }
2593 }
2594
2595 pub fn as_c64(&self) -> Complex64 {
2597 let mut result: Option<Complex64> = None;
2598
2599 if let Value::Base(sv) = self {
2600 if let ScalarValue::Complex(c) = sv {
2601 result = Some(*c);
2602 }
2603 }
2604 match result {
2605 None => panic!("expected complex value but got {:?}", self),
2606 Some(v) => v,
2607 }
2608 }
2609
2610 pub fn as_bool(&self) -> bool {
2612 let mut result: Option<bool> = None;
2613
2614 if let Value::Base(sv) = self {
2615 if let ScalarValue::Bool(b) = sv {
2616 result = Some(*b);
2617 }
2618 }
2619 match result {
2620 None => panic!("expected boolean value but got {:?}", self),
2621 Some(v) => v,
2622 }
2623 }
2624
2625 pub fn as_date(&self) -> NaiveDate {
2627 let mut result: Option<NaiveDate> = None;
2628
2629 if let Value::Base(sv) = self {
2630 if let ScalarValue::Date(nd) = sv {
2631 result = Some(*nd);
2632 }
2633 }
2634 match result {
2635 None => panic!("expected date value but got {:?}", self),
2636 Some(v) => v,
2637 }
2638 }
2639
2640 pub fn as_datetime(&self) -> DateTime<FixedOffset> {
2642 let mut result: Option<DateTime<FixedOffset>> = None;
2643
2644 if let Value::Base(sv) = self {
2645 if let ScalarValue::DateTime(dt) = sv {
2646 result = Some(*dt);
2647 }
2648 }
2649 match result {
2650 None => panic!("expected date/time value but got {:?}", self),
2651 Some(v) => v,
2652 }
2653 }
2654
2655 pub fn as_list(&self) -> Vec<Value> {
2657 let mut result: Option<Vec<Value>> = None;
2658
2659 if let Value::List(lv) = self {
2660 result = Some(lv.clone());
2661 }
2662 match result {
2663 None => panic!("expected list value but got {:?}", self),
2664 Some(v) => v,
2665 }
2666 }
2667
2668 pub fn as_mapping(&self) -> HashMap<String, Value> {
2670 let mut result: Option<HashMap<String, Value>> = None;
2671
2672 if let Value::Mapping(mv) = self {
2673 result = Some(mv.clone());
2674 }
2675 match result {
2676 None => panic!("expected mapping value but got {:?}", self),
2677 Some(v) => v,
2678 }
2679 }
2680
2681 pub fn as_config(&self) -> Config {
2683 let mut result: Option<Config> = None;
2684
2685 if let Value::Config(c) = self {
2686 result = Some(c.clone());
2687 }
2688 match result {
2689 None => panic!("expected config value but got {:?}", self),
2690 Some(v) => v,
2691 }
2692 }
2693}
2694
2695#[derive(Debug, Clone, PartialEq)]
2696pub(crate) enum InternalValue {
2697 Base(Value), List(Vec<Rc<RefCell<InternalValue>>>),
2699 Mapping(HashMap<String, Rc<RefCell<InternalValue>>>),
2700 AST(ASTValue),
2701}
2702
2703impl InternalValue {
2704 fn make_int(i: i64) -> Self {
2781 InternalValue::Base(Value::Base(ScalarValue::Integer(i)))
2782 }
2783
2784 fn make_float(f: f64) -> Self {
2785 InternalValue::Base(Value::Base(ScalarValue::Float(f)))
2786 }
2787
2788 fn make_complex(c: Complex64) -> Self {
2789 InternalValue::Base(Value::Base(ScalarValue::Complex(c)))
2790 }
2791
2792 fn make_string(s: String) -> Self {
2793 InternalValue::Base(Value::Base(ScalarValue::String(s)))
2794 }
2795}
2796
2797#[derive(Debug, PartialEq)]
2799pub enum ConfigError {
2800 SyntaxError(RecognizerError),
2804 NotLoaded,
2807 MappingExpected,
2810 StringExpected(Location),
2815 DuplicateKey(String, Location, Location),
2819 BadFilePath(String),
2822 FileNotFound(String),
2825 FileReadFailed(String),
2828 NoContext,
2831 UnknownVariable(String, Location),
2834 NotPresent(String, Option<Location>),
2838 InvalidPath(RecognizerError),
2842 InvalidPathOperand(Location),
2846 IndexOutOfRange(i64, Location),
2849 EvaluationFailed(Location),
2852 ConversionError(String),
2855 CircularReferenceError(Vec<(String, Location)>),
2858}
2859
2860#[derive(Debug, PartialEq)]
2861pub(crate) enum PathElement<'a> {
2862 Attribute(&'a Token),
2863 IndexedAccess(&'a ASTValue),
2864 SliceAccess(&'a ASTValue),
2865}
2866
2867#[derive(Debug, Clone, PartialEq)]
2870pub struct Config {
2871 pub no_duplicates: bool,
2875 root_dir: String,
2877 path: String,
2878 include_path: Vec<String>,
2879 string_converter: StringConverter,
2880 context: Option<HashMap<String, Value>>,
2881 data: Rc<RefCell<InternalValue>>,
2882 refs_seen: RefCell<HashSet<(String, Location)>>,
2883}
2884
2885impl fmt::Display for Config {
2886 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2887 let fname = Path::new(&self.path)
2888 .file_name()
2889 .expect("couldn't get file name")
2890 .to_str()
2891 .expect("couldn't convert file name to Unicode");
2892 let num_items = match &*self.data.borrow() {
2893 InternalValue::Mapping(hm) => hm.len(),
2894 _ => panic!("Unexpected type for data"),
2895 };
2896 write!(f, "Config(").unwrap();
2897 write!(f, "{}, {} items", fname, num_items).unwrap();
2898 write!(f, ")")
2899 }
2900}
2901
2902fn make_node(v: InternalValue) -> Rc<RefCell<InternalValue>> {
2903 Rc::new(RefCell::new(v))
2904}
2905
2906fn default_string_converter(s: &str, cfg: &Config) -> Option<Value> {
2907 let mut result = None;
2908
2909 fn get_i32(caps: &Captures, i: usize) -> i32 {
2910 caps.get(i).unwrap().as_str().parse::<i32>().unwrap()
2911 }
2912
2913 fn get_u32(caps: &Captures, i: usize) -> u32 {
2914 caps.get(i).unwrap().as_str().parse::<u32>().unwrap()
2915 }
2916
2917 match ISO_DATETIME_PATTERN.captures(s) {
2924 Some(groups) => {
2925 let y = get_i32(&groups, 1);
2926 let m = get_u32(&groups, 2);
2927 let d = get_u32(&groups, 3);
2928 let has_time = groups.get(5).is_some();
2929 let nd = NaiveDate::from_ymd(y, m, d);
2930
2931 if !has_time {
2932 result = Some(Value::from(nd));
2933 } else {
2934 let h = get_u32(&groups, 8);
2935 let m = get_u32(&groups, 9);
2936 let s = get_u32(&groups, 10);
2937 let has_offset = groups.get(13).is_some();
2938 let nanos = match groups.get(11) {
2939 None => 0,
2940 Some(v) => (v.as_str().parse::<f64>().unwrap() * 1.0e9) as u32,
2941 };
2942 let time = NaiveTime::from_hms_nano(h, m, s, nanos);
2943 let datetime = NaiveDateTime::new(nd, time);
2944
2945 let offsecs = if !has_offset {
2946 0
2947 } else {
2948 let sign = if groups.get(13).unwrap().as_str() == "-" {
2949 -1
2950 } else {
2951 1
2952 };
2953 let oh = get_i32(&groups, 14);
2954 let om = get_i32(&groups, 15);
2955 let os = match groups.get(17) {
2956 None => 0,
2957 Some(v) => v.as_str().parse::<i32>().unwrap(),
2958 };
2959 sign * (os + om * 60 + oh * 3600)
2960 };
2961 let offset = FixedOffset::east(offsecs);
2962 let dt = DateTime::<FixedOffset>::from_utc(datetime, offset);
2963 result = Some(Value::from(dt));
2964 }
2965 }
2966 None => match ENV_VALUE_PATTERN.captures(s) {
2967 Some(groups) => {
2968 let name = groups.get(1).unwrap().as_str();
2969
2970 match env::var(name) {
2971 Err(_) => {
2972 let has_pipe = groups.get(2).is_some();
2973
2974 if !has_pipe {
2975 result = Some(Value::Base(ScalarValue::None));
2976 } else {
2977 let s = groups.get(3).unwrap().as_str();
2978
2979 result = Some(Value::from(s))
2980 }
2981 }
2982 Ok(v) => result = Some(Value::from(v)),
2983 }
2984 }
2985 None => match INTERPOLATION_PATTERN.captures(s) {
2986 None => {}
2987 Some(_) => {
2988 let mut failed = false;
2989 let mut cp = 0;
2990 let mut parts = vec![];
2991
2992 for m in INTERPOLATION_PATTERN.find_iter(s) {
2993 let sp = m.start();
2994 let ep = m.end();
2995 let path = &s[sp + 2..ep - 1];
2996
2997 if cp < sp {
2998 parts.push(s[cp..sp].to_string());
2999 }
3000 match cfg.get(path) {
3001 Err(_) => {
3002 failed = true;
3003 break;
3004 }
3005 Ok(v) => {
3006 parts.push(format!("{}", v));
3007 }
3008 }
3009 cp = ep;
3010 }
3011 if !failed {
3012 if cp < s.len() {
3013 parts.push(s[cp..s.len()].to_string());
3014 }
3015 let rv = parts.join("");
3016 result = Some(Value::from(rv.as_str()));
3017 }
3018 }
3019 },
3020 },
3021 }
3022 result
3023}
3024
3025fn find_in_path(fname: &str, path: &[String]) -> Option<String> {
3026 for entry in path {
3027 let mut p = PathBuf::new();
3028
3029 p.push(entry);
3030 p.push(fname);
3031
3032 let path = p.as_path();
3033 if path.exists() {
3034 match path.to_str() {
3035 None => return None,
3036 Some(s) => return Some(s.to_string()),
3037 }
3038 }
3039 }
3040 None
3041}
3042
3043pub(crate) fn parse_path(s: &str) -> StdResult<ASTValue, RecognizerError> {
3044 let c = Cursor::new(s);
3045
3046 match Parser::new(Box::new(c)) {
3047 Err(e) => Err(e),
3048 Ok(mut parser) => {
3049 if parser.next_token.kind != TokenKind::Word {
3050 return Err(RecognizerError::UnexpectedToken(
3051 token_text(TokenKind::Word),
3052 token_text(parser.next_token.kind),
3053 parser.next_token.start,
3054 ));
3055 }
3056 match parser.primary() {
3057 Ok(av) => {
3058 if !parser.at_end() {
3059 Err(RecognizerError::TrailingText(parser.next_token.start))
3060 } else {
3061 Ok(av)
3062 }
3063 }
3064 Err(e) => Err(e),
3065 }
3066 }
3067 }
3068}
3069
3070pub(crate) fn unpack_path<'a>(node: &'a ASTValue) -> Vec<PathElement<'a>> {
3073 let mut path = vec![];
3074
3075 fn visit<'a>(path: &mut Vec<PathElement<'a>>, node: &'a ASTValue) {
3076 match node {
3077 ASTValue::TokenValue(t) => path.push(PathElement::Attribute(&t)),
3078 ASTValue::Unary(un) => visit(path, &un.operand),
3079 ASTValue::Binary(bn) => {
3080 visit(path, &bn.left);
3081 match bn.kind {
3082 TokenKind::Dot => match &*bn.right {
3083 ASTValue::TokenValue(t) => path.push(PathElement::Attribute(&t)),
3084 _ => panic!("unexpected node with attribute access: {:?}", bn.right),
3085 },
3086 TokenKind::LeftBracket => path.push(PathElement::IndexedAccess(&bn.right)),
3087 TokenKind::Colon => path.push(PathElement::SliceAccess(&bn.right)),
3088 _ => panic!("unpack_path not implemented for {:?}", bn),
3089 }
3090 }
3091 _ => panic!("unpack_path not implemented for {:?}", node),
3092 }
3093 }
3094
3095 visit(&mut path, node);
3096 path
3097}
3098
3099pub(crate) fn to_source(node: &ASTValue) -> String {
3100 let path = unpack_path(node);
3101 let mut parts = vec![];
3102
3103 for (i, element) in path.iter().enumerate() {
3104 match element {
3105 PathElement::Attribute(t) => {
3106 if i > 0 {
3107 parts.push(".".to_string());
3108 }
3109 parts.push(t.text.clone());
3110 }
3111 PathElement::IndexedAccess(index) => {
3112 parts.push("[".to_string());
3113 parts.push(to_source(index));
3114 parts.push("]".to_string());
3115 }
3116 PathElement::SliceAccess(slice) => {
3117 parts.push("[".to_string());
3118 match slice {
3119 ASTValue::Slice(_, start, stop, step) => {
3120 if let Some(v) = &**start {
3121 parts.push(to_source(v));
3122 }
3123 parts.push(":".to_string());
3124 if let Some(v) = &**stop {
3125 parts.push(to_source(v));
3126 }
3127 if let Some(v) = &**step {
3128 parts.push(":".to_string());
3129 parts.push(to_source(v));
3130 }
3131 }
3132 _ => panic!("unexpected in slice element: {:?}", slice),
3133 }
3134 parts.push("]".to_string());
3135 }
3136 }
3137 }
3138 parts.join("")
3139}
3140
3141impl Default for Config {
3142 fn default() -> Self {
3143 Self::new()
3144 }
3145}
3146
3147impl Config {
3148 pub fn new() -> Self {
3150 Self {
3151 no_duplicates: true,
3152 root_dir: "".to_string(),
3154 path: "".to_string(),
3155 include_path: vec![],
3156 string_converter: StringConverter(default_string_converter),
3157 context: None,
3158 data: make_node(InternalValue::Mapping(HashMap::new())),
3159 refs_seen: RefCell::new(HashSet::new()),
3160 }
3161 }
3162
3163 pub fn from_file(file_path: &str) -> StdResult<Self, ConfigError> {
3165 let mut result = Config::new();
3166
3167 match result.load_from_file(file_path) {
3168 Ok(()) => Ok(result),
3169 Err(e) => Err(e),
3170 }
3171 }
3172
3173 pub fn add_include(&mut self, dir: &str) {
3175 self.include_path.push(dir.to_string());
3176 }
3177
3178 fn try_open_file(&self, path: &str) -> StdResult<File, ConfigError> {
3179 match File::open(path) {
3180 Err(e) => {
3181 warn!("File read failed for {}: {:?}", path, e);
3182 Err(ConfigError::FileReadFailed(path.to_string()))
3183 }
3184 Ok(f) => Ok(f),
3185 }
3186 }
3187
3188 fn set_path(&mut self, file_path: &str) -> bool {
3189 let p = PathBuf::from(file_path);
3190 let mut failed = false;
3191
3192 match canonicalize(&p) {
3193 Ok(cp) => match cp.to_str() {
3194 Some(s) => {
3195 self.path = s.to_string();
3196 match cp.parent() {
3197 Some(pp) => match pp.to_str() {
3198 None => failed = true,
3199 Some(s) => self.root_dir = s.to_string(),
3200 },
3201 None => failed = true,
3202 }
3203 }
3204 None => {
3205 warn!("failed to convert {:?} to str", cp);
3206 failed = true
3207 }
3208 },
3209 Err(_) => {
3210 warn!("failed to canonicalize {:?}", p);
3211 failed = true
3212 }
3213 };
3214 failed
3215 }
3216
3217 pub fn load_from_file(&mut self, file_path: &str) -> StdResult<(), ConfigError> {
3219 match self.try_open_file(file_path) {
3220 Err(e) => Err(e),
3221 Ok(f) => match self.load(Box::new(f)) {
3222 Err(e) => Err(e),
3223 Ok(()) => {
3224 if self.set_path(file_path) {
3225 Err(ConfigError::BadFilePath(file_path.to_string()))
3226 } else {
3227 Ok(())
3228 }
3229 }
3230 },
3231 }
3232 }
3233
3234 fn wrap_mapping(
3235 &self,
3236 items: &[(Token, ASTValue)],
3237 ) -> StdResult<HashMap<String, Rc<RefCell<InternalValue>>>, ConfigError> {
3238 let mut maybe_seen: Option<HashMap<String, Location>> = if self.no_duplicates {
3240 Some(HashMap::new())
3241 } else {
3242 None
3243 };
3244 let mut result: HashMap<String, Rc<RefCell<InternalValue>>> = HashMap::new();
3245
3246 for (t, v) in items.iter() {
3247 let key: &str;
3248
3249 match &t.value {
3250 ScalarValue::Identifier(iv) => {
3251 key = &iv;
3252 }
3253 ScalarValue::String(sv) => {
3254 key = &sv;
3255 }
3256 _ => panic!("non-string key encountered"),
3257 }
3258 match maybe_seen {
3259 None => {
3260 result.insert(key.to_string(), make_node(InternalValue::AST(v.clone())));
3261 }
3262 Some(ref mut seen) => match seen.get(key) {
3263 Some(orig_loc) => {
3264 return Err(ConfigError::DuplicateKey(
3265 key.to_string(),
3266 t.start,
3267 *orig_loc,
3268 ));
3269 }
3270 None => {
3271 seen.insert(key.to_string(), t.start.clone());
3272 result.insert(key.to_string(), make_node(InternalValue::AST(v.clone())));
3273 }
3274 },
3275 }
3276 }
3277 Ok(result)
3278 }
3279
3280 fn wrap_sequence(&self, items: &[ASTValue]) -> Vec<Rc<RefCell<InternalValue>>> {
3281 let mut result = vec![];
3282
3283 for item in items.iter() {
3284 result.push(make_node(InternalValue::AST(item.clone())));
3285 }
3286 result
3287 }
3288
3289 pub fn load(&mut self, r: Box<dyn Read>) -> StdResult<(), ConfigError> {
3291 let mut parser = Parser::new(r).expect("unable to create parser");
3292
3293 match parser.container() {
3294 Err(e) => Err(ConfigError::SyntaxError(e)),
3295 Ok(node) => {
3296 match node {
3298 ASTValue::Mapping(items) => match self.wrap_mapping(&items) {
3299 Err(e) => Err(e),
3300 Ok(data) => {
3301 self.data = make_node(InternalValue::Mapping(data));
3302 Ok(())
3303 }
3304 },
3305 _ => Err(ConfigError::MappingExpected),
3306 }
3307 }
3308 }
3309 }
3310
3311 pub fn set_context(&mut self, context: HashMap<String, Value>) {
3314 self.context = Some(context)
3315 }
3316
3317 fn eval_at(&self, node: &ASTValue, loc: Location) -> StdResult<InternalValue, ConfigError> {
3318 match self.evaluate(node) {
3319 Err(e) => Err(e),
3320 Ok(v) => match v {
3321 InternalValue::Base(cv) => match cv {
3322 Value::Base(tv) => match tv {
3323 ScalarValue::String(mut fname) => {
3324 let mut dirs = vec![];
3325 let p = Path::new(&fname);
3326
3327 if p.is_absolute() {
3328 dirs.push(p.parent().unwrap().to_str().unwrap().to_string());
3329 fname = p.file_name().unwrap().to_str().unwrap().to_string();
3330 } else {
3331 dirs.push(self.root_dir.clone());
3332 dirs.extend_from_slice(&self.include_path);
3333 }
3334
3335 match find_in_path(&fname, &dirs) {
3336 None => Err(ConfigError::FileNotFound(fname.to_string())),
3337 Some(p) => {
3338 match self.try_open_file(&p) {
3339 Err(e) => Err(e),
3340 Ok(f) => {
3341 let mut parser = Parser::new(Box::new(f))
3342 .expect("unable to create parser");
3343
3344 match parser.container() {
3345 Err(e) => Err(ConfigError::SyntaxError(e)),
3346 Ok(node) => match node {
3347 ASTValue::Mapping(items) => match self
3348 .wrap_mapping(&items)
3349 {
3350 Err(e) => Err(e),
3351 Ok(data) => {
3352 let data = make_node(
3354 InternalValue::Mapping(data),
3355 );
3356 let mut cfg = Config::new();
3357
3358 cfg.no_duplicates = self.no_duplicates;
3359 cfg.context = self.context.clone();
3360 cfg.include_path =
3361 self.include_path.clone();
3362 cfg.set_path(&p);
3363 cfg.data = data;
3364 Ok(InternalValue::Base(Value::Config(
3365 cfg,
3366 )))
3367 }
3368 },
3369 ASTValue::List(items) => {
3370 let mut result = vec![];
3371
3372 for item in items {
3373 result.push(make_node(
3374 InternalValue::AST(item.clone()),
3375 ));
3376 }
3377 Ok(InternalValue::List(result))
3378 }
3379 _ => {
3380 todo!("included data is neither mapping nor list");
3381 }
3382 },
3383 }
3384 }
3385 }
3386 }
3393 }
3394 }
3395 _ => Err(ConfigError::StringExpected(loc)),
3396 },
3397 _ => Err(ConfigError::StringExpected(loc)),
3398 },
3399 _ => todo!("unhandled internal config value"),
3400 },
3401 }
3402 }
3403
3404 fn eval_reference(&self, node: &ASTValue) -> StdResult<InternalValue, ConfigError> {
3405 self.get_from_path(node)
3406 }
3407
3408 fn eval_negation(
3409 &self,
3410 node: &ASTValue,
3411 loc: Location,
3412 ) -> StdResult<InternalValue, ConfigError> {
3413 match self.evaluate(node) {
3414 Err(e) => Err(e),
3415 Ok(v) => match &v {
3416 InternalValue::Base(cv) => match cv {
3417 Value::Base(tv) => match tv {
3418 ScalarValue::Integer(i) => Ok(InternalValue::make_int(-i)),
3419 ScalarValue::Float(f) => Ok(InternalValue::make_float(-f)),
3420 ScalarValue::Complex(c) => Ok(InternalValue::make_complex(-c)),
3421 _ => {
3422 warn!("cannot negate {:?}", v);
3423 Err(ConfigError::EvaluationFailed(loc))
3424 }
3425 },
3426 _ => {
3427 warn!("cannot negate {:?}", v);
3428 Err(ConfigError::EvaluationFailed(loc))
3429 }
3430 },
3431 _ => {
3432 warn!("cannot negate {:?}", v);
3433 Err(ConfigError::EvaluationFailed(loc))
3434 }
3435 },
3436 }
3437 }
3438
3439 fn eval_unary(&self, node: &UnaryNode) -> StdResult<InternalValue, ConfigError> {
3440 match node.kind {
3441 TokenKind::At => self.eval_at(&node.operand, node.start),
3442 TokenKind::Dollar => self.eval_reference(&node.operand),
3443 TokenKind::Minus => self.eval_negation(&node.operand, node.start),
3444 _ => todo!("unhandled unary kind: {:?}", node.kind),
3445 }
3446 }
3447
3448 fn get_operands(
3449 &self,
3450 node: &BinaryNode,
3451 ) -> StdResult<(InternalValue, InternalValue), ConfigError> {
3452 let lhs = self.evaluate(&node.left)?;
3453 let rhs = self.evaluate(&node.right)?;
3454 Ok((lhs, rhs))
3455 }
3456
3457 fn merge_dicts(
3458 &self,
3459 left: &HashMap<String, Rc<RefCell<InternalValue>>>,
3460 right: &HashMap<String, Rc<RefCell<InternalValue>>>,
3461 ) -> StdResult<HashMap<String, Rc<RefCell<InternalValue>>>, ConfigError> {
3462 let mut result = left.clone();
3463
3464 for (k, v) in right.iter() {
3465 let key = k.clone();
3466
3467 match result.get(k) {
3468 None => {
3469 result.insert(key, v.clone());
3471 }
3472 Some(ov) => {
3473 let target: InternalValue;
3477
3478 if let InternalValue::AST(node) = &*ov.borrow() {
3479 target = self.evaluate(&node)?;
3480 } else {
3481 target = ov.borrow().clone();
3482 }
3483 if let InternalValue::Mapping(ref tm) = target {
3484 let source: InternalValue;
3485
3486 if let InternalValue::AST(node) = &*v.borrow() {
3487 source = self.evaluate(&node)?;
3488 } else {
3489 source = ov.borrow().clone();
3490 }
3491 if let InternalValue::Mapping(ref sm) = source {
3492 let merged = self.merge_dicts(tm, sm)?;
3493
3494 result.insert(key, make_node(InternalValue::Mapping(merged)));
3495 } else {
3496 result.insert(key, v.clone());
3497 }
3498 } else {
3499 result.insert(key, v.clone());
3500 }
3501 }
3502 }
3503 }
3504 Ok(result)
3505 }
3506
3507 fn eval_add(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3508 match self.get_operands(node) {
3509 Err(e) => Err(e),
3510 Ok((lhs, rhs)) => match &lhs {
3511 InternalValue::Base(cvlhs) => match &rhs {
3512 InternalValue::Base(cvrhs) => match &cvlhs {
3513 Value::Base(svlhs) => match &cvrhs {
3514 Value::Base(svrhs) => match &svlhs {
3515 ScalarValue::Integer(ilhs) => match &svrhs {
3516 ScalarValue::Integer(irhs) => {
3517 Ok(InternalValue::make_int(ilhs + irhs))
3518 }
3519 ScalarValue::Float(frhs) => {
3520 Ok(InternalValue::make_float(*ilhs as f64 + frhs))
3521 }
3522 ScalarValue::Complex(crhs) => {
3523 let clhs = Complex64::new(*ilhs as f64, 0.0);
3524
3525 Ok(InternalValue::make_complex(clhs + crhs))
3526 }
3527 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3528 },
3529 ScalarValue::Float(flhs) => match &svrhs {
3530 ScalarValue::Integer(irhs) => {
3531 Ok(InternalValue::make_float(flhs + *irhs as f64))
3532 }
3533 ScalarValue::Float(frhs) => {
3534 Ok(InternalValue::make_float(flhs + frhs))
3535 }
3536 ScalarValue::Complex(crhs) => {
3537 let clhs = Complex64::new(*flhs, 0.0);
3538
3539 Ok(InternalValue::make_complex(clhs + crhs))
3540 }
3541 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3542 },
3543 ScalarValue::Complex(clhs) => match &svrhs {
3544 ScalarValue::Integer(irhs) => {
3545 let crhs = Complex64::new(*irhs as f64, 0.0);
3546
3547 Ok(InternalValue::make_complex(clhs + crhs))
3548 }
3549 ScalarValue::Float(frhs) => {
3550 let crhs = Complex64::new(*frhs, 0.0);
3551
3552 Ok(InternalValue::make_complex(clhs + crhs))
3553 }
3554 ScalarValue::Complex(crhs) => {
3555 Ok(InternalValue::make_complex(clhs + crhs))
3556 }
3557 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3558 },
3559 ScalarValue::String(slhs) => match &svrhs {
3560 ScalarValue::String(srhs) => {
3561 let mut r = String::new();
3562
3563 r.push_str(slhs);
3564 r.push_str(srhs);
3565 Ok(InternalValue::make_string(r))
3566 }
3567 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3568 },
3569 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3570 },
3571 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3572 },
3573 Value::List(seqlhs) => match &cvrhs {
3574 Value::List(seqrhs) => {
3575 let mut result = seqlhs.clone();
3576
3577 result.extend(seqrhs.iter().cloned());
3578 Ok(InternalValue::Base(Value::List(result)))
3579 }
3580 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3581 },
3582 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3583 },
3584 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3585 },
3586 InternalValue::List(llhs) => match &rhs {
3587 InternalValue::List(lrhs) => {
3588 let mut result = llhs.clone();
3589
3590 result.extend(lrhs.iter().cloned());
3591 Ok(InternalValue::List(result))
3592 }
3593 InternalValue::Base(b) => match b {
3594 Value::List(seq) => match self.base_unwrap_list(llhs, false) {
3595 Err(e) => Err(e),
3596 Ok(mut result) => {
3597 result.extend(seq.iter().cloned());
3598 Ok(InternalValue::Base(Value::List(result)))
3599 }
3600 },
3601 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3602 },
3603 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3604 },
3605 InternalValue::Mapping(mlhs) => match &rhs {
3606 InternalValue::Mapping(mrhs) => match self.merge_dicts(mlhs, mrhs) {
3607 Err(e) => Err(e),
3608 Ok(v) => Ok(InternalValue::Mapping(v)),
3609 },
3610 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3611 },
3612 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3613 },
3614 }
3615 }
3616
3617 fn eval_subtract(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3618 match self.get_operands(node) {
3619 Err(e) => Err(e),
3620 Ok((lhs, rhs)) => match &lhs {
3621 InternalValue::Base(cvlhs) => match &rhs {
3622 InternalValue::Base(cvrhs) => match &cvlhs {
3623 Value::Base(svlhs) => match &cvrhs {
3624 Value::Base(svrhs) => match &svlhs {
3625 ScalarValue::Integer(ilhs) => match &svrhs {
3626 ScalarValue::Integer(irhs) => {
3627 Ok(InternalValue::make_int(ilhs - irhs))
3628 }
3629 ScalarValue::Float(frhs) => {
3630 Ok(InternalValue::make_float(*ilhs as f64 - frhs))
3631 }
3632 ScalarValue::Complex(crhs) => {
3633 let clhs = Complex64::new(*ilhs as f64, 0.0);
3634
3635 Ok(InternalValue::make_complex(clhs - crhs))
3636 }
3637 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3638 },
3639 ScalarValue::Float(flhs) => match &svrhs {
3640 ScalarValue::Integer(irhs) => {
3641 Ok(InternalValue::make_float(flhs - *irhs as f64))
3642 }
3643 ScalarValue::Float(frhs) => {
3644 Ok(InternalValue::make_float(flhs - frhs))
3645 }
3646 ScalarValue::Complex(crhs) => {
3647 let clhs = Complex64::new(*flhs, 0.0);
3648
3649 Ok(InternalValue::make_complex(clhs - crhs))
3650 }
3651 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3652 },
3653 ScalarValue::Complex(clhs) => match &svrhs {
3654 ScalarValue::Integer(irhs) => {
3655 let crhs = Complex64::new(*irhs as f64, 0.0);
3656
3657 Ok(InternalValue::make_complex(clhs - crhs))
3658 }
3659 ScalarValue::Float(frhs) => {
3660 let crhs = Complex64::new(*frhs, 0.0);
3661
3662 Ok(InternalValue::make_complex(clhs - crhs))
3663 }
3664 ScalarValue::Complex(crhs) => {
3665 Ok(InternalValue::make_complex(clhs - crhs))
3666 }
3667 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3668 },
3669 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3670 },
3671 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3672 },
3673 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3674 },
3675 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3676 },
3677 InternalValue::Mapping(mlhs) => match &rhs {
3678 InternalValue::Mapping(mrhs) => {
3679 let mut result = mlhs.clone();
3680
3681 for (k, _) in mrhs.iter() {
3682 match result.get(k) {
3683 None => {}
3684 Some(_) => {
3685 result.remove(k);
3686 }
3687 }
3688 }
3689
3690 Ok(InternalValue::Mapping(result))
3691 }
3692 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3693 },
3694 _ => todo!("cannot subtract {:?} from {:?}", rhs, lhs),
3695 },
3696 }
3697 }
3698
3699 fn eval_multiply(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3700 match self.get_operands(node) {
3701 Err(e) => Err(e),
3702 Ok((lhs, rhs)) => match &lhs {
3703 InternalValue::Base(cvlhs) => match &rhs {
3704 InternalValue::Base(cvrhs) => match &cvlhs {
3705 Value::Base(svlhs) => match &cvrhs {
3706 Value::Base(svrhs) => match &svlhs {
3707 ScalarValue::Integer(ilhs) => match &svrhs {
3708 ScalarValue::Integer(irhs) => {
3709 Ok(InternalValue::make_int(ilhs * irhs))
3710 }
3711 ScalarValue::Float(frhs) => {
3712 Ok(InternalValue::make_float(*ilhs as f64 * frhs))
3713 }
3714 ScalarValue::Complex(crhs) => {
3715 let clhs = Complex64::new(*ilhs as f64, 0.0);
3716
3717 Ok(InternalValue::make_complex(clhs * crhs))
3718 }
3719 _ => todo!("cannot multiply {:?} by {:?}", lhs, rhs),
3720 },
3721 ScalarValue::Float(flhs) => match &svrhs {
3722 ScalarValue::Integer(irhs) => {
3723 Ok(InternalValue::make_float(flhs * *irhs as f64))
3724 }
3725 ScalarValue::Float(frhs) => {
3726 Ok(InternalValue::make_float(flhs * frhs))
3727 }
3728 ScalarValue::Complex(crhs) => {
3729 let clhs = Complex64::new(*flhs, 0.0);
3730
3731 Ok(InternalValue::make_complex(clhs * crhs))
3732 }
3733 _ => todo!("cannot multiply {:?} by {:?}", lhs, rhs),
3734 },
3735 ScalarValue::Complex(clhs) => match &svrhs {
3736 ScalarValue::Integer(irhs) => {
3737 let crhs = Complex64::new(*irhs as f64, 0.0);
3738
3739 Ok(InternalValue::make_complex(clhs * crhs))
3740 }
3741 ScalarValue::Float(frhs) => {
3742 let crhs = Complex64::new(*frhs, 0.0);
3743
3744 Ok(InternalValue::make_complex(clhs * crhs))
3745 }
3746 ScalarValue::Complex(crhs) => {
3747 Ok(InternalValue::make_complex(clhs * crhs))
3748 }
3749 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3750 },
3751 _ => todo!("cannot multiply {:?} by {:?}", lhs, rhs),
3752 },
3753 _ => todo!("cannot multiply {:?} by {:?}", lhs, rhs),
3754 },
3755 _ => todo!("cannot multiply {:?} by {:?}", lhs, rhs),
3756 },
3757 _ => todo!("cannot multiply {:?} by {:?}", lhs, rhs),
3758 },
3759 _ => todo!("cannot multiply {:?} by {:?}", lhs, rhs),
3760 },
3761 }
3762 }
3763
3764 fn eval_divide(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3765 match self.get_operands(node) {
3766 Err(e) => Err(e),
3767 Ok((lhs, rhs)) => match &lhs {
3768 InternalValue::Base(cvlhs) => match &rhs {
3769 InternalValue::Base(cvrhs) => match &cvlhs {
3770 Value::Base(svlhs) => match &cvrhs {
3771 Value::Base(svrhs) => match &svlhs {
3772 ScalarValue::Integer(ilhs) => match &svrhs {
3773 ScalarValue::Integer(irhs) => Ok(InternalValue::make_float(
3774 (*ilhs as f64) / (*irhs as f64),
3775 )),
3776 ScalarValue::Float(frhs) => {
3777 Ok(InternalValue::make_float(*ilhs as f64 * frhs))
3778 }
3779 ScalarValue::Complex(crhs) => {
3780 let clhs = Complex64::new(*ilhs as f64, 0.0);
3781
3782 Ok(InternalValue::make_complex(clhs / crhs))
3783 }
3784 _ => todo!("cannot divide {:?} by {:?}", lhs, rhs),
3785 },
3786 ScalarValue::Float(flhs) => match &svrhs {
3787 ScalarValue::Integer(irhs) => {
3788 Ok(InternalValue::make_float(flhs - *irhs as f64))
3789 }
3790 ScalarValue::Float(frhs) => {
3791 Ok(InternalValue::make_float(flhs / frhs))
3792 }
3793 ScalarValue::Complex(crhs) => {
3794 let clhs = Complex64::new(*flhs, 0.0);
3795
3796 Ok(InternalValue::make_complex(clhs / crhs))
3797 }
3798 _ => todo!("cannot divide {:?} by {:?}", lhs, rhs),
3799 },
3800 ScalarValue::Complex(clhs) => match &svrhs {
3801 ScalarValue::Integer(irhs) => {
3802 let crhs = Complex64::new(*irhs as f64, 0.0);
3803
3804 Ok(InternalValue::make_complex(clhs / crhs))
3805 }
3806 ScalarValue::Float(frhs) => {
3807 let crhs = Complex64::new(*frhs, 0.0);
3808
3809 Ok(InternalValue::make_complex(clhs / crhs))
3810 }
3811 ScalarValue::Complex(crhs) => {
3812 Ok(InternalValue::make_complex(clhs / crhs))
3813 }
3814 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3815 },
3816 _ => todo!("cannot divide {:?} by {:?}", lhs, rhs),
3817 },
3818 _ => todo!("cannot divide {:?} by {:?}", lhs, rhs),
3819 },
3820 _ => todo!("cannot divide {:?} by {:?}", lhs, rhs),
3821 },
3822 _ => todo!("cannot divide {:?} by {:?}", lhs, rhs),
3823 },
3824 _ => todo!("cannot divide {:?} by {:?}", lhs, rhs),
3825 },
3826 }
3827 }
3828
3829 fn eval_integer_divide(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3830 match self.get_operands(node) {
3831 Err(e) => Err(e),
3832 Ok((lhs, rhs)) => match &lhs {
3833 InternalValue::Base(cvlhs) => match &rhs {
3834 InternalValue::Base(cvrhs) => match &cvlhs {
3835 Value::Base(svlhs) => match &cvrhs {
3836 Value::Base(svrhs) => match &svlhs {
3837 ScalarValue::Integer(ilhs) => match &svrhs {
3838 ScalarValue::Integer(irhs) => {
3839 Ok(InternalValue::make_int(ilhs / irhs))
3840 }
3841 _ => todo!("cannot integer-divide {:?} by {:?}", lhs, rhs),
3842 },
3843 _ => todo!("cannot integer-divide {:?} by {:?}", lhs, rhs),
3844 },
3845 _ => todo!("cannot integer-divide {:?} by {:?}", lhs, rhs),
3846 },
3847 _ => todo!("cannot integer-divide {:?} by {:?}", lhs, rhs),
3848 },
3849 _ => todo!("cannot integer-divide {:?} by {:?}", lhs, rhs),
3850 },
3851 _ => todo!("cannot integer-divide {:?} by {:?}", lhs, rhs),
3852 },
3853 }
3854 }
3855
3856 fn eval_modulo(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3857 match self.get_operands(node) {
3858 Err(e) => Err(e),
3859 Ok((lhs, rhs)) => match &lhs {
3860 InternalValue::Base(cvlhs) => match &rhs {
3861 InternalValue::Base(cvrhs) => match &cvlhs {
3862 Value::Base(svlhs) => match &cvrhs {
3863 Value::Base(svrhs) => match &svlhs {
3864 ScalarValue::Integer(ilhs) => match &svrhs {
3865 ScalarValue::Integer(irhs) => {
3866 Ok(InternalValue::make_int(ilhs % irhs))
3867 }
3868 _ => todo!("cannot compute {:?} modulo {:?}", lhs, rhs),
3869 },
3870 _ => todo!("cannot compute {:?} modulo {:?}", lhs, rhs),
3871 },
3872 _ => todo!("cannot compute {:?} modulo {:?}", lhs, rhs),
3873 },
3874 _ => todo!("cannot compute {:?} modulo {:?}", lhs, rhs),
3875 },
3876 _ => todo!("cannot compute {:?} modulo {:?}", lhs, rhs),
3877 },
3878 _ => todo!("cannot compute {:?} modulo {:?}", lhs, rhs),
3879 },
3880 }
3881 }
3882
3883 fn eval_left_shift(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3884 match self.get_operands(node) {
3885 Err(e) => Err(e),
3886 Ok((lhs, rhs)) => match &lhs {
3887 InternalValue::Base(cvlhs) => match &rhs {
3888 InternalValue::Base(cvrhs) => match &cvlhs {
3889 Value::Base(svlhs) => match &cvrhs {
3890 Value::Base(svrhs) => match &svlhs {
3891 ScalarValue::Integer(ilhs) => match &svrhs {
3892 ScalarValue::Integer(irhs) => {
3893 Ok(InternalValue::make_int(ilhs << irhs))
3894 }
3895 _ => todo!("cannot compute {:?} left-shift {:?}", lhs, rhs),
3896 },
3897 _ => todo!("cannot compute {:?} left-shift {:?}", lhs, rhs),
3898 },
3899 _ => todo!("cannot compute {:?} left-shift {:?}", lhs, rhs),
3900 },
3901 _ => todo!("cannot compute {:?} left-shift {:?}", lhs, rhs),
3902 },
3903 _ => todo!("cannot compute {:?} left-shift {:?}", lhs, rhs),
3904 },
3905 _ => todo!("cannot compute {:?} left-shift {:?}", lhs, rhs),
3906 },
3907 }
3908 }
3909
3910 fn eval_right_shift(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3911 match self.get_operands(node) {
3912 Err(e) => Err(e),
3913 Ok((lhs, rhs)) => match &lhs {
3914 InternalValue::Base(cvlhs) => match &rhs {
3915 InternalValue::Base(cvrhs) => match &cvlhs {
3916 Value::Base(svlhs) => match &cvrhs {
3917 Value::Base(svrhs) => match &svlhs {
3918 ScalarValue::Integer(ilhs) => match &svrhs {
3919 ScalarValue::Integer(irhs) => {
3920 Ok(InternalValue::make_int(ilhs >> irhs))
3921 }
3922 _ => todo!("cannot compute {:?} right-shift {:?}", lhs, rhs),
3923 },
3924 _ => todo!("cannot compute {:?} right-shift {:?}", lhs, rhs),
3925 },
3926 _ => todo!("cannot compute {:?} right-shift {:?}", lhs, rhs),
3927 },
3928 _ => todo!("cannot compute {:?} right-shift {:?}", lhs, rhs),
3929 },
3930 _ => todo!("cannot compute {:?} right-shift {:?}", lhs, rhs),
3931 },
3932 _ => todo!("cannot compute {:?} right-shift {:?}", lhs, rhs),
3933 },
3934 }
3935 }
3936
3937 fn eval_power(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
3938 match self.get_operands(node) {
3939 Err(e) => Err(e),
3940 Ok((lhs, rhs)) => match &lhs {
3941 InternalValue::Base(cvlhs) => match &rhs {
3942 InternalValue::Base(cvrhs) => match &cvlhs {
3943 Value::Base(svlhs) => match &cvrhs {
3944 Value::Base(svrhs) => match &svlhs {
3945 ScalarValue::Integer(ilhs) => match &svrhs {
3946 ScalarValue::Integer(irhs) => {
3947 Ok(InternalValue::make_int(ilhs.pow(*irhs as u32)))
3948 }
3949 ScalarValue::Float(frhs) => {
3950 Ok(InternalValue::make_float((*ilhs as f64).powf(*frhs)))
3951 }
3952 ScalarValue::Complex(crhs) => {
3953 let clhs = Complex64::new(*ilhs as f64, 0.0);
3954
3955 Ok(InternalValue::make_complex(clhs.powc(*crhs)))
3956 }
3957 _ => todo!("cannot raise {:?} to the power of {:?}", lhs, rhs),
3958 },
3959 ScalarValue::Float(flhs) => match &svrhs {
3960 ScalarValue::Integer(irhs) => {
3961 Ok(InternalValue::make_float(flhs.powf(*irhs as f64)))
3962 }
3963 ScalarValue::Float(frhs) => {
3964 Ok(InternalValue::make_float(flhs.powf(*frhs)))
3965 }
3966 ScalarValue::Complex(crhs) => {
3967 let clhs = Complex64::new(*flhs, 0.0);
3968
3969 Ok(InternalValue::make_complex(clhs.powc(*crhs)))
3970 }
3971 _ => todo!("cannot raise {:?} to the power of {:?}", lhs, rhs),
3972 },
3973 ScalarValue::Complex(clhs) => match &svrhs {
3974 ScalarValue::Integer(irhs) => {
3975 let crhs = Complex64::new(*irhs as f64, 0.0);
3976
3977 Ok(InternalValue::make_complex(clhs.powc(crhs)))
3978 }
3979 ScalarValue::Float(frhs) => {
3980 let crhs = Complex64::new(*frhs, 0.0);
3981
3982 Ok(InternalValue::make_complex(clhs.powc(crhs)))
3983 }
3984 ScalarValue::Complex(crhs) => {
3985 Ok(InternalValue::make_complex(clhs.powc(*crhs)))
3986 }
3987 _ => todo!("cannot add {:?} and {:?}", lhs, rhs),
3988 },
3989 _ => todo!("cannot raise {:?} to the power of {:?}", lhs, rhs),
3990 },
3991 _ => todo!("cannot raise {:?} to the power of {:?}", lhs, rhs),
3992 },
3993 _ => todo!("cannot raise {:?} to the power of {:?}", lhs, rhs),
3994 },
3995 _ => todo!("cannot raise {:?} to the power of {:?}", lhs, rhs),
3996 },
3997 _ => todo!("cannot raise {:?} to the power of {:?}", lhs, rhs),
3998 },
3999 }
4000 }
4001
4002 fn eval_bitwise_and(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
4003 match self.get_operands(node) {
4004 Err(e) => Err(e),
4005 Ok((lhs, rhs)) => match &lhs {
4006 InternalValue::Base(cvlhs) => match &rhs {
4007 InternalValue::Base(cvrhs) => match &cvlhs {
4008 Value::Base(svlhs) => match &cvrhs {
4009 Value::Base(svrhs) => match &svlhs {
4010 ScalarValue::Integer(ilhs) => match &svrhs {
4011 ScalarValue::Integer(irhs) => {
4012 Ok(InternalValue::make_int(ilhs & irhs))
4013 }
4014 _ => todo!("cannot compute {:?} bit-and {:?}", lhs, rhs),
4015 },
4016 _ => todo!("cannot compute {:?} bit-and {:?}", lhs, rhs),
4017 },
4018 _ => todo!("cannot compute {:?} bit-and {:?}", lhs, rhs),
4019 },
4020 _ => todo!("cannot compute {:?} bit-and {:?}", lhs, rhs),
4021 },
4022 _ => todo!("cannot compute {:?} bit-and {:?}", lhs, rhs),
4023 },
4024 _ => todo!("cannot compute {:?} bit-and {:?}", lhs, rhs),
4025 },
4026 }
4027 }
4028
4029 fn eval_bitwise_or(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
4030 match self.get_operands(node) {
4031 Err(e) => Err(e),
4032 Ok((lhs, rhs)) => match &lhs {
4033 InternalValue::Base(cvlhs) => match &rhs {
4034 InternalValue::Base(cvrhs) => match &cvlhs {
4035 Value::Base(svlhs) => match &cvrhs {
4036 Value::Base(svrhs) => match &svlhs {
4037 ScalarValue::Integer(ilhs) => match &svrhs {
4038 ScalarValue::Integer(irhs) => {
4039 Ok(InternalValue::make_int(ilhs | irhs))
4040 }
4041 _ => todo!("cannot compute {:?} bit-or {:?}", lhs, rhs),
4042 },
4043 _ => todo!("cannot compute {:?} bit-or {:?}", lhs, rhs),
4044 },
4045 _ => todo!("cannot compute {:?} bit-or {:?}", lhs, rhs),
4046 },
4047 _ => todo!("cannot compute {:?} bit-or {:?}", lhs, rhs),
4048 },
4049 _ => todo!("cannot compute {:?} bit-or {:?}", lhs, rhs),
4050 },
4051 InternalValue::Mapping(mlhs) => match &rhs {
4052 InternalValue::Mapping(mrhs) => match self.merge_dicts(mlhs, mrhs) {
4053 Err(e) => Err(e),
4054 Ok(v) => Ok(InternalValue::Mapping(v)),
4055 },
4056 _ => todo!("cannot compute {:?} bit-or {:?}", lhs, rhs),
4057 },
4058 _ => todo!("cannot compute {:?} bit-or {:?}", lhs, rhs),
4059 },
4060 }
4061 }
4062
4063 fn eval_bitwise_xor(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
4064 match self.get_operands(node) {
4065 Err(e) => Err(e),
4066 Ok((lhs, rhs)) => match &lhs {
4067 InternalValue::Base(cvlhs) => match &rhs {
4068 InternalValue::Base(cvrhs) => match &cvlhs {
4069 Value::Base(svlhs) => match &cvrhs {
4070 Value::Base(svrhs) => match &svlhs {
4071 ScalarValue::Integer(ilhs) => match &svrhs {
4072 ScalarValue::Integer(irhs) => {
4073 Ok(InternalValue::make_int(ilhs ^ irhs))
4074 }
4075 _ => todo!("cannot compute {:?} bit-xor {:?}", lhs, rhs),
4076 },
4077 _ => todo!("cannot compute {:?} bit-xor {:?}", lhs, rhs),
4078 },
4079 _ => todo!("cannot compute {:?} bit-xor {:?}", lhs, rhs),
4080 },
4081 _ => todo!("cannot compute {:?} bit-xor {:?}", lhs, rhs),
4082 },
4083 _ => todo!("cannot compute {:?} bit-xor {:?}", lhs, rhs),
4084 },
4085 _ => todo!("cannot compute {:?} bit-xor {:?}", lhs, rhs),
4086 },
4087 }
4088 }
4089
4090 fn eval_logical_or(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
4091 match self.evaluate(&node.left) {
4092 Err(e) => Err(e),
4093 Ok(v) => match &v {
4094 InternalValue::Base(cv) => match cv {
4095 Value::Base(sv) => match sv {
4096 ScalarValue::Bool(b) => {
4097 if *b {
4098 Ok(v)
4099 } else {
4100 self.evaluate(&node.right)
4101 }
4102 }
4103 _ => Err(ConfigError::EvaluationFailed(node.start)),
4104 },
4105 _ => Err(ConfigError::EvaluationFailed(node.start)),
4106 },
4107 _ => Err(ConfigError::EvaluationFailed(node.start)),
4108 },
4109 }
4110 }
4111
4112 fn eval_logical_and(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
4113 match self.evaluate(&node.left) {
4114 Err(e) => Err(e),
4115 Ok(v) => match &v {
4116 InternalValue::Base(cv) => match cv {
4117 Value::Base(sv) => match sv {
4118 ScalarValue::Bool(b) => {
4119 if !*b {
4120 Ok(v)
4121 } else {
4122 self.evaluate(&node.right)
4123 }
4124 }
4125 _ => Err(ConfigError::EvaluationFailed(node.start)),
4126 },
4127 _ => Err(ConfigError::EvaluationFailed(node.start)),
4128 },
4129 _ => Err(ConfigError::EvaluationFailed(node.start)),
4130 },
4131 }
4132 }
4133
4134 fn eval_binary(&self, node: &BinaryNode) -> StdResult<InternalValue, ConfigError> {
4135 match node.kind {
4136 TokenKind::Plus => self.eval_add(node),
4137 TokenKind::Minus => self.eval_subtract(node),
4138 TokenKind::Star => self.eval_multiply(node),
4139 TokenKind::Slash => self.eval_divide(node),
4140 TokenKind::SlashSlash => self.eval_integer_divide(node),
4141 TokenKind::Modulo => self.eval_modulo(node),
4142 TokenKind::Power => self.eval_power(node),
4143 TokenKind::LeftShift => self.eval_left_shift(node),
4144 TokenKind::RightShift => self.eval_right_shift(node),
4145 TokenKind::BitwiseAnd => self.eval_bitwise_and(node),
4146 TokenKind::BitwiseOr => self.eval_bitwise_or(node),
4147 TokenKind::BitwiseXor => self.eval_bitwise_xor(node),
4148 TokenKind::And => self.eval_logical_and(node),
4149 TokenKind::Or => self.eval_logical_or(node),
4150 _ => todo!("unhandled binary node {:?}", node.kind),
4151 }
4152 }
4153
4154 fn evaluate(&self, node: &ASTValue) -> StdResult<InternalValue, ConfigError> {
4155 match node {
4156 ASTValue::TokenValue(t) => match &t.value {
4157 ScalarValue::Identifier(s) => match self.context {
4158 None => Err(ConfigError::NoContext),
4159 Some(ref cmap) => match cmap.get(s) {
4160 None => Err(ConfigError::UnknownVariable(s.clone(), t.start)),
4161 Some(v) => Ok(InternalValue::Base(v.clone())),
4162 },
4163 },
4164 ScalarValue::String(s) => {
4165 if t.kind == TokenKind::BackTick {
4166 match self.convert_string(&s) {
4167 None => Err(ConfigError::ConversionError(s.to_string())),
4168 Some(v) => Ok(InternalValue::Base(v)),
4169 }
4170 } else {
4171 Ok(InternalValue::Base(Value::Base(t.value.clone())))
4172 }
4173 }
4174 _ => Ok(InternalValue::Base(Value::Base(t.value.clone()))),
4175 },
4176 ASTValue::Unary(un) => self.eval_unary(&un),
4177 ASTValue::Binary(bn) => self.eval_binary(&bn),
4178 ASTValue::Mapping(items) => match self.wrap_mapping(&items) {
4179 Err(e) => Err(e),
4180 Ok(data) => Ok(InternalValue::Mapping(data)),
4181 },
4182 ASTValue::List(items) => Ok(InternalValue::List(self.wrap_sequence(items))),
4183 _ => todo!("other AST node evaluation: {:?}", node),
4184 }
4185 }
4186
4187 pub fn contains_key(&self, key: &str) -> bool {
4190 match &*self.data.borrow() {
4191 InternalValue::Mapping(hm) => hm.get(key).is_some(),
4192 _ => false,
4193 }
4194 }
4195
4196 fn get_location(&self, node: &ASTValue) -> StdResult<Location, ConfigError> {
4197 let result = match node {
4198 ASTValue::TokenValue(t) => t.start,
4199 ASTValue::Unary(un) => un.start,
4200 ASTValue::Binary(bn) => bn.start,
4201 ASTValue::Slice(loc, _, _, _) => *loc,
4202 _ => panic!("unable to determine position for {:?}", node),
4203 };
4204 Ok(result)
4205 }
4206
4207 fn get_slice_index_or_step(
4208 &self,
4209 pos: Location,
4210 maybe_node: &Option<ASTValue>,
4211 ) -> StdResult<Option<i64>, ConfigError> {
4212 match maybe_node {
4213 None => Ok(None),
4214 Some(node) => match self.evaluate(node) {
4215 Err(e) => Err(e),
4216 Ok(v) => match v {
4217 InternalValue::Base(b) => match b {
4218 Value::Base(sv) => match sv {
4219 ScalarValue::Integer(i) => Ok(Some(i)),
4220 _ => Err(ConfigError::InvalidPathOperand(pos)),
4221 },
4222 _ => Err(ConfigError::InvalidPathOperand(pos)),
4223 },
4224 _ => Err(ConfigError::InvalidPathOperand(pos)),
4225 },
4226 },
4227 }
4228 }
4229
4230 fn get_slice(
4231 &self,
4232 pos: Location,
4233 list: &[Rc<RefCell<InternalValue>>],
4234 start: Option<i64>,
4235 stop: Option<i64>,
4236 step: Option<i64>,
4237 ) -> StdResult<Vec<Rc<RefCell<InternalValue>>>, ConfigError> {
4238 let size = list.len() as i64;
4239 let step_value = match step {
4240 None => 1,
4241 Some(i) => i,
4242 };
4243 if step_value == 0 {
4244 return Err(ConfigError::InvalidPathOperand(pos));
4245 }
4246 let mut start_index = match start {
4247 None => 0,
4248 Some(mut i) => {
4249 if i < 0 {
4250 if i >= -size {
4251 i += size;
4252 } else {
4253 i = 0;
4254 }
4255 } else if i >= size {
4256 i = size - 1;
4257 };
4258 i
4259 }
4260 };
4261 let mut stop_index = match stop {
4262 None => size - 1,
4263 Some(mut i) => {
4264 if i < 0 {
4265 if i >= -size {
4266 i += size;
4267 } else {
4268 i = 0;
4269 }
4270 };
4271 if i > size {
4272 i = size;
4273 }
4274 if step_value < 0 {
4275 i += 1;
4276 } else {
4277 i -= 1;
4278 }
4279 i
4280 }
4281 };
4282 if step_value < 0 && start_index < stop_index {
4283 std::mem::swap(&mut stop_index, &mut start_index);
4284 }
4285 let mut i = start_index;
4286 let mut result = vec![];
4287 let mut not_done = if step_value > 0 {
4288 i <= stop_index
4289 } else {
4290 i >= stop_index
4291 };
4292 while not_done {
4293 result.push(list[i as usize].clone());
4294 i += step_value;
4295 not_done = if step_value > 0 {
4296 i <= stop_index
4297 } else {
4298 i >= stop_index
4299 };
4300 }
4301 Ok(result)
4302 }
4303
4304 fn reference_seen(&self, node: &ASTValue) -> bool {
4305 if let ASTValue::Unary(un) = node {
4306 if un.kind == TokenKind::Dollar {
4307 let k = (to_source(node), un.start);
4308
4309 if self.refs_seen.borrow().contains(&k) {
4310 return true;
4311 }
4312 self.refs_seen.borrow_mut().insert(k);
4313 }
4314 }
4315 false
4316 }
4317
4318 fn get_from_path(&self, node: &ASTValue) -> StdResult<InternalValue, ConfigError> {
4319 let path = unpack_path(node);
4320 let mut result = self.data.clone();
4321
4322 for element in path.iter() {
4323 let new_result: Rc<RefCell<InternalValue>>;
4324
4325 match element {
4326 PathElement::Attribute(t) => {
4327 let key = match t.kind {
4328 TokenKind::Word => t.text.clone(),
4329 TokenKind::String => match &t.value {
4330 ScalarValue::String(s) => s.clone(),
4331 _ => panic!("unexpected token value: {:?}", t.value),
4332 },
4333 _ => panic!("unexpected token kind: {:?}", t.kind),
4334 };
4335 match &*result.borrow() {
4336 InternalValue::Base(b) => match b {
4337 Value::Mapping(hm) => match hm.get(&key) {
4338 None => return Err(ConfigError::NotPresent(key, Some(t.start))),
4339 Some(v) => {
4340 new_result = make_node(InternalValue::Base(v.clone()));
4341 }
4342 },
4343 Value::Config(cfg) => {
4344 new_result = make_node(InternalValue::Base(cfg.get(&key)?));
4345 }
4346 _ => return Err(ConfigError::InvalidPathOperand(t.start)),
4347 },
4348 InternalValue::Mapping(hm) => {
4349 match hm.get(&key) {
4350 None => return Err(ConfigError::NotPresent(key, Some(t.start))),
4351 Some(v) => {
4352 new_result = v.clone();
4376 }
4377 }
4378 }
4379 _ => return Err(ConfigError::InvalidPathOperand(t.start)),
4380 }
4381 }
4382 PathElement::IndexedAccess(index_node) => {
4383 let spos = self.get_location(index_node).unwrap();
4384
4385 match &*result.borrow() {
4386 InternalValue::List(lv) => {
4387 let v = self.evaluate(index_node)?;
4388
4389 match v {
4390 InternalValue::Base(b) => match b {
4391 Value::Base(sv) => match sv {
4392 ScalarValue::Integer(mut index) => {
4393 let size = lv.len() as i64;
4394
4395 if index < 0 && index >= -size {
4396 index += size;
4397 }
4398 if index < 0 || index >= size {
4399 return Err(ConfigError::IndexOutOfRange(
4400 index, spos,
4401 ));
4402 }
4403 new_result = lv[index as usize].clone();
4409 }
4410 _ => return Err(ConfigError::InvalidPathOperand(spos)),
4411 },
4412 _ => return Err(ConfigError::InvalidPathOperand(spos)),
4413 },
4414 _ => return Err(ConfigError::InvalidPathOperand(spos)),
4415 }
4416 }
4417 _ => return Err(ConfigError::InvalidPathOperand(spos)),
4418 };
4419 }
4420 PathElement::SliceAccess(slice) => {
4421 let spos = self.get_location(slice).unwrap();
4422
4423 match &*result.borrow() {
4424 InternalValue::List(lv) => match slice {
4425 ASTValue::Slice(loc, start, stop, step) => {
4426 let start_index = self.get_slice_index_or_step(*loc, &*start)?;
4427 let stop_index = self.get_slice_index_or_step(*loc, &*stop)?;
4428 let step_value = self.get_slice_index_or_step(*loc, &*step)?;
4429 let slice =
4430 self.get_slice(*loc, lv, start_index, stop_index, step_value)?;
4431
4432 new_result = make_node(InternalValue::List(slice))
4433 }
4434 _ => {
4435 return Err(ConfigError::InvalidPathOperand(spos));
4436 }
4437 },
4438 _ => return Err(ConfigError::InvalidPathOperand(spos)),
4439 }
4440 }
4441 }
4442
4443 let mut evaluated: Option<InternalValue> = None;
4450
4451 if let InternalValue::AST(node) = &*new_result.borrow() {
4452 if self.reference_seen(node) {
4453 let mut locations: Vec<(String, Location)> =
4454 self.refs_seen.borrow().iter().cloned().collect();
4455
4456 locations.sort();
4457 return Err(ConfigError::CircularReferenceError(locations));
4458 }
4459 evaluated = Some(self.evaluate(node)?);
4460 }
4461 if let Some(icv) = evaluated {
4462 result = make_node(icv);
4463 } else {
4464 result = new_result;
4465 }
4466 }
4467 let r = (&*result).borrow().clone();
4468 Ok(r)
4469 }
4470
4471 fn base_unwrap_list(
4472 &self,
4473 items: &[Rc<RefCell<InternalValue>>],
4474 unwrap_configs: bool,
4475 ) -> StdResult<Vec<Value>, ConfigError> {
4476 let mut result = vec![];
4477
4478 for item in items {
4479 result.push(self.unwrap(&item.borrow(), unwrap_configs)?);
4480 }
4481 Ok(result)
4482 }
4483
4484 fn unwrap_list(
4485 &self,
4486 items: &[Rc<RefCell<InternalValue>>],
4487 unwrap_configs: bool,
4488 ) -> StdResult<Value, ConfigError> {
4489 match self.base_unwrap_list(items, unwrap_configs) {
4490 Err(e) => Err(e),
4491 Ok(v) => Ok(Value::List(v)),
4492 }
4493 }
4494
4495 fn base_unwrap_map(
4496 &self,
4497 map: &HashMap<String, Rc<RefCell<InternalValue>>>,
4498 unwrap_configs: bool,
4499 ) -> StdResult<HashMap<String, Value>, ConfigError> {
4500 let mut result: HashMap<String, Value> = HashMap::new();
4501
4502 for (k, v) in map.iter() {
4503 result.insert(k.to_string(), self.unwrap(&*v.borrow(), unwrap_configs)?);
4504 }
4505 Ok(result)
4506 }
4507
4508 fn unwrap_map(
4509 &self,
4510 map: &HashMap<String, Rc<RefCell<InternalValue>>>,
4511 unwrap_configs: bool,
4512 ) -> StdResult<Value, ConfigError> {
4513 match self.base_unwrap_map(map, unwrap_configs) {
4514 Err(e) => Err(e),
4515 Ok(v) => Ok(Value::Mapping(v)),
4516 }
4517 }
4518
4519 fn unwrap(&self, icv: &InternalValue, unwrap_configs: bool) -> StdResult<Value, ConfigError> {
4520 match icv {
4521 InternalValue::AST(node) => match self.evaluate(&node) {
4522 Err(e) => Err(e),
4523 Ok(icv) => self.unwrap(&icv, unwrap_configs),
4524 },
4525 InternalValue::Base(cv) => match cv {
4526 Value::Config(c) => {
4527 if !unwrap_configs {
4528 Ok(cv.clone())
4529 } else {
4530 Ok(Value::Mapping(c.as_mapping(unwrap_configs)?))
4531 }
4532 }
4533 _ => Ok(cv.clone()),
4534 },
4535 InternalValue::List(items) => self.unwrap_list(&items, unwrap_configs),
4536 InternalValue::Mapping(hm) => self.unwrap_map(&hm, unwrap_configs),
4537 }
4538 }
4539
4540 pub fn as_mapping(
4545 &self,
4546 unwrap_configs: bool,
4547 ) -> StdResult<HashMap<String, Value>, ConfigError> {
4548 let v = self.unwrap(&*self.data.borrow(), unwrap_configs)?;
4549
4550 match v {
4551 Value::Mapping(hm) => Ok(hm),
4552 _ => panic!("unexpected value returned: {:?}", v),
4553 }
4554 }
4555
4556 pub fn get(&self, key: &str) -> StdResult<Value, ConfigError> {
4560 self.refs_seen.borrow_mut().clear();
4561 match &*self.data.borrow() {
4562 InternalValue::Mapping(hm) => {
4563 if hm.is_empty() {
4564 Err(ConfigError::NotLoaded)
4565 } else {
4566 let iv = match hm.get(key) {
4567 None => {
4568 if is_identifier(key) {
4569 Err(ConfigError::NotPresent(key.to_string(), None))
4570 } else {
4571 match parse_path(key) {
4572 Err(e) => Err(ConfigError::InvalidPath(e)),
4573 Ok(node) => self.get_from_path(&node),
4574 }
4575 }
4576 }
4577 Some(v) => {
4578 let r = v.borrow();
4579 Ok(r.clone())
4580 }
4581 };
4582 match iv {
4583 Err(e) => Err(e),
4584 Ok(icv) => self.unwrap(&icv, false),
4585 }
4586 }
4587 }
4588 _ => panic!("unexpected root data type"),
4589 }
4590 }
4591
4592 pub(crate) fn convert_string(&self, s: &str) -> Option<Value> {
4593 (self.string_converter.0)(s, &self)
4594 }
4595}