pub fn debug_command(&mut self, command: &str, vm: &PolarVirtualMachine) -> Option<Goal> {
        fn show<T>(stack: &[T]) -> Goal
        where
            T: std::fmt::Display,
        {
            Goal::Debug {
                message: stack
                    .iter()
                    .map(ToString::to_string)
                    .collect::<Vec<_>>()
                    .join("\n"),
            }
        }
        let parts: Vec<&str> = command.split_whitespace().collect();
        let default_command = match self.last.take() {
            Some(s) => s,
            _ => "help".to_owned(),
        };
        let command = *parts.get(0).unwrap_or(&&default_command[..]);
        self.last = Some(String::from(command));
        match command {
            "c" | "continue" | "q" | "quit" => self.step = None,

            "n" | "next" | "over" => {
                self.step = Some(Step::Over{ level: vm.trace_stack.len() })
            }
            "s" | "step" | "into" => {
                self.step = Some(Step::Into)
            }
            "o" | "out" => {
                self.step = Some(Step::Out{ level: vm.trace_stack.len() })
            }
            "g" | "goal" => {
                self.step = Some(Step::Goal)
            }
            "e" | "error" => {
                self.step = Some(Step::Error)
            }
            "r" | "rule" => {
                self.step = Some(Step::Rule)
            }
            "l" | "line" => {
                let lines = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0);
                return Some(Goal::Debug {
                    message: vm.queries.last().map_or_else(
                        || "".to_string(),
                        |query| self.query_source(query, lines),
                    ),
                });
            }
            "query" => {
                let mut level = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0);
                let mut trace_stack = vm.trace_stack.clone();

                // Walk up the trace stack to get the query at the requested level.
                let mut term = vm.trace.last().and_then(|t| t.term());
                while level > 0 {
                    if let Some(trace) = trace_stack.pop().map(|ts| ts.as_ref().clone()) {
                        if let Some(t) = trace.last() {
                            if let Trace{node: Node::Term(t), ..} = &**t {
                                term = Some(t.clone());
                                level-=1;
                            }
                        }
                    } else {
                        return Some(Goal::Debug {
                            message: "Error: level is out of range".to_owned()
                        })
                    }
                }

                if let Some(query) = term {
                    return Some(Goal::Debug {
                        message: vm.query_summary(&query)});
                } else {
                    return Some(Goal::Debug {
                        message: "".to_owned()
                    })
                }
            }
            "stack" | "trace" => {
                return Some(Goal::Debug {
                    message: vm.stack_trace()
                })
            }
            "goals" => return Some(show(&vm.goals)),
            "bindings" => {
                return Some(show(vm.bindings_debug().as_slice()))
            }
            "var" => {
                if parts.len() > 1 {
                    let vars: Vec<Binding> = parts[1..]
                        .iter()
                        .map(|name| {
                            get_binding_for_var(name, vm)
                        })
                        .collect();
                    return Some(show(&vars));
                } else {
                    let mut vars = vm
                        .bindings(true)
                        .keys()
                        .map(|k| k.0.as_ref())
                        .collect::<Vec<_>>()
                        .join(", ");
                    if vars.is_empty() {
                        vars = "No variables in scope.".to_string();
                    }
                    return Some(Goal::Debug { message: vars });
                }
            }
            _ => {
                return Some(Goal::Debug {
                    message: "Debugger Commands
  h[elp]                  Print this help documentation.
  c[ontinue]              Continue evaluation.
  s[tep] | into           Step to the next query (will step into rules).
  n[ext] | over           Step to the next query at the same level of the query stack (will not step into rules).
  o[ut]                   Step out of the current query stack level to the next query in the level above.
  g[oal]                  Step to the next goal of the Polar VM.
  e[rror]                 Step to the next error.
  r[ule]                  Step to the next rule.
  l[ine] [<n>]            Print the current line and <n> lines of context.
  query [<i>]             Print the current query or the query at level <i> in the query stack.
  stack | trace           Print the current query stack.
  goals                   Print the current goal stack.
  bindings                Print all bindings
  var [<name> ...]        Print available variables. If one or more arguments
                          are provided, print the value of those variables.
  q[uit]                  Alias for 'continue'."
                        .to_string(),
                })
            }
        }
        None
    }
