ps_parser/
parser.rs

1mod command;
2mod error;
3mod predicates;
4mod script_result;
5mod stream_message;
6mod token;
7mod value;
8mod variables;
9
10use std::collections::HashMap;
11
12pub(crate) use command::CommandError;
13use command::{Command, CommandElem};
14pub(crate) use stream_message::StreamMessage;
15use value::{Param, RuntimeObject, ScriptBlock, ValResult};
16use variables::{Scope, SessionScope};
17type ParserResult<T> = core::result::Result<T, ParserError>;
18use error::ParserError;
19type PestError = pest::error::Error<Rule>;
20use pest::Parser;
21use pest_derive::Parser;
22use predicates::{ArithmeticPred, BitwisePred, LogicalPred, StringPred};
23pub use script_result::{PsValue, ScriptResult};
24pub use token::{Token, Tokens};
25pub(crate) use value::{Val, ValType};
26pub use variables::Variables;
27use variables::{VarName, VariableError};
28
29use crate::parser::command::CommandOutput;
30
31type Pair<'i> = ::pest::iterators::Pair<'i, Rule>;
32type Pairs<'i> = ::pest::iterators::Pairs<'i, Rule>;
33
34pub(crate) const NEWLINE: &str = "\n";
35
36macro_rules! unexpected_token {
37    ($pair:expr) => {
38        panic!("Unexpected token: {:?}", $pair.as_rule())
39    };
40}
41
42macro_rules! check_rule {
43    ($pair:expr, $rule:pat) => {
44        if !matches!($pair.as_rule(), $rule) {
45            panic!(
46                "Unexpected token: {:?}, instead of {}",
47                $pair.as_rule(),
48                stringify!($rule)
49            );
50        }
51    };
52}
53
54macro_rules! not_implemented {
55    ($token:expr) => {
56        Err(ParserError::NotImplemented(format!(
57            "Not implemented: {:?}",
58            $token.as_rule()
59        )))
60    };
61}
62
63#[derive(Default)]
64pub(crate) struct Results {
65    output: Vec<StreamMessage>,
66    deobfuscated: Vec<String>,
67}
68
69impl Results {
70    fn new() -> Self {
71        Self {
72            output: Vec::new(),
73            deobfuscated: Vec::new(),
74        }
75    }
76}
77
78#[derive(Parser)]
79#[grammar = "powershell.pest"]
80pub struct PowerShellSession {
81    variables: Variables,
82    tokens: Tokens,
83    errors: Vec<ParserError>,
84    results: Vec<Results>,
85    skip_error: u32,
86}
87
88impl Default for PowerShellSession {
89    fn default() -> Self {
90        Self::new()
91    }
92}
93
94impl<'a> PowerShellSession {
95    /// Creates a new PowerShell parsing session with default settings.
96    ///
97    /// The session is initialized with built-in variables like `$true`,
98    /// `$false`, `$null`, and special variables like `$?` for error status
99    /// tracking.
100    ///
101    /// # Returns
102    ///
103    /// A new `PowerShellSession` instance ready for script evaluation.
104    ///
105    /// # Examples
106    ///
107    /// ```rust
108    /// use ps_parser::PowerShellSession;
109    ///
110    /// let mut session = PowerShellSession::new();
111    /// let result = session.safe_eval("$true").unwrap();
112    /// assert_eq!(result, "True");
113    /// ```
114    pub fn new() -> Self {
115        Self {
116            variables: Variables::new(),
117            tokens: Tokens::new(),
118            errors: Vec::new(),
119            results: Vec::new(),
120            skip_error: 0,
121        }
122    }
123
124    /// Creates a new PowerShell session with the provided variables.
125    ///
126    /// This constructor allows you to initialize the session with a custom set
127    /// of variables, such as environment variables or variables loaded from
128    /// configuration files.
129    ///
130    /// # Arguments
131    ///
132    /// * `variables` - A `Variables` instance containing the initial variable
133    ///   set.
134    ///
135    /// # Returns
136    ///
137    /// A new `PowerShellSession` instance with the provided variables.
138    ///
139    /// # Examples
140    ///
141    /// ```rust
142    /// use ps_parser::{PowerShellSession, Variables};
143    ///
144    /// let env_vars = Variables::env();
145    /// let mut session = PowerShellSession::new().with_variables(env_vars);
146    /// let username = session.safe_eval("$env:USERNAME").unwrap();
147    /// ```
148    pub fn with_variables(mut self, variables: Variables) -> Self {
149        self.variables = variables;
150        self
151    }
152
153    /// Safely evaluates a PowerShell script and returns the output as a string.
154    ///
155    /// This method parses and evaluates the provided PowerShell script,
156    /// handling errors gracefully and returning the result as a formatted
157    /// string. It's the recommended method for simple script evaluation.
158    ///
159    /// # Arguments
160    ///
161    /// * `script` - A string slice containing the PowerShell script to
162    ///   evaluate.
163    ///
164    /// # Returns
165    ///
166    /// * `Result<String, ParserError>` - The output of the script evaluation,
167    ///   or an error if parsing/evaluation fails.
168    ///
169    /// # Examples
170    ///
171    /// ```rust
172    /// use ps_parser::PowerShellSession;
173    ///
174    /// let mut session = PowerShellSession::new();
175    ///
176    /// // Simple arithmetic
177    /// let result = session.safe_eval("1 + 2 * 3").unwrap();
178    /// assert_eq!(result, "7");
179    ///
180    /// // Variable assignment and retrieval
181    /// let result = session.safe_eval("$name = 'World'; \"Hello $name\"").unwrap();
182    /// assert_eq!(result, "Hello World");
183    /// ```
184    pub fn safe_eval(&mut self, script: &str) -> Result<String, ParserError> {
185        let script_res = self.parse_input(script)?;
186        Ok(script_res.result().to_string())
187    }
188
189    pub fn deobfuscate_script(&mut self, script: &str) -> Result<String, ParserError> {
190        self.push_scope_session();
191        let script_res = self.parse_input(script)?;
192        self.pop_scope_session();
193        Ok(script_res.deobfuscated().to_string())
194    }
195
196    pub fn env_variables(&self) -> HashMap<String, PsValue> {
197        self.variables
198            .get_env()
199            .into_iter()
200            .map(|(k, v)| (k, v.into()))
201            .collect()
202    }
203
204    pub fn session_variables(&self) -> HashMap<String, PsValue> {
205        self.variables
206            .get_global()
207            .into_iter()
208            .map(|(k, v)| (k, v.into()))
209            .collect()
210    }
211
212    /// Parses and evaluates a PowerShell script, returning detailed results.
213    ///
214    /// This method provides comprehensive information about the parsing and
215    /// evaluation process, including the final result, generated output,
216    /// any errors encountered, and the tokenized representation of the
217    /// script. It's particularly useful for debugging and deobfuscation.
218    ///
219    /// # Arguments
220    ///
221    /// * `input` - A string slice containing the PowerShell script to parse and
222    ///   evaluate.
223    ///
224    /// # Returns
225    ///
226    /// * `Result<ScriptResult, ParserError>` - A detailed result containing the
227    ///   evaluation outcome, output, errors, and tokens, or a parsing error if
228    ///   the script is malformed.
229    ///
230    /// # Examples
231    ///
232    /// ```rust
233    /// use ps_parser::PowerShellSession;
234    ///
235    /// let mut session = PowerShellSession::new();
236    /// let script_result = session.parse_input("$a = 42; Write-Output $a").unwrap();
237    ///
238    /// println!("Final result: {:?}", script_result.result());
239    /// println!("Generated output: {:?}", script_result.output());
240    /// println!("Parsing errors: {:?}", script_result.errors());
241    /// println!("Deobfuscated code: {:?}", script_result.deobfuscated());
242    /// ```
243    pub fn parse_input(&mut self, input: &str) -> Result<ScriptResult, ParserError> {
244        self.variables.init();
245        let (script_last_output, mut result) = self.parse_subscript(input)?;
246        self.variables.clear_script_functions();
247        Ok(ScriptResult::new(
248            script_last_output,
249            std::mem::take(&mut result.output),
250            std::mem::take(&mut result.deobfuscated),
251            std::mem::take(&mut self.tokens),
252            std::mem::take(&mut self.errors),
253            self.variables
254                .script_scope()
255                .into_iter()
256                .map(|(k, v)| (k, v.into()))
257                .collect(),
258        ))
259    }
260
261    pub(crate) fn parse_subscript(&mut self, input: &str) -> Result<(Val, Results), ParserError> {
262        let mut pairs = PowerShellSession::parse(Rule::program, input)?;
263        //create new scope for script
264        self.results.push(Results::new());
265
266        let program_token = pairs.next().expect("");
267
268        let mut script_last_output = Val::default();
269
270        if let Rule::program = program_token.as_rule() {
271            let mut pairs = program_token.into_inner();
272            let _script_param_block_token = pairs.next().unwrap();
273            if let Some(named_blocks) = pairs.peek()
274                && named_blocks.as_rule() == Rule::named_blocks
275            {
276                //todo
277                let _ = pairs.next();
278            }
279            for token in pairs {
280                let token_str = token.as_str();
281                match token.as_rule() {
282                    Rule::statement_terminator => continue,
283                    Rule::EOI => break,
284                    _ => {}
285                };
286
287                let result = self.eval_statement(token.clone());
288                self.variables.set_status(result.is_ok());
289
290                if let Ok(Val::NonDisplayed(_)) = &result {
291                    continue;
292                }
293
294                script_last_output = match result {
295                    Ok(val) => {
296                        if val != Val::Null {
297                            self.add_output_statement(val.display().into());
298                            self.add_deobfuscated_statement(val.cast_to_script());
299                        }
300
301                        val
302                    }
303                    Err(e) => {
304                        self.errors.push(e);
305                        self.add_deobfuscated_statement(token_str.into());
306                        Val::Null
307                    }
308                };
309            }
310        }
311
312        Ok((script_last_output, self.results.pop().unwrap_or_default()))
313    }
314
315    fn add_function(
316        &mut self,
317        name: String,
318        func: ScriptBlock,
319        scope: Option<Scope>,
320    ) -> ParserResult<Val> {
321        // let func_str= func.to_function(&name, &scope);
322        // self.add_deobfuscated_statement(func_str);
323
324        if let Some(Scope::Global) = &scope {
325            self.variables.add_global_function(name.clone(), func);
326        } else {
327            self.variables.add_script_function(name.clone(), func);
328        }
329
330        Err(ParserError::Skip)
331    }
332
333    pub(crate) fn parse_function_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
334        check_rule!(token, Rule::function_statement);
335
336        let mut pair = token.into_inner();
337
338        let function_keyword_token = pair.next().unwrap();
339        check_rule!(function_keyword_token, Rule::function_keyword);
340
341        let mut next_token = pair.next().unwrap();
342        let scope = if next_token.as_rule() == Rule::scope_keyword {
343            let scope = Scope::from(next_token.as_str());
344            next_token = pair.next().unwrap();
345            Some(scope)
346        } else {
347            None
348        };
349
350        let function_name_token = next_token;
351        check_rule!(function_name_token, Rule::function_name);
352        let fname = function_name_token.as_str().to_ascii_lowercase();
353
354        let Some(mut next_token) = pair.next() else {
355            //empty function
356            return self.add_function(fname, ScriptBlock::empty(), scope);
357        };
358
359        let params = if next_token.as_rule() == Rule::parameter_list {
360            let param_list = self.parse_parameter_list(next_token)?;
361            if let Some(token) = pair.next() {
362                next_token = token;
363            } else {
364                return self.add_function(fname, ScriptBlock::empty(), scope);
365            }
366
367            param_list
368        } else {
369            Vec::new()
370        };
371        check_rule!(next_token, Rule::script_block);
372
373        let mut script_block = self.parse_script_block(next_token)?;
374
375        if script_block.params.0.is_empty() {
376            script_block = script_block.with_params(params);
377        }
378
379        self.add_function(fname, script_block, scope)
380    }
381
382    pub(crate) fn eval_if_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
383        check_rule!(token, Rule::if_statement);
384        let mut pair = token.into_inner();
385        let condition_token = pair.next().unwrap();
386        let true_token = pair.next().unwrap();
387        let condition_val = self.eval_pipeline(condition_token.clone())?;
388        let res = if condition_val.cast_to_bool() {
389            self.eval_statement_block(true_token)?
390        } else if let Some(mut token) = pair.next() {
391            if token.as_rule() == Rule::elseif_clauses {
392                for else_if in token.into_inner() {
393                    let mut pairs = else_if.into_inner();
394                    let condition_token = pairs.next().unwrap();
395                    let statement_token = pairs.next().unwrap();
396                    let condition_val = self.eval_pipeline(condition_token)?;
397                    if condition_val.cast_to_bool() {
398                        return self.eval_statement_block(statement_token);
399                    }
400                }
401                let Some(token2) = pair.next() else {
402                    return Ok(Val::Null);
403                };
404                token = token2;
405            }
406            if token.as_rule() == Rule::else_condition {
407                let statement_token = token.into_inner().next().unwrap();
408                self.eval_statement_block(statement_token)?
409            } else {
410                Val::Null
411            }
412        } else {
413            Val::Null
414        };
415
416        Ok(res)
417    }
418
419    fn eval_flow_control_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
420        check_rule!(token, Rule::flow_control_statement);
421        let token = token.into_inner().next().unwrap();
422
423        Ok(match token.as_rule() {
424            Rule::flow_control_label_statement => Val::Null, //TODO
425            Rule::flow_control_pipeline_statement => {
426                let token = token.into_inner().next().unwrap();
427                //todo: throw, return or exit
428                if let Some(pipeline_token) = token.into_inner().next() {
429                    self.eval_pipeline(pipeline_token)?
430                } else {
431                    Val::Null
432                }
433            }
434            _ => unexpected_token!(token),
435        })
436    }
437
438    fn eval_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
439        match token.as_rule() {
440            Rule::pipeline => self.eval_pipeline(token),
441            Rule::if_statement => self.eval_if_statement(token),
442            Rule::flow_control_statement => self.eval_flow_control_statement(token),
443            Rule::function_statement => self.parse_function_statement(token),
444            Rule::statement_terminator => Ok(Val::Null),
445            Rule::EOI => Ok(Val::Null),
446            _ => {
447                not_implemented!(token)
448            }
449        }
450    }
451
452    fn safe_eval_sub_expr(&mut self, token: Pair<'a>) -> ParserResult<Val> {
453        // match self.eval_statements(token.clone()) {
454        //     Ok(vals) => Ok(Val::Array(vals)),
455        //     Err(err) => {
456        //         self.errors.push(err);
457        //         Ok(Val::ScriptText(token.as_str().to_string()))
458        //     }
459        // }
460        check_rule!(token, Rule::sub_expression);
461        let Some(inner_token) = token.into_inner().next() else {
462            return Ok(Val::Null);
463        };
464        let mut inner_val = self.eval_pipeline(inner_token)?;
465        if let Val::ScriptText(script) = &mut inner_val {
466            *script = format!("$({})", script);
467            //self.tokens.push(Token::SubExpression(script.clone()));
468        }
469        Ok(inner_val)
470    }
471
472    fn eval_statement_block(&mut self, token: Pair<'a>) -> ParserResult<Val> {
473        Ok(self
474            .safe_eval_statements(token)?
475            .iter()
476            .last()
477            .cloned()
478            .unwrap_or(Val::Null))
479    }
480
481    fn eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
482        //check_rule!(token, Rule::statements);
483        let pairs = token.into_inner();
484        let mut statements = vec![];
485
486        for token in pairs {
487            let s = self.eval_statement(token)?;
488            statements.push(s);
489        }
490        Ok(statements)
491    }
492
493    fn safe_eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
494        //check_rule!(token, Rule::statements);
495        let pairs = token.into_inner();
496        let mut statements = vec![];
497
498        for token in pairs {
499            match self.eval_statement(token.clone()) {
500                Ok(s) => statements.push(s),
501                Err(err) => {
502                    self.errors.push(err);
503                    statements.push(Val::ScriptText(token.as_str().to_string()));
504                }
505            }
506        }
507        Ok(statements)
508    }
509
510    fn parse_dq(&mut self, token: Pair<'a>) -> ParserResult<String> {
511        let mut res_str = String::new();
512        let pairs = token.into_inner();
513        for token in pairs {
514            let token = token.into_inner().next().unwrap();
515            let s = match token.as_rule() {
516                Rule::variable => self.get_variable(token)?.cast_to_string(),
517                Rule::sub_expression => self.safe_eval_sub_expr(token)?.cast_to_string(),
518                Rule::backtick_escape => token
519                    .as_str()
520                    .strip_prefix("`")
521                    .unwrap_or_default()
522                    .to_string(),
523                _ => token.as_str().to_string(),
524            };
525            res_str.push_str(s.as_str());
526        }
527        Ok(res_str)
528    }
529
530    fn eval_string_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
531        check_rule!(token, Rule::string_literal);
532        let mut pair = token.into_inner();
533        let token = pair.next().unwrap();
534        let cloned_token = token.clone();
535
536        let mut is_expandable = false;
537        let res = match token.as_rule() {
538            Rule::doublequoted_string_literal | Rule::doublequoted_multiline_string_literal => {
539                is_expandable = true;
540                self.parse_dq(token)?
541            }
542            Rule::singlequoted_string_literal => {
543                let token_string = token.as_str().to_string();
544                let stripped_prefix = token_string
545                    .strip_prefix("'")
546                    .unwrap_or(token_string.as_str());
547                let stripped_suffix = stripped_prefix.strip_suffix("'").unwrap_or(stripped_prefix);
548                stripped_suffix.to_string()
549            }
550            Rule::singlequoted_multiline_string_literal => {
551                let mut res_str = String::new();
552                let pairs = token.into_inner();
553                for token in pairs {
554                    res_str.push_str(token.as_str());
555                }
556                res_str
557            }
558            _ => unexpected_token!(token),
559        };
560        let ps_token = if is_expandable {
561            Token::StringExpandable(cloned_token.as_str().to_string(), res.clone())
562        } else {
563            Token::String(cloned_token.as_str().to_string())
564        };
565        self.tokens.push(ps_token);
566
567        Ok(Val::String(res.into()))
568    }
569
570    fn get_variable(&mut self, token: Pair<'a>) -> ParserResult<Val> {
571        check_rule!(token, Rule::variable);
572        let var_name = Self::parse_variable(token)?;
573        let Some(var) = self.variables.get(&var_name) else {
574            return Err(ParserError::VariableError(VariableError::NotDefined(
575                var_name.name,
576            )));
577        };
578        Ok(var)
579    }
580
581    fn parse_scoped_variable(token: Pair<'a>) -> ParserResult<VarName> {
582        //can be scoped or splatted
583        let mut pairs = token.into_inner();
584        let mut token = pairs.next().unwrap();
585
586        let scope = if token.as_rule() == Rule::scope_keyword {
587            let scope = token.as_str().to_ascii_lowercase();
588            token = pairs.next().unwrap();
589            check_rule!(token, Rule::var_name);
590            Some(Scope::from(scope.as_str()))
591        } else {
592            None
593        };
594        Ok(VarName::new(scope, token.as_str().to_ascii_lowercase()))
595    }
596
597    fn skip_value_access(&mut self, token: Pair<'a>) -> ParserResult<()> {
598        check_rule!(token, Rule::value_access);
599        let mut pair = token.into_inner();
600        let token = pair.next().unwrap();
601        let mut val = self.eval_value(token)?;
602        let _ = self.eval_element_access(pair.next().unwrap(), &mut val)?;
603        Err(ParserError::Skip)
604    }
605
606    // fn get_assignable_variable<'b>(&mut self, pairs: Pairs<'a>, object: &'b mut
607    // Val) -> ParserResult<&'b mut Val> {     let mut var = object;
608    //     for token in pairs {
609    //             let tmp = self.variable_access(token, &mut var)?;
610    //             var = tmp;
611    //     }
612    //     Ok(var)
613    // }
614
615    fn parse_assignable_variable(
616        &mut self,
617        token: Pair<'a>,
618    ) -> ParserResult<(VarName, Option<Pairs<'a>>)> {
619        check_rule!(token, Rule::assignable_variable);
620        let mut pair = token.into_inner();
621        let token = pair.next().unwrap();
622        match token.as_rule() {
623            Rule::variable => {
624                let var_name = Self::parse_variable(token)?;
625
626                Ok((var_name, None))
627            }
628            Rule::variable_access => {
629                let mut pairs = token.into_inner();
630                let var_token = pairs.next().unwrap();
631                let var_name = Self::parse_variable(var_token)?;
632                // let mut object = &mut var;
633                // for token in pairs {
634                //     object = self.variable_access(token, &mut object)?;
635                // }
636                Ok((var_name, Some(pairs)))
637            }
638            Rule::value_access => self
639                .skip_value_access(token)
640                .map(|()| (Default::default(), None)),
641            _ => unexpected_token!(token),
642        }
643    }
644
645    fn parse_variable(token: Pair<'a>) -> ParserResult<VarName> {
646        check_rule!(token, Rule::variable);
647        let mut pair = token.into_inner();
648        let token = pair.next().unwrap();
649
650        Ok(match token.as_rule() {
651            Rule::special_variable => {
652                VarName::new_with_scope(Scope::Special, token.as_str().to_string())
653            }
654            Rule::parenthesized_variable => {
655                Self::parse_variable(token.into_inner().next().unwrap())?
656            }
657            Rule::braced_variable => {
658                let token = token.into_inner().next().unwrap();
659                let var = token.as_str().to_ascii_lowercase();
660                let splits: Vec<&str> = var.split(":").collect();
661                if splits.len() == 2 {
662                    VarName::new_with_scope(Scope::from(splits[0]), splits[1].to_string())
663                } else {
664                    VarName::new(None, var)
665                }
666            }
667            Rule::scoped_variable => Self::parse_scoped_variable(token)?,
668            _ => unexpected_token!(token),
669        })
670    }
671
672    fn eval_expression_with_unary_operator(&mut self, token: Pair<'a>) -> ParserResult<Val> {
673        check_rule!(token, Rule::expression_with_unary_operator);
674        let mut pair = token.into_inner();
675        let token = pair.next().unwrap();
676
677        let res = match token.as_rule() {
678            Rule::pre_inc_expression => {
679                let variable_token = token.into_inner().next().unwrap();
680                let var_name = Self::parse_variable(variable_token)?;
681                let mut var = self.variables.get(&var_name).unwrap_or_default();
682                var.inc()?;
683
684                self.variables.set(&var_name, var.clone())?;
685                var
686            }
687            Rule::pre_dec_expression => {
688                let variable_token = token.into_inner().next().unwrap();
689                let var_name = Self::parse_variable(variable_token)?;
690                let mut var = self.variables.get(&var_name).unwrap_or_default();
691                var.dec()?;
692
693                self.variables.set(&var_name, var.clone())?;
694                var
695            }
696            Rule::cast_expression => self.eval_cast_expression(token)?,
697            Rule::negate_op => {
698                let unary_token = pair.next().unwrap();
699                let unary = self.eval_unary_exp(unary_token)?;
700                Val::Bool(!unary.cast_to_bool())
701            }
702            Rule::bitwise_negate_op => {
703                let unary_token = pair.next().unwrap();
704                let unary = self.eval_unary_exp(unary_token)?;
705                Val::Int(!unary.cast_to_int()?)
706            }
707            _ => unexpected_token!(token),
708        };
709
710        Ok(res)
711    }
712
713    fn eval_argument_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
714        check_rule!(token, Rule::argument_list);
715        let mut pairs = token.into_inner();
716        let token = pairs.next().unwrap();
717
718        self.skip_error += 1;
719
720        let arg = self.eval_expression(token.clone())?;
721        self.skip_error -= 1;
722
723        if let Val::Array(vec) = arg {
724            Ok(vec)
725        } else {
726            Ok(vec![arg])
727        }
728    }
729
730    fn eval_member_access(&mut self, token: Pair<'a>) -> ParserResult<String> {
731        //check_rule!(token, Rule::member_access);
732        let member_name_token = token.into_inner().next().unwrap();
733        let member_name = member_name_token.as_str().to_ascii_lowercase();
734
735        Ok(member_name)
736    }
737
738    fn method_is_static(&mut self, token: Pair<'a>) -> bool {
739        check_rule!(token, Rule::method_invocation);
740        let mut pairs = token.into_inner();
741
742        let access = pairs.next().unwrap();
743        match access.as_rule() {
744            Rule::member_access => false,
745            Rule::static_access => true,
746            _ => unexpected_token!(access),
747        }
748    }
749
750    fn eval_method_invokation(&mut self, token: Pair<'a>) -> ParserResult<(String, Vec<Val>)> {
751        check_rule!(token, Rule::method_invocation);
752        let token_string = token.as_str().to_string();
753
754        let mut pairs = token.into_inner();
755
756        let access = pairs.next().unwrap();
757        //check_rule!(member_access, Rule::member_access);
758        let method_name = self.eval_member_access(access)?;
759
760        let args = if let Some(token) = pairs.next() {
761            check_rule!(token, Rule::argument_list);
762            self.eval_argument_list(token)?
763        } else {
764            Vec::new()
765        };
766
767        self.tokens.push(Token::Function(
768            token_string,
769            method_name.clone(),
770            args.clone().iter().map(|arg| arg.clone().into()).collect(),
771        ));
772        Ok((method_name, args))
773    }
774
775    fn eval_element_access<'b>(
776        &mut self,
777        token: Pair<'a>,
778        object: &'b mut Val,
779    ) -> ParserResult<&'b mut Val> {
780        let mut pairs = token.into_inner();
781        let index_token = pairs.next().unwrap();
782        check_rule!(index_token, Rule::expression);
783        let index = self.eval_expression(index_token)?;
784        Ok(object.get_index(index)?)
785    }
786
787    fn variable_access<'b>(
788        &mut self,
789        token: Pair<'a>,
790        object: &'b mut Val,
791    ) -> ParserResult<&'b mut Val> {
792        fn get_member_name(token: Pair<'_>) -> &'_ str {
793            token.into_inner().next().unwrap().as_str()
794        }
795        match token.as_rule() {
796            Rule::static_access => {
797                //todo
798                Err(ParserError::NotImplemented(
799                    "modificable static_member".into(),
800                ))
801            }
802            Rule::member_access => Ok(object.member(get_member_name(token))?),
803            Rule::element_access => Ok(self.eval_element_access(token, object)?),
804            _ => unexpected_token!(token),
805        }
806    }
807
808    fn value_access(&mut self, token: Pair<'a>, object: &mut Val) -> ParserResult<Val> {
809        fn get_member_name(token: Pair<'_>) -> &'_ str {
810            token.into_inner().next().unwrap().as_str()
811        }
812        Ok(match token.as_rule() {
813            Rule::static_access => object.readonly_static_member(get_member_name(token))?,
814            Rule::member_access => object.readonly_member(get_member_name(token))?.clone(),
815            Rule::method_invocation => {
816                let static_method = self.method_is_static(token.clone());
817                let (function_name, args) = self.eval_method_invokation(token)?;
818                log::trace!("Method: {:?} {:?}", &function_name, &args);
819                if static_method {
820                    let call = object.static_method(function_name.as_str())?;
821                    call(args)?
822                } else {
823                    let call = object.method(function_name.as_str())?;
824                    call(object, args)?
825                }
826            }
827            Rule::element_access => self.eval_element_access(token, object)?.clone(),
828            _ => unexpected_token!(token),
829        })
830    }
831
832    fn eval_value_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
833        check_rule!(token, Rule::value_access);
834        let mut pairs = token.into_inner();
835        let token = pairs.next().unwrap();
836
837        let mut object = self.eval_value(token)?;
838        for token in pairs {
839            object = self.value_access(token, &mut object)?;
840        }
841        log::debug!("Success eval_access: {:?}", object);
842        Ok(object)
843    }
844
845    fn parse_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
846        check_rule!(token, Rule::value_access);
847        let mut pairs = token.into_inner();
848        let token = pairs.next().unwrap();
849
850        let mut object = self
851            .eval_value(token.clone())
852            .map(|v| v.cast_to_script())
853            .unwrap_or(token.as_str().to_string());
854
855        for token in pairs {
856            match token.as_rule() {
857                Rule::static_access => {
858                    object.push_str(token.as_str());
859                }
860                Rule::member_access => {
861                    object.push_str(token.as_str());
862                }
863                Rule::method_invocation => {
864                    let static_method = self.method_is_static(token.clone());
865                    let (method_name, args) = self.eval_method_invokation(token.clone())?;
866                    let separator = if static_method { "::" } else { "." };
867                    object = format!(
868                        "{}{separator}{}({})",
869                        object,
870                        method_name.to_ascii_lowercase(),
871                        args.iter()
872                            .map(|arg| arg.cast_to_script())
873                            .collect::<Vec<String>>()
874                            .join(", ")
875                    )
876                }
877                Rule::element_access => {
878                    let mut pairs = token.into_inner();
879                    let index_token = pairs.next().unwrap();
880                    check_rule!(index_token, Rule::expression);
881                    let index = self.eval_expression(index_token)?;
882                    object = format!("{}[{}]", object, index);
883                }
884                _ => unexpected_token!(token),
885            }
886        }
887        Ok(Val::String(object.into()))
888    }
889
890    fn eval_primary_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
891        check_rule!(token, Rule::primary_expression);
892        let mut pair = token.into_inner();
893        let token = pair.next().unwrap();
894        let res = match token.as_rule() {
895            Rule::value_access => match self.eval_value_access(token.clone()) {
896                Ok(res) => res,
897                Err(err) => {
898                    log::info!("eval_access error: {:?}", err);
899                    self.errors.push(err);
900                    self.parse_access(token)?
901                }
902            },
903            Rule::value => self.eval_value(token)?,
904            Rule::post_inc_expression => {
905                let variable_token = token.into_inner().next().unwrap();
906                let var_name = Self::parse_variable(variable_token)?;
907                let mut var = self.variables.get(&var_name).unwrap_or_default();
908                let var_to_return = var.clone();
909
910                var.inc()?;
911                self.variables.set(&var_name, var.clone())?;
912
913                //if var_to_return.ttype() ==
914                var_to_return
915            }
916            Rule::post_dec_expression => {
917                let variable_token = token.into_inner().next().unwrap();
918                let var_name = Self::parse_variable(variable_token)?;
919                let mut var = self.variables.get(&var_name).unwrap_or_default();
920                let var_to_return = var.clone();
921
922                var.dec()?;
923                self.variables.set(&var_name, var.clone())?;
924
925                var_to_return
926            }
927            _ => unexpected_token!(token),
928        };
929
930        Ok(res)
931    }
932
933    fn eval_type_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
934        check_rule!(token, Rule::type_literal);
935
936        let token = token.into_inner().next().unwrap();
937        check_rule!(token, Rule::type_spec);
938        Ok(ValType::runtime(token.as_str())?)
939    }
940
941    fn parse_script_block(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
942        check_rule!(token, Rule::script_block);
943
944        let raw_text = token.as_str().to_string();
945
946        let mut pairs = token.into_inner();
947        let Some(token) = pairs.next() else {
948            return Ok(ScriptBlock::new(vec![], String::new(), raw_text));
949        };
950
951        let params = self.parse_script_param_block(token.clone())?;
952        //let params_str = token.as_str().to_string();
953
954        let script_body = if let Some(token) = pairs.next() {
955            check_rule!(token, Rule::script_block_body);
956            token.as_str().to_string()
957        } else {
958            String::new()
959        };
960
961        Ok(ScriptBlock::new(params, script_body, raw_text))
962
963        //todo is it necessary?
964        // Ok(if let Ok(deobfuscated_body) =
965        // self.deobfuscate_script(&script_body) {
966        //     ScriptBlock::new(params, deobfuscated_body.clone(),
967        // format!("{};{}", params_str, deobfuscated_body)) } else {
968        //     ScriptBlock::new(params, script_body, raw_text)
969        // })
970    }
971
972    fn parse_script_block_expression(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
973        check_rule!(token, Rule::script_block_expression);
974        let mut pairs = token.into_inner();
975        self.parse_script_block(pairs.next().unwrap())
976    }
977
978    fn eval_hash_key(&mut self, token: Pair<'a>) -> ParserResult<String> {
979        check_rule!(token, Rule::key_expression);
980        let mut pairs = token.into_inner();
981        let key_token = pairs.next().unwrap();
982
983        Ok(match key_token.as_rule() {
984            Rule::simple_name => key_token.as_str().to_ascii_lowercase(),
985            Rule::unary_exp => self
986                .eval_unary_exp(key_token)?
987                .cast_to_string()
988                .to_ascii_lowercase(),
989            _ => unexpected_token!(key_token),
990        })
991    }
992
993    fn eval_hash_entry(&mut self, token: Pair<'a>) -> ParserResult<(String, Val)> {
994        check_rule!(token, Rule::hash_entry);
995
996        let mut pairs = token.into_inner();
997        let token_key = pairs.next().unwrap();
998        let token_value = pairs.next().unwrap();
999        let value = match token_value.as_rule() {
1000            //Rule::statement => self.eval_statement(token_value)?,
1001            Rule::type_literal => self.eval_type_literal(token_value)?,
1002            _ => self.eval_statement(token_value)?,
1003        };
1004
1005        Ok((self.eval_hash_key(token_key)?, value))
1006    }
1007
1008    fn eval_hash_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1009        check_rule!(token, Rule::hash_literal_expression);
1010        let pairs = token.into_inner();
1011        let mut hash = HashMap::new();
1012        for token in pairs {
1013            let (key, value) = self.eval_hash_entry(token)?;
1014            hash.insert(key, value);
1015        }
1016        Ok(Val::HashTable(hash))
1017    }
1018
1019    // fn get_variable_access(&mut self, token: Pair<'a>) -> ParserResult<&mut Val>
1020    // {     check_rule!(token, Rule::variable_access);
1021    //     let mut pair = token.into_inner();
1022    //     let var_token = pair.next().unwrap();
1023    //     let mut object = self.get_variable(var_token)?;
1024    //     let access_token = pair.next().unwrap();
1025    //     Ok(self.eval_element_access(access_token, &mut object)?)
1026    // }
1027
1028    fn eval_value(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1029        check_rule!(token, Rule::value);
1030        let mut pair = token.into_inner();
1031        let token = pair.next().unwrap();
1032
1033        let res = match token.as_rule() {
1034            Rule::parenthesized_expression => {
1035                let token = token.into_inner().next().unwrap();
1036                self.safe_eval_pipeline(token)?
1037            }
1038            Rule::sub_expression | Rule::array_expression => {
1039                let statements = self.eval_statements(token)?;
1040                if statements.len() == 1 {
1041                    if let Val::Array(_) = statements[0] {
1042                        statements[0].clone()
1043                    } else {
1044                        Val::Array(statements)
1045                    }
1046                } else {
1047                    Val::Array(statements)
1048                }
1049            }
1050            Rule::script_block_expression => {
1051                Val::ScriptBlock(self.parse_script_block_expression(token)?)
1052            }
1053            Rule::hash_literal_expression => self.eval_hash_literal(token)?,
1054            Rule::string_literal => self.eval_string_literal(token)?,
1055            Rule::number_literal => self.eval_number_literal(token)?,
1056            Rule::type_literal => self.eval_type_literal(token)?,
1057            Rule::variable => self.get_variable(token)?,
1058            _ => unexpected_token!(token),
1059        };
1060        log::debug!("eval_value - res: {:?}", res);
1061        Ok(res)
1062    }
1063
1064    fn eval_number_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1065        check_rule!(token, Rule::number_literal);
1066        let mut negate = false;
1067        let mut pairs = token.into_inner();
1068        let mut token = pairs.next().unwrap();
1069
1070        //first handle prefix sign: + or -
1071        if token.as_rule() == Rule::minus {
1072            negate = true;
1073            token = pairs.next().unwrap();
1074        } else if token.as_rule() == Rule::plus {
1075            token = pairs.next().unwrap();
1076        }
1077
1078        let mut val = self.eval_number(token)?;
1079
1080        if negate {
1081            val.neg()?;
1082        }
1083
1084        if let Some(unit) = pairs.next() {
1085            let unit = unit.as_str().to_ascii_lowercase();
1086            let unit_int = match unit.as_str() {
1087                "k" => 1024,
1088                "m" => 1024 * 1024,
1089                "g" => 1024 * 1024 * 1024,
1090                "t" => 1024 * 1024 * 1024 * 1024,
1091                "p" => 1024 * 1024 * 1024 * 1024 * 1024,
1092                _ => 1,
1093            };
1094            val.mul(Val::Int(unit_int))?;
1095        }
1096        Ok(val)
1097    }
1098
1099    fn eval_number(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1100        check_rule!(token, Rule::number);
1101        let mut pairs = token.into_inner();
1102        let token = pairs.next().unwrap();
1103        let v = match token.as_rule() {
1104            Rule::decimal_integer => {
1105                let int_val = token.into_inner().next().unwrap();
1106                Val::Int(int_val.as_str().parse::<i64>().unwrap())
1107            }
1108            Rule::hex_integer => {
1109                let int_val = token.into_inner().next().unwrap();
1110                Val::Int(i64::from_str_radix(int_val.as_str(), 16).unwrap())
1111            }
1112            Rule::float => {
1113                let float_str = token.as_str().trim();
1114                Val::Float(float_str.parse::<f64>()?)
1115                //todo: handle all border cases
1116            }
1117            _ => unexpected_token!(token),
1118        };
1119        Ok(v)
1120    }
1121
1122    fn eval_unary_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1123        check_rule!(token, Rule::unary_exp);
1124        let token = token.into_inner().next().unwrap();
1125        match token.as_rule() {
1126            Rule::expression_with_unary_operator => self.eval_expression_with_unary_operator(token),
1127            Rule::primary_expression => self.eval_primary_expression(token),
1128            _ => unexpected_token!(token),
1129        }
1130    }
1131
1132    fn eval_array_literal_exp_special_case(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1133        check_rule!(token, Rule::array_literal_exp_special_case);
1134        let mut pairs = token.into_inner();
1135        let token = pairs.next().unwrap();
1136
1137        let val = self.eval_array_literal_exp(token)?;
1138        Ok(Val::Array(vec![val]))
1139    }
1140
1141    fn safe_parse_arg(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1142        Ok(if self.skip_error > 0 {
1143            match self.eval_unary_exp(token.clone()) {
1144                Ok(val) => val,
1145                Err(err) => {
1146                    self.errors.push(err);
1147                    Val::ScriptText(token.as_str().to_string())
1148                }
1149            }
1150        } else {
1151            self.eval_unary_exp(token.clone())?
1152        })
1153    }
1154
1155    fn eval_array_literal_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1156        check_rule!(token, Rule::array_literal_exp);
1157        let mut arr = Vec::new();
1158        let mut pairs = token.into_inner();
1159        let token = pairs.next().unwrap();
1160
1161        //if array literal starts with ',' we must eval single element as array too
1162        if let Rule::array_literal_exp_special_case = token.as_rule() {
1163            return self.eval_array_literal_exp_special_case(token);
1164        }
1165
1166        arr.push(self.safe_parse_arg(token)?);
1167        for token in pairs {
1168            arr.push(self.safe_parse_arg(token)?);
1169        }
1170
1171        Ok(if arr.len() == 1 {
1172            arr[0].clone()
1173        } else {
1174            Val::Array(arr)
1175        })
1176    }
1177
1178    fn eval_range_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1179        fn range(mut left: i64, right: i64) -> Vec<Val> {
1180            let mut v = Vec::new();
1181            if left <= right {
1182                loop {
1183                    v.push(left);
1184                    if left == right {
1185                        break;
1186                    }
1187                    left += 1;
1188                }
1189            } else {
1190                loop {
1191                    v.push(left);
1192                    if left == right {
1193                        break;
1194                    }
1195                    left -= 1;
1196                }
1197            }
1198            v.into_iter().map(Val::Int).collect()
1199        }
1200        check_rule!(token, Rule::range_exp);
1201        let mut pairs = token.into_inner();
1202        let token = pairs.next().unwrap();
1203        let res = match token.as_rule() {
1204            Rule::decimal_integer => {
1205                let int_val = token.into_inner().next().unwrap();
1206                let left = int_val.as_str().parse::<i64>().unwrap();
1207                let token = pairs.next().unwrap();
1208                let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1209                Val::Array(range(left, right))
1210            }
1211            Rule::array_literal_exp => {
1212                let res = self.eval_array_literal_exp(token)?;
1213                if let Some(token) = pairs.next() {
1214                    let left = res.cast_to_int()?;
1215                    let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1216                    Val::Array(range(left, right))
1217                } else {
1218                    res
1219                }
1220            }
1221            _ => unexpected_token!(token),
1222        };
1223
1224        Ok(res)
1225    }
1226
1227    fn eval_format_impl(&mut self, format: Val, mut pairs: Pairs<'a>) -> ParserResult<Val> {
1228        fn format_with_vec(fmt: &str, args: Vec<Val>) -> ParserResult<String> {
1229            fn strange_special_case(fmt: &str, n: i64) -> String {
1230                fn split_digits(n: i64) -> Vec<u8> {
1231                    n.abs() // ignore sign for digit splitting
1232                        .to_string()
1233                        .chars()
1234                        .filter_map(|c| c.to_digit(10).map(|opt| opt as u8))
1235                        .collect()
1236                }
1237
1238                //"{0:31sdfg,0100a0b00}" -f 578 evals to 310100a5b78
1239                let mut digits = split_digits(n);
1240                digits.reverse();
1241                let mut fmt_vec = fmt.as_bytes().to_vec();
1242                fmt_vec.reverse();
1243
1244                let mut i = 0;
1245                for digit in digits {
1246                    while i < fmt_vec.len() {
1247                        if fmt_vec[i] != b'0' {
1248                            i += 1
1249                        } else {
1250                            fmt_vec[i] = digit + b'0';
1251                            break;
1252                        }
1253                    }
1254                }
1255                fmt_vec.reverse();
1256                String::from_utf8(fmt_vec).unwrap_or_default()
1257            }
1258
1259            let mut output = String::new();
1260            let mut i = 0;
1261
1262            while i < fmt.len() {
1263                if fmt[i..].starts_with('{') {
1264                    if let Some(end) = fmt[i..].find('}') {
1265                        let token = &fmt[i + 1..i + end];
1266                        let formatted = if token.contains(':') {
1267                            let mut parts = token.split(':');
1268                            let index: usize = if let Some(p) = parts.next() {
1269                                p.parse().unwrap_or(0)
1270                            } else {
1271                                0
1272                            };
1273
1274                            let spec = parts.next();
1275                            match args.get(index) {
1276                                Some(val) => match spec {
1277                                    Some(s) if s.starts_with('N') => {
1278                                        let precision = s[1..].parse::<usize>().unwrap_or(2);
1279                                        if let Ok(f) = val.cast_to_float() {
1280                                            format!("{:.1$}", f, precision)
1281                                        } else {
1282                                            val.cast_to_string().to_string()
1283                                        }
1284                                    }
1285                                    Some(s) => strange_special_case(s, val.cast_to_int()?),
1286                                    None => val.cast_to_string().to_string(),
1287                                },
1288                                None => format!("{{{}}}", token), /* leave as-is if index out of
1289                                                                   * bounds */
1290                            }
1291                        } else if token.contains(',') {
1292                            let mut parts = token.split(',');
1293                            let index: usize = parts.next().unwrap().parse().unwrap_or(0);
1294                            let spec = parts.next();
1295                            match args.get(index) {
1296                                Some(val) => match spec {
1297                                    Some(s) => {
1298                                        let spaces = s.parse::<usize>().unwrap_or(0);
1299                                        let spaces_str = " ".repeat(spaces);
1300                                        format!("{spaces_str}{}", val.cast_to_string())
1301                                    }
1302                                    _ => val.cast_to_string().to_string(),
1303                                },
1304                                None => format!("{{{}}}", token), /* leave as-is if index out of
1305                                                                   * bounds */
1306                            }
1307                        } else {
1308                            let index: usize =
1309                                Val::String(token.to_string().into()).cast_to_int()? as usize;
1310                            match args.get(index) {
1311                                Some(val) => val.cast_to_string().to_string(),
1312                                None => format!("{{{}}}", token), /* leave as-is if index out of
1313                                                                   * bounds */
1314                            }
1315                        };
1316
1317                        output.push_str(&formatted);
1318                        i += end + 1;
1319                    } else {
1320                        output.push('{');
1321                        i += 1;
1322                    }
1323                } else {
1324                    output.push(fmt[i..].chars().next().unwrap());
1325                    i += 1;
1326                }
1327            }
1328
1329            Ok(output)
1330        }
1331
1332        Ok(if let Some(token) = pairs.next() {
1333            let first_fmt = format.cast_to_string();
1334
1335            let second_fmt = self.eval_range_exp(token)?;
1336            let res = self.eval_format_impl(second_fmt, pairs)?;
1337            Val::String(format_with_vec(first_fmt.as_str(), res.cast_to_array())?.into())
1338        } else {
1339            format
1340        })
1341    }
1342
1343    fn eval_format_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1344        check_rule!(token, Rule::format_exp);
1345        let mut pairs = token.into_inner();
1346        let format = self.eval_range_exp(pairs.next().unwrap())?;
1347        self.eval_format_impl(format, pairs)
1348    }
1349
1350    fn eval_mult(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1351        check_rule!(token, Rule::multiplicative_exp);
1352        let mut pairs = token.into_inner();
1353        let mut res = self.eval_format_exp(pairs.next().unwrap())?;
1354        while let Some(op) = pairs.next() {
1355            let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1356                log::error!("No arithmetic function for operator: {}", op.as_str());
1357                return Err(ParserError::NotImplemented(format!(
1358                    "No arithmetic function for operator: {}",
1359                    op.as_str()
1360                )));
1361            };
1362
1363            let postfix = pairs.next().unwrap();
1364            let right_op = self.eval_format_exp(postfix)?;
1365            res = fun(res, right_op)?;
1366        }
1367
1368        Ok(res)
1369    }
1370
1371    fn eval_additive(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1372        check_rule!(token, Rule::additive_exp);
1373
1374        let mut pairs = token.into_inner();
1375        let mut res = self.eval_mult(pairs.next().unwrap())?;
1376        while let Some(op) = pairs.next() {
1377            //check_rule!(op, Rule::additive_op); plus or minus
1378            let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1379                log::error!("No arithmetic function for operator: {}", op.as_str());
1380                return Err(ParserError::NotImplemented(format!(
1381                    "No arithmetic function for operator: {}",
1382                    op.as_str()
1383                )));
1384            };
1385
1386            let mult = pairs.next().unwrap();
1387            let right_op = self.eval_mult(mult)?;
1388            res = fun(res, right_op)?;
1389        }
1390
1391        Ok(res)
1392    }
1393
1394    fn eval_split_special_case(
1395        &mut self,
1396        script_block: ScriptBlock,
1397        input: Val,
1398    ) -> ParserResult<Vec<String>> {
1399        let mut res_vec = vec![];
1400        let mut parts = String::new();
1401        let input_str = input.cast_to_string();
1402        let characters = input_str.chars();
1403
1404        // filtered_elements.join("")
1405        for ch in characters {
1406            let b = match script_block.run(vec![], self, Some(Val::String(ch.to_string().into()))) {
1407                Err(er) => {
1408                    self.errors.push(er);
1409                    false
1410                }
1411                Ok(res) => res.val.cast_to_bool(),
1412            };
1413
1414            if b {
1415                res_vec.push(parts);
1416                parts = String::new();
1417            } else {
1418                parts.push(ch);
1419            }
1420        }
1421        self.variables.reset_ps_item();
1422        Ok(res_vec)
1423    }
1424
1425    fn eval_comparison_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1426        check_rule!(token, Rule::comparison_exp);
1427        let mut pairs = token.into_inner();
1428        let token = pairs.next().unwrap();
1429
1430        // we need to handle strange case. -split and -join can be invoke without
1431        // previous expression, eg. "-join 'some'"
1432        let mut res = if token.as_rule() == Rule::additive_exp {
1433            self.eval_additive(token)?
1434        } else {
1435            Val::Null
1436        };
1437
1438        while let Some(op) = pairs.next() {
1439            let Some(fun) = StringPred::get(op.as_str()) else {
1440                log::error!("No string predicate for operator: {}", op.as_str());
1441                return Err(ParserError::NotImplemented(format!(
1442                    "No string predicate for operator: {}",
1443                    op.as_str()
1444                )));
1445            };
1446
1447            let token = pairs.next().unwrap();
1448            let right_op = match token.as_rule() {
1449                Rule::script_block_expression => {
1450                    let script_block = self.parse_script_block_expression(token)?;
1451
1452                    return Ok(Val::Array(
1453                        self.eval_split_special_case(script_block, res)?
1454                            .into_iter()
1455                            .map(|s| Val::String(s.into()))
1456                            .collect::<Vec<_>>(),
1457                    ));
1458                }
1459                Rule::additive_exp => self.eval_additive(token)?,
1460                //Rule::type_literal => self.eval_type_literal(token)?,
1461                _ => unexpected_token!(token),
1462            };
1463            log::trace!("res: {:?}, right_op: {:?}", &res, &right_op);
1464            res = fun(res, right_op)?;
1465            log::trace!("res: {:?}", &res);
1466        }
1467
1468        Ok(res)
1469    }
1470
1471    fn parse_script_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1472        check_rule!(token, Rule::script_param_block);
1473        let mut pairs = token.into_inner();
1474        let Some(param_block_token) = pairs.next() else {
1475            return Ok(vec![]);
1476        };
1477        self.parse_param_block(param_block_token)
1478    }
1479
1480    fn parse_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1481        check_rule!(token, Rule::param_block);
1482        let mut pairs = token.into_inner();
1483
1484        let Some(token) = pairs.next() else {
1485            return Ok(vec![]);
1486        };
1487
1488        let option_param_token = match token.as_rule() {
1489            Rule::attribute_list => {
1490                //self.parse_attribute_list(token)?;
1491                pairs.next()
1492            }
1493            Rule::parameter_list => Some(token),
1494            _ => unexpected_token!(token),
1495        };
1496
1497        let Some(param_token) = option_param_token else {
1498            return Ok(vec![]);
1499        };
1500        self.parse_parameter_list(param_token)
1501    }
1502
1503    fn parse_parameter_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1504        check_rule!(token, Rule::parameter_list);
1505        let mut params = vec![];
1506        let param_list_pairs = token.into_inner();
1507        for script_parameter_token in param_list_pairs {
1508            check_rule!(script_parameter_token, Rule::script_parameter);
1509            params.push(self.parse_script_parameter(script_parameter_token)?);
1510        }
1511        Ok(params)
1512    }
1513
1514    fn parse_attribute_list(&mut self, token: Pair<'a>) -> ParserResult<Option<ValType>> {
1515        check_rule!(token, Rule::attribute_list);
1516        let attribute_list_pairs = token.into_inner();
1517        for attribute_token in attribute_list_pairs {
1518            check_rule!(attribute_token, Rule::attribute);
1519            let attribute_type_token = attribute_token.into_inner().next().unwrap();
1520            match attribute_type_token.as_rule() {
1521                Rule::attribute_info => {
1522                    //skip for now
1523                    continue;
1524                }
1525                Rule::type_literal => {
1526                    let runtime_type = self.eval_type_literal(attribute_type_token)?;
1527                    return Ok(Some(runtime_type.type_definition()?));
1528                }
1529                _ => unexpected_token!(attribute_type_token),
1530            }
1531        }
1532        Ok(None)
1533    }
1534    fn parse_script_parameter(&mut self, token: Pair<'a>) -> ParserResult<Param> {
1535        check_rule!(token, Rule::script_parameter);
1536        let mut pairs = token.into_inner();
1537        let mut token = pairs.next().unwrap();
1538
1539        let type_literal = if token.as_rule() == Rule::attribute_list {
1540            let type_literal = self.parse_attribute_list(token)?;
1541            token = pairs.next().unwrap();
1542            type_literal
1543        } else {
1544            None
1545        };
1546
1547        check_rule!(token, Rule::variable);
1548        let var_name = Self::parse_variable(token)?;
1549
1550        let default_value = if let Some(default_value_token) = pairs.next() {
1551            check_rule!(default_value_token, Rule::script_parameter_default);
1552            let default_value_expr = default_value_token.into_inner().next().unwrap();
1553            let default_value = self.eval_value(default_value_expr)?;
1554            Some(default_value)
1555        } else {
1556            None
1557        };
1558        Ok(Param::new(type_literal, var_name.name, default_value))
1559    }
1560
1561    fn eval_bitwise_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1562        check_rule!(token, Rule::bitwise_exp);
1563
1564        let mut pairs = token.into_inner();
1565        let mut res = self.eval_as_exp(pairs.next().unwrap())?;
1566        while let Some(op) = pairs.next() {
1567            check_rule!(op, Rule::bitwise_operator);
1568            let Some(fun) = BitwisePred::get(op.as_str()) else {
1569                log::error!("No bitwise predicate for operator: {}", op.as_str());
1570                return Err(ParserError::NotImplemented(format!(
1571                    "No bitwise predicate for operator: {}",
1572                    op.as_str()
1573                )));
1574            };
1575
1576            let mult = pairs.next().unwrap();
1577            let right_op = self.eval_as_exp(mult)?;
1578            res = fun(res, right_op)?;
1579        }
1580
1581        Ok(res)
1582    }
1583
1584    fn eval_as_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1585        check_rule!(token, Rule::as_expression);
1586
1587        let mut pairs = token.into_inner();
1588        let mut res = self.eval_comparison_exp(pairs.next().unwrap())?;
1589        for token in pairs {
1590            let runtime_object = match token.as_rule() {
1591                Rule::type_literal => self.eval_type_literal(token)?,
1592                Rule::comparison_exp => self.eval_comparison_exp(token)?,
1593                _ => unexpected_token!(token),
1594            };
1595
1596            res = res.cast(&runtime_object).unwrap_or_default();
1597        }
1598
1599        Ok(res)
1600    }
1601
1602    fn parse_cmdlet_command_name(&mut self, token: Pair<'a>) -> ParserResult<Command> {
1603        check_rule!(token, Rule::cmdlet_command);
1604
1605        let mut pairs = token.into_inner();
1606        let token = pairs.next().unwrap();
1607        let command_name = match token.as_rule() {
1608            Rule::command_name => token.as_str(),
1609            Rule::where_command_name => "where-object",
1610            Rule::foreach_command_name => "foreach-object",
1611            Rule::powershell_command_name => "powershell",
1612            _ => unexpected_token!(token),
1613        };
1614
1615        let mut command = Command::cmdlet(command_name);
1616        if Rule::command_name == token.as_rule() {
1617            command.set_session_scope(SessionScope::New);
1618        }
1619        Ok(command)
1620    }
1621
1622    fn parse_command_args(&mut self, pairs: Pairs<'a>) -> ParserResult<Vec<CommandElem>> {
1623        let mut args = vec![];
1624        for command_element_token in pairs {
1625            let token_string = command_element_token.as_str().to_string();
1626            match command_element_token.as_rule() {
1627                Rule::command_argument => {
1628                    let arg_token = command_element_token.into_inner().next().unwrap();
1629                    let arg = match arg_token.as_rule() {
1630                        Rule::array_literal_exp => self.eval_array_literal_exp(arg_token)?,
1631                        Rule::script_block_expression => {
1632                            Val::ScriptBlock(self.parse_script_block_expression(arg_token)?)
1633                        }
1634                        Rule::parenthesized_expression => {
1635                            let token = arg_token.into_inner().next().unwrap();
1636                            self.eval_pipeline(token)?
1637                        }
1638                        _ => Val::ScriptText(arg_token.as_str().to_string()),
1639                    };
1640                    args.push(CommandElem::Argument(arg));
1641                }
1642                Rule::command_parameter => {
1643                    args.push(CommandElem::Parameter(token_string.to_ascii_lowercase()))
1644                }
1645                Rule::argument_list => args.push(CommandElem::ArgList(token_string)),
1646                Rule::splatten_arg => {
1647                    let var_name = Self::parse_scoped_variable(command_element_token)?;
1648                    let var = self.variables.get(&var_name).unwrap_or_default();
1649                    if let Val::HashTable(h) = var {
1650                        for (k, v) in h {
1651                            args.push(CommandElem::Parameter(format!("-{}", k)));
1652                            args.push(CommandElem::Argument(v));
1653                        }
1654                    }
1655                }
1656                Rule::redirection => { //todo: implement redirection
1657                }
1658                Rule::stop_parsing => { //todo: stop parsing
1659                }
1660                _ => unexpected_token!(command_element_token),
1661            }
1662        }
1663        Ok(args)
1664    }
1665
1666    fn eval_command(&mut self, token: Pair<'a>, piped_arg: Option<Val>) -> ParserResult<Val> {
1667        check_rule!(token, Rule::command);
1668        let mut pairs = token.into_inner();
1669
1670        let command_token = pairs.next().unwrap();
1671        let mut command = match command_token.as_rule() {
1672            Rule::cmdlet_command => self.parse_cmdlet_command_name(command_token)?,
1673            Rule::invocation_command => self.parse_invocation_command(command_token)?,
1674            _ => unexpected_token!(command_token),
1675        };
1676
1677        let mut args = self.parse_command_args(pairs)?;
1678        if let Some(arg) = piped_arg {
1679            args.insert(0, CommandElem::Argument(arg));
1680        }
1681
1682        command.with_args(args);
1683        match command.execute(self) {
1684            Ok(CommandOutput {
1685                val,
1686                deobfuscated: _deobfuscated,
1687            }) => Ok(val),
1688            Err(e) => {
1689                self.errors.push(e);
1690                Ok(Val::ScriptText(command.to_string()))
1691            }
1692        }
1693
1694        // if let Some(msg) = deobfuscated {
1695        //     self.add_deobfuscated_statement(msg);
1696        // }
1697    }
1698
1699    fn add_deobfuscated_statement(&mut self, msg: String) {
1700        if let Some(last) = self.results.last_mut() {
1701            last.deobfuscated.push(msg);
1702        }
1703    }
1704
1705    fn add_output_statement(&mut self, msg: StreamMessage) {
1706        if let Some(last) = self.results.last_mut() {
1707            last.output.push(msg);
1708        }
1709    }
1710
1711    fn parse_invocation_command(&mut self, token: Pair<'a>) -> ParserResult<Command> {
1712        check_rule!(token, Rule::invocation_command);
1713
1714        let invocation_command_token = token.into_inner().next().unwrap();
1715
1716        let mut session_scope = match invocation_command_token.as_rule() {
1717            Rule::current_scope_invocation_command => SessionScope::Current,
1718            Rule::new_scope_invocation_command => SessionScope::New,
1719            _ => unexpected_token!(invocation_command_token),
1720        };
1721
1722        let token_inner = invocation_command_token.into_inner().next().unwrap();
1723
1724        let mut command = match token_inner.as_rule() {
1725            Rule::cmdlet_command => {
1726                session_scope = SessionScope::New;
1727                self.parse_cmdlet_command_name(token_inner)?
1728            }
1729            Rule::primary_expression => {
1730                let primary = self.eval_primary_expression(token_inner)?;
1731                if let Val::ScriptBlock(script_block) = primary {
1732                    Command::script_block(script_block)
1733                } else {
1734                    Command::cmdlet(&primary.cast_to_script())
1735                }
1736            }
1737            Rule::path_command_name => Command::path(token_inner.as_str()),
1738            _ => unexpected_token!(token_inner),
1739        };
1740
1741        command.set_session_scope(session_scope);
1742        Ok(command)
1743    }
1744
1745    fn eval_redirected_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1746        check_rule!(token, Rule::redirected_expression);
1747
1748        let expression_token = token.into_inner().next().unwrap();
1749        //todo: handle redirections
1750
1751        self.eval_expression(expression_token)
1752    }
1753
1754    fn eval_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1755        check_rule!(token, Rule::expression);
1756        let token_string = token.as_str().trim().to_string();
1757
1758        let mut pairs = token.into_inner();
1759        let mut res = self.eval_bitwise_exp(pairs.next().unwrap())?;
1760        while let Some(op) = pairs.next() {
1761            check_rule!(op, Rule::logical_operator);
1762            let Some(fun) = LogicalPred::get(op.as_str()) else {
1763                log::error!("No logical predicate for operator: {}", op.as_str());
1764                return Err(ParserError::NotImplemented(format!(
1765                    "No logical predicate for operator: {}",
1766                    op.as_str()
1767                )));
1768            };
1769
1770            let mult = pairs.next().unwrap();
1771            let right_op = self.eval_bitwise_exp(mult)?;
1772            res = Val::Bool(fun(res, right_op));
1773        }
1774        self.tokens
1775            .push(Token::Expression(token_string, res.clone().into()));
1776
1777        if let Val::String(value::PsString(s)) = &res {
1778            self.tokens.push(Token::String(s.clone()));
1779        }
1780
1781        Ok(res)
1782    }
1783
1784    fn eval_pipeline_tail(&mut self, token: Pair<'a>, mut piped_arg: Val) -> ParserResult<Val> {
1785        check_rule!(token, Rule::pipeline_tail);
1786        let pairs = token.into_inner();
1787
1788        for token in pairs {
1789            //self.variables.set_ps_item(arg);
1790            piped_arg = self.eval_command(token, Some(piped_arg))?;
1791        }
1792
1793        Ok(piped_arg)
1794    }
1795
1796    fn eval_pipeline_with_tail(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1797        check_rule!(token, Rule::pipeline_with_tail);
1798        let mut pairs = token.into_inner();
1799        let token = pairs.next().unwrap();
1800
1801        let result: Val = match token.as_rule() {
1802            Rule::redirected_expression => self.eval_redirected_expression(token)?,
1803            Rule::command => self.eval_command(token, None)?,
1804            _ => unexpected_token!(token),
1805        };
1806
1807        if let Some(token) = pairs.next() {
1808            match token.as_rule() {
1809                Rule::pipeline_tail => Ok(self.eval_pipeline_tail(token, result)?),
1810                _ => unexpected_token!(token),
1811            }
1812        } else {
1813            Ok(result)
1814        }
1815    }
1816
1817    fn eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1818        check_rule!(token, Rule::pipeline);
1819        let mut pairs = token.into_inner();
1820        let token = pairs.next().unwrap();
1821
1822        match token.as_rule() {
1823            Rule::assignment_exp => self.eval_assigment_exp(token),
1824            Rule::pipeline_with_tail => self.eval_pipeline_with_tail(token),
1825            _ => unexpected_token!(token),
1826        }
1827    }
1828
1829    fn safe_eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1830        let res = self.eval_pipeline(token.clone());
1831
1832        let v = match res {
1833            Ok(val) => val,
1834            Err(err) => {
1835                self.errors.push(err);
1836                Val::ScriptText(token.as_str().to_string())
1837            }
1838        };
1839
1840        Ok(v)
1841    }
1842
1843    fn eval_cast_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1844        check_rule!(token, Rule::cast_expression);
1845
1846        let mut pairs = token.into_inner();
1847        let type_token = pairs.next().unwrap();
1848        check_rule!(type_token, Rule::type_literal);
1849        let val_type = self.eval_type_literal(type_token)?;
1850        let token = pairs.next().unwrap();
1851        let res = match token.as_rule() {
1852            Rule::parenthesized_expression => {
1853                let token = token.into_inner().next().unwrap();
1854                self.safe_eval_pipeline(token)?
1855            }
1856            Rule::unary_exp => self.eval_unary_exp(token)?,
1857            _ => unexpected_token!(token),
1858        };
1859        Ok(res.cast(&val_type)?)
1860    }
1861
1862    fn eval_assigment_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1863        check_rule!(token, Rule::assignment_exp);
1864
1865        let mut specified_type = None;
1866
1867        let mut pairs = token.into_inner();
1868        let mut token = pairs.next().unwrap();
1869        if token.as_rule() == Rule::type_literal {
1870            specified_type = Some(self.eval_type_literal(token)?);
1871            token = pairs.next().unwrap();
1872        }
1873        let (var_name, access) = self.parse_assignable_variable(token)?;
1874        let mut variable = self.variables.get(&var_name).unwrap_or_default();
1875        let mut accessed_elem = &mut variable;
1876
1877        // sometimes we have variable access like $a[0].Property, and we need access
1878        // property by reference
1879        if let Some(access) = access {
1880            for token in access {
1881                accessed_elem = self.variable_access(token, accessed_elem)?;
1882            }
1883        }
1884        let assignement_op = pairs.next().unwrap();
1885
1886        //get operand
1887        let op = assignement_op.into_inner().next().unwrap();
1888        let pred = ArithmeticPred::get(op.as_str());
1889
1890        let right_token = pairs.next().unwrap();
1891        let right_op = self.eval_statement(right_token.clone())?;
1892
1893        let Some(pred) = pred else {
1894            log::error!("No arithmetic function for operator: {}", op.as_str());
1895            return Err(ParserError::NotImplemented(format!(
1896                "No arithmetic function for operator: {}",
1897                op.as_str()
1898            )));
1899        };
1900        *accessed_elem = pred(accessed_elem.clone(), right_op)?;
1901        if let Some(runtime_type) = specified_type {
1902            *accessed_elem = accessed_elem.cast(&runtime_type)?;
1903        }
1904        self.variables.set(&var_name, variable.clone())?;
1905
1906        //we want save each assignment statement
1907        self.add_deobfuscated_statement(format!("{} = {}", var_name, variable.cast_to_script()));
1908
1909        Ok(Val::NonDisplayed(Box::new(variable)))
1910    }
1911
1912    fn push_scope_session(&mut self) {
1913        self.variables.push_scope_session();
1914    }
1915
1916    fn pop_scope_session(&mut self) {
1917        self.variables.pop_scope_session();
1918    }
1919}
1920
1921#[cfg(test)]
1922mod tests {
1923    use pest::Parser;
1924
1925    use super::*;
1926
1927    #[test]
1928    fn comment_and_semicolon() {
1929        let input = r#"
1930# This is a single line comment
1931$a = 1; $b = 2; Write-Output $a
1932
1933Write-Output "Hello"  # Another comment
1934
1935<#
1936    This is a
1937    multi-line block comment
1938#>
1939"#;
1940
1941        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1942    }
1943
1944    #[test]
1945    fn while_loop() {
1946        let input = r#"
1947while ($true) {
1948    if ($someCondition) {
1949        break
1950    }
1951    # other code
1952}
1953"#;
1954
1955        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1956    }
1957
1958    #[test]
1959    fn foreach_loop() {
1960        let input = r#"
1961foreach ($n in $numbers) {
1962    Write-Output $n
1963}
1964"#;
1965
1966        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1967    }
1968
1969    #[test]
1970    fn for_loop() {
1971        let input = r#"
1972# Comma separated assignment expressions enclosed in parentheses.
1973for (($i = 0), ($j = 0); $i -lt 10; $i++)
1974{
1975    "`$i:$i"
1976    "`$j:$j"
1977}
1978"#;
1979
1980        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1981    }
1982
1983    #[test]
1984    fn switch() {
1985        let input = r#"
1986switch ($var) {
1987    "a" { Write-Output "A" }
1988    1 { Write-Output "One" }
1989    default { Write-Output "Other" }
1990}
1991"#;
1992
1993        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1994    }
1995
1996    #[test]
1997    fn functions() {
1998        let input = r#"
1999function Get-Square {
2000    param($x)
2001    return $x * $x
2002}
2003
2004function Say-Hello {
2005    Write-Output "Hello"
2006}
2007"#;
2008
2009        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2010    }
2011
2012    #[test]
2013    fn if_expression() {
2014        let input = r#"
2015$x="hello"
2016        Write-Host $x
2017        $y = 42
2018        Start-Process "notepad.exe"
2019
2020        $x = 42
2021if ($x -eq 1) {
2022    Write-Output "One"
2023} elseif ($x -eq 2) {
2024    Write-Output "Two"
2025} else {
2026    Write-Output "Other"
2027}
2028"#;
2029
2030        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2031    }
2032
2033    #[test]
2034    fn command() {
2035        let input = r#"
2036Get-Process | Where-Object { $_.CPU -gt 100 }
2037"#;
2038
2039        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2040    }
2041
2042    #[test]
2043    fn range() {
2044        let input = r#"
2045$numbers = 1..5
2046"#;
2047
2048        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2049    }
2050
2051    #[test]
2052    fn literals() {
2053        let input = r#"
2054$hex = 0xFF
2055
2056$name = "Alice"
2057$msg = "Hello, $name. Today is $day."
2058$escaped = "She said: `"Hi`""
2059$literal = 'Hello, $name'
2060"#;
2061
2062        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2063    }
2064
2065    #[test]
2066    fn floats() {
2067        let input = r#"
2068    $pi = 3.1415
2069$half = .5
2070"#;
2071
2072        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2073    }
2074
2075    #[test]
2076    fn arrays() {
2077        let input = r#"
2078$a = 1, 2, 3
2079$b = @("one", "two", "three")
2080$c = @(1, 2, @(3, 4))
2081"#;
2082
2083        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2084    }
2085
2086    #[test]
2087    fn static_method_call() {
2088        let input = r#"
2089[Threading.Thread]::Sleep(399)
2090"#;
2091
2092        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2093    }
2094
2095    #[test]
2096    fn neg_pipeline() {
2097        let input = r#"
2098-not $input | Where-Object { $_ -gt 5 }
2099"#;
2100
2101        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2102    }
2103
2104    #[test]
2105    fn amsi_fail() {
2106        let input = r#"
2107#Matt Graebers second Reflection method 
2108$VMRviwsbtehQfPtxbt=$null;
2109$ilryNQSTt="System.$([cHAR]([ByTE]0x4d)+[ChAR]([byte]0x61)+[chAr](110)+[cHar]([byTE]0x61)+[cHaR](103)+[cHar](101*64/64)+[chaR]([byTE]0x6d)+[cHAr](101)+[CHAr]([byTE]0x6e)+[Char](116*103/103)).$([Char]([ByTe]0x41)+[Char](117+70-70)+[CHAr]([ByTE]0x74)+[CHar]([bYte]0x6f)+[CHar]([bytE]0x6d)+[ChaR]([ByTe]0x61)+[CHar]([bYte]0x74)+[CHAR]([byte]0x69)+[Char](111*26/26)+[chAr]([BYTe]0x6e)).$(('Âmsí'+'Ùtìl'+'s').NORmalizE([ChAR](44+26)+[chAR](111*9/9)+[cHar](82+32)+[ChaR](109*34/34)+[cHaR](68+24-24)) -replace [ChAr](92)+[CHaR]([BYTe]0x70)+[Char]([BytE]0x7b)+[CHaR]([BYTe]0x4d)+[chAR](110)+[ChAr](15+110))"
2110
2111"#;
2112
2113        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2114    }
2115}