summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs32
3 files changed, 37 insertions, 3 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 50a3b6b..9cc468a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,7 @@
name = "dhall"
version = "0.1.0"
dependencies = [
+ "bytecount 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-util 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -44,6 +45,11 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "bytecount"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "diff"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -246,6 +252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum bit-set 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84527c7b0452f22545cc010e72d366a435561d2b28b978035550b3778c4d428d"
"checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
+"checksum bytecount 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49e3c21915578e2300b08d3c174a8ac887e0c6421dff86fdc4d741dc29e5d413"
"checksum diff 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e48977eec6d3b7707462c2dc2e1363ad91b5dd822cf942537ccdc2085dc87587"
"checksum docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9"
"checksum fixedbitset 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3c33fc4c00db33f5174eb98aea809c4c007db0b71351d810a7e094ea3b64d"
diff --git a/Cargo.toml b/Cargo.toml
index 625cda1..8a5ad81 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,5 +8,6 @@ build = "build.rs"
lalrpop = "0.12.4"
[dependencies]
+bytecount = "0.1.4"
lalrpop-util = "0.12.4"
nom = "2.0.0"
diff --git a/src/main.rs b/src/main.rs
index e60a893..0abcea8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,4 @@
+extern crate bytecount;
extern crate lalrpop_util;
#[macro_use]
extern crate nom;
@@ -11,16 +12,41 @@ pub mod parser;
use std::io::{self, Read};
+fn print_error(message: &str, source: &str, start: usize, end: usize) {
+ let line_number = bytecount::count(source[..start].as_bytes(), '\n' as u8);
+ let line_start = source[..start].rfind('\n').map(|i| i + 1).unwrap_or(0);
+ let line_end = source[end..].find('\n').unwrap_or(0) + end;
+ let context = &source[line_start..line_end];
+
+ println!("error: {}", message);
+ println!(" --> (stdin):{}:0", line_number);
+ let line_number_str = line_number.to_string();
+ let line_number_width = line_number_str.len();
+ println!("{:w$} |", "", w = line_number_width);
+ println!("{} | {}", line_number_str, context);
+ println!("{:w$} | {:so$}{:^>ew$}", "", "", "",
+ w = line_number_width,
+ so = source[line_start..start].chars().count(),
+ ew = ::std::cmp::max(1, source[start..end].chars().count()));
+}
+
fn main() {
let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer).unwrap();
match parser::parse_expr(&buffer) {
Ok(e) => println!("{:?}", e),
Err(lalrpop_util::ParseError::User { error: lexer::LexicalError::Error(pos, e) }) => {
- let context = &buffer[pos..::std::cmp::min(buffer.len(), pos + 20)];
- println!("Unexpected token in {:?}: {:?}...", e, context);
+ print_error(&format!("Unexpected token {:?}", e), &buffer, pos, pos);
+ }
+ Err(lalrpop_util::ParseError::UnrecognizedToken { token: Some((start, t, end)), expected: e }) => {
+ print_error(&format!("Unrecognized token {:?}", t), &buffer, start, end);
+ if e.len() > 0 {
+ println!("Expected {:?}", e);
+ }
+ }
+ Err(e) => {
+ print_error(&format!("Parser error {:?}", e), &buffer, 0, 0);
}
- Err(e) => println!("{:?}", e),
}
/*