/// Process debugging commands from the user.
///
/// For informational commands (`"bindings"`, `"goals"`, `"line"`, `"queries"`, and `"var"`),
/// look up relevant data via the passed-in
/// [`PolarVirtualMachine`](../vm/struct.PolarVirtualMachine.html), format it, and return a
/// [`Goal::Debug`](../vm/enum.Goal.html) containing the formatted string that will be
/// displayed to the user.
///
/// For movement commands (`"continue"`, `"over"`, `"out"`, `"step"`), set the internal state
/// of the [`Debugger`](struct.Debugger.html) to the appropriate
/// [`Option<Step>`](struct.Debugger.html#structfield.step).
Process debugging commands from the user.


Process debugging commands from the user .
pub fn debug_command(&mut self, command: &str, vm: &PolarVirtualMachine) -> Option<Goal> {
        fn show<T>(stack: &[T]) -> Goal
        where
            T: std::fmt::Display,
        {
            Goal::Debug {
                message: stack
                    .iter()
                    .map(ToString::to_string)
                    .collect::<Vec<_>>()
                    .join("\n"),
            }
        }
        let parts: Vec<&str> = command.split_whitespace().collect();
        let default_command = match self.last.take() {
            Some(s) => s,
            _ => "help".to_owned(),
        };
        let command = *parts.get(0).unwrap_or(&&default_command[..]);
        self.last = Some(String::from(command));
        match command {
            "c" | "continue" | "q" | "quit" => self.step = None,
            "n" | "next" | "over" => {
                self.step = Some(Step::Over{ level: vm.trace_stack.len() })
            }
            "s" | "step" | "into" => {
                self.step = Some(Step::Into)
            }
            "o" | "out" => {
                self.step = Some(Step::Out{ level: vm.trace_stack.len() })
            }
            "g" | "goal" => {
                self.step = Some(Step::Goal)
            }
            "e" | "error" => {
                self.step = Some(Step::Error)
            }
            "r" | "rule" => {
                self.step = Some(Step::Rule)
            }
            "l" | "line" => {
                let lines = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0);
                return Some(Goal::Debug {
                    message: vm.queries.last().map_or_else(
                        || "".to_string(),
                        |query| self.query_source(query, lines),
                    ),
                });
            }
            "query" => {
                let mut level = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0);
                let mut trace_stack = vm.trace_stack.clone();
                // Walk up the trace stack to get the query at the requested level.
                let mut term = vm.trace.last().and_then(|t| t.term());
                while level > 0 {
                    if let Some(trace) = trace_stack.pop().map(|ts| ts.as_ref().clone()) {
                        if let Some(t) = trace.last() {
                            if let Trace{node: Node::Term(t), ..} = &**t {
                                term = Some(t.clone());
                                level-=1;
                            }
                        }
                    } else {
                        return Some(Goal::Debug {
                            message: "Error: level is out of range".to_owned()
                        })
                    }
                }
                if let Some(query) = term {
                    return Some(Goal::Debug {
                        message: vm.query_summary(&query)});
                } else {
                    return Some(Goal::Debug {
                        message: "".to_owned()
                    })
                }
            }
            "stack" | "trace" => {
                return Some(Goal::Debug {
                    message: vm.stack_trace()
                })
            }
            "goals" => return Some(show(&vm.goals)),
            "bindings" => {
                return Some(show(vm.bindings_debug().as_slice()))
            }
            "var" => {
                if parts.len() > 1 {
                    let vars: Vec<Binding> = parts[1..]
                        .iter()
                        .map(|name| {
                            get_binding_for_var(name, vm)
                        })
                        .collect();
                    return Some(show(&vars));
                } else {
                    let mut vars = vm
                        .bindings(true)
                        .keys()
                        .map(|k| k.0.as_ref())
                        .collect::<Vec<_>>()
                        .join(", ");
                    if vars.is_empty() {
                        vars = "No variables in scope.".to_string();
                    }
                    return Some(Goal::Debug { message: vars });
                }
            }
            _ => {
                return Some(Goal::Debug {
                    message: "Debugger Commands
  h[elp]                  Print this help documentation.
  c[ontinue]              Continue evaluation.
  s[tep] | into           Step to the next query (will step into rules).
  n[ext] | over           Step to the next query at the same level of the query stack (will not step into rules).
  o[ut]                   Step out of the current query stack level to the next query in the level above.
  g[oal]                  Step to the next goal of the Polar VM.
  e[rror]                 Step to the next error.
  r[ule]                  Step to the next rule.
  l[ine] [<n>]            Print the current line and <n> lines of context.
  query [<i>]             Print the current query or the query at level <i> in the query stack.
  stack | trace           Print the current query stack.
  goals                   Print the current goal stack.
  bindings                Print all bindings
  var [<name> ...]        Print available variables. If one or more arguments
                          are provided, print the value of those variables.
  q[uit]                  Alias for 'continue'."
                        .to_string(),
                })
            }
        }
        None
    }
