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