-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add visualization of ASTs to CLI & REPL
- Add actual arg parsing to CLI - Make REPL a sub-mode initiated by a CLI command - Add partial (lots of `todo!()`s) translation of AST into graphviz - Add FFI to graphviz to layout & render - Add `display` mode which prints image to console
- Loading branch information
Showing
11 changed files
with
951 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
use clap::{ArgEnum, Parser, Subcommand}; | ||
|
||
#[derive(Parser)] | ||
#[clap(author, version, about, long_about = None)] | ||
pub struct Args { | ||
#[clap(subcommand)] | ||
pub command: Commands, | ||
} | ||
|
||
#[derive(Subcommand)] | ||
pub enum Commands { | ||
#[cfg(feature = "visualize")] | ||
/// Dump the AST for a query | ||
Ast { | ||
#[clap(short = 'T', long = "format", value_enum)] | ||
format: Format, | ||
|
||
/// Query to parse | ||
#[clap(value_parser)] | ||
query: String, | ||
}, | ||
/// interactive REPL (Read Eval Print Loop) shell | ||
Repl, | ||
} | ||
|
||
#[derive(ArgEnum, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||
pub enum Format { | ||
/// JSON | ||
Json, | ||
/// Graphviz dot | ||
Dot, | ||
/// Graphviz svg output | ||
Svg, | ||
/// Graphviz svg rendered to png | ||
Png, | ||
/// Display rendered output | ||
Display, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
use miette::{Diagnostic, LabeledSpan, SourceCode}; | ||
use partiql_parser::ParseError; | ||
use partiql_source_map::location::{BytePosition, Location}; | ||
use thiserror::Error; | ||
|
||
#[derive(Debug, Error)] | ||
pub enum CLIError { | ||
#[error("PartiQL syntax error:")] | ||
SyntaxError { | ||
src: String, | ||
msg: String, | ||
loc: Location<BytePosition>, | ||
}, | ||
// TODO add github issue link | ||
#[error("Internal Compiler Error - please report this.")] | ||
InternalCompilerError { src: String }, | ||
} | ||
|
||
impl Diagnostic for CLIError { | ||
fn source_code(&self) -> Option<&dyn SourceCode> { | ||
match self { | ||
CLIError::SyntaxError { src, .. } => Some(src), | ||
CLIError::InternalCompilerError { src, .. } => Some(src), | ||
} | ||
} | ||
|
||
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> { | ||
match self { | ||
CLIError::SyntaxError { msg, loc, .. } => { | ||
Some(Box::new(std::iter::once(LabeledSpan::new( | ||
Some(msg.to_string()), | ||
loc.start.0 .0 as usize, | ||
loc.end.0 .0 as usize - loc.start.0 .0 as usize, | ||
)))) | ||
} | ||
CLIError::InternalCompilerError { .. } => None, | ||
} | ||
} | ||
} | ||
|
||
impl CLIError { | ||
pub fn from_parser_error(err: ParseError, source: &str) -> CLIError { | ||
match err { | ||
ParseError::SyntaxError(partiql_source_map::location::Located { inner, location }) => { | ||
CLIError::SyntaxError { | ||
src: source.to_string(), | ||
msg: format!("Syntax error `{}`", inner), | ||
loc: location, | ||
} | ||
} | ||
ParseError::UnexpectedToken(partiql_source_map::location::Located { | ||
inner, | ||
location, | ||
}) => CLIError::SyntaxError { | ||
src: source.to_string(), | ||
msg: format!("Unexpected token `{}`", inner.token), | ||
loc: location, | ||
}, | ||
ParseError::LexicalError(partiql_source_map::location::Located { inner, location }) => { | ||
CLIError::SyntaxError { | ||
src: source.to_string(), | ||
msg: format!("Lexical error `{}`", inner), | ||
loc: location, | ||
} | ||
} | ||
ParseError::Unknown(location) => CLIError::SyntaxError { | ||
src: source.to_string(), | ||
msg: "Unknown parser error".to_string(), | ||
loc: Location { | ||
start: location, | ||
end: location, | ||
}, | ||
}, | ||
ParseError::IllegalState(_location) => CLIError::InternalCompilerError { | ||
src: source.to_string(), | ||
}, | ||
_ => { | ||
todo!("Not yet handled {:?}", err); | ||
} | ||
} | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
pub mod args; | ||
|
||
pub mod error; | ||
pub mod repl; | ||
|
||
#[cfg(feature = "visualize")] | ||
pub mod visualize; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#![deny(rustdoc::broken_intra_doc_links)] | ||
|
||
use clap::Parser; | ||
use partiql_cli::{args, repl}; | ||
|
||
use partiql_parser::Parsed; | ||
|
||
#[allow(dead_code)] | ||
fn parse(query: &str) -> miette::Result<Parsed> { | ||
let res = partiql_parser::Parser::default().parse(query); | ||
//TODO | ||
Ok(res.expect("parse failure")) | ||
} | ||
|
||
fn main() -> miette::Result<()> { | ||
let args = args::Args::parse(); | ||
|
||
match &args.command { | ||
args::Commands::Repl => repl::repl(), | ||
|
||
#[cfg(feature = "visualize")] | ||
args::Commands::Ast { format, query } => { | ||
use partiql_cli::args::Format; | ||
use partiql_cli::visualize::render::{display, to_dot, to_json, to_png, to_svg}; | ||
use std::io::Write; | ||
|
||
let parsed = parse(&query)?; | ||
match format { | ||
Format::Json => println!("{}", to_json(&parsed.ast)), | ||
Format::Dot => println!("{}", to_dot(&parsed.ast)), | ||
Format::Svg => println!("{}", to_svg(&parsed.ast)), | ||
Format::Png => { | ||
std::io::stdout() | ||
.write(&to_png(&parsed.ast)) | ||
.expect("png write"); | ||
} | ||
Format::Display => display(&parsed.ast), | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.