summary refs log tree commit diff
path: root/src/main.rs
blob: 60c14ca9802ee92f655a999803d8e81b13a89b14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use crate::prelude::*;
use std::io;
use std::io::prelude::*;

#[macro_use] extern crate lalrpop_util;

lalrpop_mod!(pub commandline);
pub mod error;
pub mod path;
pub mod prelude;
pub mod result;


pub enum Input {
  String(String),
  End,
}


fn main() -> Result<()> {
  std::process::exit(match repl() {
    Ok(()) => 0,
    Err(ref e) => {
      eprintln!("{}", e);
      1
    }
  })
}


fn repl() -> Result<()> {
  println!("Hello, terminal!");

  loop {
    prompt()?;

    let input = read()?;
    match input {
      Input::String(string) => execute(&string)?,
      Input::End => break,
    }
  }

  Ok(())
}


fn prompt() -> Result<()> {
  print!("$ ");
  io::stdout().flush()?;

  Ok(())
}


fn read() -> Result<Input> {
  let mut input = String::new();
  let n_bytes = io::stdin().read_line(&mut input)?;

  if n_bytes == 0 {
    Ok(Input::End)
  } else {
    Ok(Input::String(input))
  }
}


fn execute(input: &str) -> Result<()> {
  let invocation = commandline::InvocationParser::new().parse(input)?;

  println!("{}", input);

  match invocation.as_slice() {
    ["paths", path_list, ..] => {
      let paths = path::parse_path_list(path_list)?;
      for path in &paths {
        println!("{}", path);
      }
    },
    _ => {
      println!("invocation '{:?}'", invocation);
    }
  }

  Ok(())
}