From e5d9aee00b0c775df1d8e2d8819aeb80dffa73c2 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 1 Mar 2019 17:28:19 +0100 Subject: Split abnf_to_pest and dhall into their own crates --- dhall/src/main.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 dhall/src/main.rs (limited to 'dhall/src/main.rs') diff --git a/dhall/src/main.rs b/dhall/src/main.rs new file mode 100644 index 0000000..cdab3c0 --- /dev/null +++ b/dhall/src/main.rs @@ -0,0 +1,101 @@ +use std::io::{self, Read}; +use std::error::Error; +use term_painter::ToStyle; + +use dhall::*; + +const ERROR_STYLE: term_painter::Color = term_painter::Color::Red; +const BOLD: term_painter::Attr = term_painter::Attr::Bold; + +fn print_error(message: &str, source: &str, start: usize, end: usize) { + let line_number = bytecount::count(source[..start].as_bytes(), b'\n'); + 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_prefix = &source[line_start..start]; + let context_highlighted = &source[start..end]; + let context_suffix = &source[end..line_end]; + + let line_number_str = line_number.to_string(); + let line_number_width = line_number_str.len(); + + BOLD.with(|| { + ERROR_STYLE.with(|| { + print!("error: "); + }); + println!("{}", message); + }); + BOLD.with(|| { + print!(" -->"); + }); + println!(" {}:{}:0", "(stdin)", line_number); + BOLD.with(|| { + println!("{:w$} |", "", w = line_number_width); + print!("{} |", line_number_str); + }); + print!(" {}", context_prefix); + BOLD.with(|| { + ERROR_STYLE.with(|| { + print!("{}", context_highlighted); + }); + }); + println!("{}", context_suffix); + BOLD.with(|| { + print!("{:w$} |", "", w = line_number_width); + ERROR_STYLE.with(|| { + println!(" {:so$}{:^>ew$}", "", "", + 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(); + let expr = match parser::parse_expr(&buffer) { + Ok(e) => e, + Err(lalrpop_util::ParseError::User { error: lexer::LexicalError::Error(pos, e) }) => { + print_error(&format!("Unexpected token {:?}", e), &buffer, pos, pos); + return; + } + Err(lalrpop_util::ParseError::UnrecognizedToken { token: Some((start, t, end)), expected: e }) => { + print_error(&format!("Unrecognized token {:?}", t), &buffer, start, end); + if !e.is_empty() { + println!("Expected {:?}", e); + } + return; + } + Err(e) => { + print_error(&format!("Parser error {:?}", e), &buffer, 0, 0); + return; + } + }; + + /* + expr' <- load expr + */ + + let type_expr = match typecheck::type_of(&expr) { + Err(e) => { + let explain = ::std::env::args().any(|s| s == "--explain"); + if !explain { + term_painter::Color::BrightBlack.with(|| { + println!("Use \"dhall --explain\" for detailed errors"); + }); + } + ERROR_STYLE.with(|| print!("Error: ")); + println!("{}", e.type_message.description()); + if explain { + println!("{}", e.type_message); + } + println!("{}", e.current); + // FIXME Print source position + return; + } + Ok(type_expr) => type_expr, + }; + + println!("{}", type_expr); + println!(""); + println!("{}", normalize::<_, X, _>(&expr)); +} -- cgit v1.2.3