ps_parser/
parser.rs

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