pub fn debug_command ( & mut self , command : & str , vm : & PolarVirtualMachine ) -> Option < Goal > { fn show < T > ( stack : & [ T ] ) -> Goal where T : std :: fmt :: Display , { Goal :: Debug { message : stack . iter ( ) . map ( ToString :: to_string ) . collect :: < Vec < _ > > ( ) . join ( " \n " ) , } } let parts : Vec < & str > = command . split_whitespace ( ) . collect ( ) ; let default_command = match self . last . take ( ) { Some ( s ) => s , _ => " " . to_owned ( ) , } ; let command = * parts . get ( 0 ) . unwrap_or ( & & default_command [ .. ] ) ; self . last = Some ( String :: from ( command ) ) ; match command { " " | " " | " " | " " => self . step = None , " " | " " | " " => { self . step = Some ( Step :: Over { level : vm . trace_stack . len ( ) } ) } " " | " " | " " => { self . step = Some ( Step :: Into ) } " " | " " => { self . step = Some ( Step :: Out { level : vm . trace_stack . len ( ) } ) } " " | " " => { self . step = Some ( Step :: Goal ) } " " | " " => { self . step = Some ( Step :: Error ) } " " | " " => { self . step = Some ( Step :: Rule ) } " " | " " => { let lines = parts . get ( 1 ) . and_then ( | s | s . parse ( ) . ok ( ) ) . unwrap_or ( 0 ) ; return Some ( Goal :: Debug { message : vm . queries . last ( ) . map_or_else ( | | " " . to_string ( ) , | query | self . query_source ( query , lines ) , ) , } ) ; } " " => { let mut level = parts . get ( 1 ) . and_then ( | s | s . parse ( ) . ok ( ) ) . unwrap_or ( 0 ) ; let mut trace_stack = vm . trace_stack . clone ( ) ; // Walk up the trace stack to get the query at the requested level. let mut term = vm . trace . last ( ) . and_then ( | t | t . term ( ) ) ; while level > 0 { if let Some ( trace ) = trace_stack . pop ( ) . map ( | ts | ts . as_ref ( ) . clone ( ) ) { if let Some ( t ) = trace . last ( ) { if let Trace { node : Node :: Term ( t ) , .. } = & * * t { term = Some ( t . clone ( ) ) ; level -= 1 ; } } } else { return Some ( Goal :: Debug { message : " " . to_owned ( ) } ) } } if let Some ( query ) = term { return Some ( Goal :: Debug { message : vm . query_summary ( & query ) } ) ; } else { return Some ( Goal :: Debug { message : " " . to_owned ( ) } ) } } " " | " " => { return Some ( Goal :: Debug { message : vm . stack_trace ( ) } ) } " " => return Some ( show ( & vm . goals ) ) , " " => { return Some ( show ( vm . bindings_debug ( ) . as_slice ( ) ) ) } " " => { if parts . len ( ) > 1 { let vars : Vec < Binding > = parts [ 1 .. ] . iter ( ) . map ( | name | { get_binding_for_var ( name , vm ) } ) . collect ( ) ; return Some ( show ( & vars ) ) ; } else { let mut vars = vm . bindings ( true ) . keys ( ) . map ( | k | k . 0 . as_ref ( ) ) . collect :: < Vec < _ > > ( ) . join ( " " ) ; if vars . is_empty ( ) { vars = " " . to_string ( ) ; } return Some ( Goal :: Debug { message : vars } ) ; } } _ => { return Some ( Goal :: Debug { message : " " . to_string ( ) , } ) } } None }
Process debugging commands from the user.
Process debugging commands from the user .
&mut self
command
&str
vm
&PolarVirtualMachine
&mut self
command
&str
vm
&PolarVirtualMachine