Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bril2json -p -p and Rust/Clap updates #233

Merged
merged 7 commits into from
Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bril-rs/bril2json/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ keywords = ["compiler", "bril", "parser", "data-structures", "language"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "3.2", features = ["derive"] }
clap = { version = "4.0", features = ["derive"] }
lalrpop-util = { version = "0.19", features = ["lexer"] }
regex = "1.5"

Expand Down
18 changes: 9 additions & 9 deletions bril-rs/bril2json/src/bril_grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ Alias : String = {
}

AbstractFunction : AbstractFunction = {
<loc:@L> <f: Func> <a: (Argument_List)?> <t:OutputType?> "{" <c :(<AbstractCode>)*> "}" => {let a = a.unwrap_or_default(); AbstractFunction {
<loc:@L> <f: Func> <a: (Argument_List)?> <t:OutputType?> <loc2:@R> "{" <c :(<AbstractCode>)*> "}" => {let a = a.unwrap_or_default(); AbstractFunction {
name : f,
args : a,
return_type : t,
instrs: c,
pos : lines.get_position(loc),
pos : lines.get_position(loc, loc2),
}}
}

Expand All @@ -100,19 +100,19 @@ AbstractArgument : AbstractArgument = {
}

AbstractCode : AbstractCode = {
<loc:@L> <l: Label> ":" => AbstractCode::Label{ label : l, pos : lines.get_position(loc)},
<loc:@L> <l: Label> ":" <loc2:@R> => AbstractCode::Label{ label : l, pos : lines.get_position(loc, loc2)},
<i: AbstractInstruction> => AbstractCode::Instruction(i),
}

AbstractInstruction : AbstractInstruction = {
<loc:@L> <i:Ident> <t:(":" <AbstractType>)?> "=" <c: ConstOps> <l: Literal> ";" => AbstractInstruction::Constant {
<loc:@L> <i:Ident> <t:(":" <AbstractType>)?> "=" <c: ConstOps> <l: Literal> ";" <loc2:@R> => AbstractInstruction::Constant {
op : c,
dest : i,
const_type : t,
value : l,
pos : lines.get_position(loc),
pos : lines.get_position(loc, loc2),
},
<loc:@L> <i:Ident> <t:(":" <AbstractType>)?> "=" <v:Ident> <f :(<Args>)*> ";" => {
<loc:@L> <i:Ident> <t:(":" <AbstractType>)?> "=" <v:Ident> <f :(<Args>)*> ";" <loc2:@R> => {
let mut a_vec = Vec::new();
let mut f_vec = Vec::new();
let mut l_vec = Vec::new();
Expand All @@ -130,10 +130,10 @@ AbstractInstruction : AbstractInstruction = {
args: a_vec,
funcs: f_vec,
labels: l_vec,
pos : lines.get_position(loc),
pos : lines.get_position(loc, loc2),
}
},
<loc:@L> <e:Ident> <f :(<Args>)*> ";" => {
<loc:@L> <e:Ident> <f :(<Args>)*> ";" <loc2:@R> => {
let mut a_vec = Vec::new();
let mut f_vec = Vec::new();
let mut l_vec = Vec::new();
Expand All @@ -149,7 +149,7 @@ AbstractInstruction : AbstractInstruction = {
args: a_vec,
funcs: f_vec,
labels: l_vec,
pos : lines.get_position(loc),
pos : lines.get_position(loc, loc2),
}
}

Expand Down
11 changes: 7 additions & 4 deletions bril-rs/bril2json/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use clap::Parser;
use clap::{ArgAction::Count, Parser};

#[derive(Parser)]
#[clap(about, version, author)] // keeps the cli synced with Cargo.toml
#[command(about, version, author)] // keeps the cli synced with Cargo.toml
pub struct Cli {
/// The bril file to statically link. stdin is assumed if file is not provided.
#[arg(short, long, action)]
pub file: Option<String>,
/// Flag for whether position information should be included
#[clap(short, action)]
pub position: bool,
#[arg(short, action = Count)]
pub position: u8,
}
56 changes: 47 additions & 9 deletions bril-rs/bril2json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,25 @@
pub mod bril_grammar;
#[doc(hidden)]
pub mod cli;
use bril_rs::{AbstractProgram, Position};
use std::fs::File;

use bril_rs::{AbstractProgram, ColRow, Position};

#[doc(hidden)]
#[derive(Clone)]
pub struct Lines {
use_pos: bool,
with_end: bool,
new_lines: Vec<usize>,
src_name: Option<String>,
}

impl Lines {
fn new(input: &str, use_pos: bool) -> Self {
fn new(input: &str, use_pos: bool, with_end: bool, src_name: Option<String>) -> Self {
Self {
use_pos,
with_end,
src_name,
new_lines: input
.as_bytes()
.iter()
Expand All @@ -30,21 +36,37 @@ impl Lines {
}
}

fn get_position(&self, index: usize) -> Option<Position> {
fn get_position(&self, starting_index: usize, ending_index: usize) -> Option<Position> {
if self.use_pos {
Some(Position {
pos: self.get_row_col(starting_index).unwrap(),
pos_end: if self.with_end {
self.get_row_col(ending_index)
} else {
None
},
src: self.src_name.clone(),
})
} else {
None
}
}

fn get_row_col(&self, index: usize) -> Option<ColRow> {
if self.use_pos {
Some(
self.new_lines
.iter()
.enumerate()
.map(|(i, j)| (i + 1, j))
.fold(
Position {
ColRow {
col: index as u64,
row: 1,
},
|current, (line_num, idx)| {
if *idx < index {
Position {
ColRow {
row: (line_num + 1) as u64,
col: (index - idx) as u64,
}
Expand All @@ -66,17 +88,33 @@ impl Lines {
pub fn parse_abstract_program_from_read<R: std::io::Read>(
mut input: R,
use_pos: bool,
with_end: bool,
file_name: Option<String>,
) -> AbstractProgram {
let mut buffer = String::new();
input.read_to_string(&mut buffer).unwrap();
let parser = bril_grammar::AbstractProgramParser::new();

let src_name = file_name.map(|f| std::fs::canonicalize(f).unwrap().display().to_string());

parser
.parse(&Lines::new(&buffer, use_pos), &buffer)
.parse(&Lines::new(&buffer, use_pos, with_end, src_name), &buffer)
.unwrap()
}

#[must_use]
/// A wrapper around [`parse_abstract_program_from_read`] which assumes [`std::io::Stdin`]
pub fn parse_abstract_program(use_pos: bool) -> AbstractProgram {
parse_abstract_program_from_read(std::io::stdin(), use_pos)
/// A wrapper around [`parse_abstract_program_from_read`] which assumes [`std::io::Stdin`] if `file_name` is [`None`]
/// # Panics
/// Will panic if the input is not well-formed Bril text or if `file_name` does not exist
pub fn parse_abstract_program(
use_pos: bool,
with_end: bool,
file_name: Option<String>,
) -> AbstractProgram {
let input: Box<dyn std::io::Read> = match file_name.clone() {
Some(f) => Box::new(File::open(f).unwrap()),
None => Box::new(std::io::stdin()),
};

parse_abstract_program_from_read(input, use_pos, with_end, file_name)
}
6 changes: 5 additions & 1 deletion bril-rs/bril2json/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ use clap::Parser;

fn main() {
let args = Cli::parse();
output_abstract_program(&parse_abstract_program(args.position))
output_abstract_program(&parse_abstract_program(
args.position >= 1,
args.position >= 2,
args.file,
))
}
2 changes: 1 addition & 1 deletion bril-rs/brild/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ keywords = ["compiler", "bril", "parser", "data-structures", "language"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "3.2", features = ["derive"] }
clap = { version = "4.0", features = ["derive"] }
thiserror = "1.0"

[dependencies.bril2json]
Expand Down
6 changes: 3 additions & 3 deletions bril-rs/brild/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use clap::Parser;
use std::path::PathBuf;

#[derive(Parser)]
#[clap(about, version, author)] // keeps the cli synced with Cargo.toml
#[command(about, version, author)] // keeps the cli synced with Cargo.toml
pub struct Cli {
/// The bril file to statically link. stdin is assumed if file is not provided.
#[clap(short, long, action)]
#[arg(short, long, action)]
pub file: Option<String>,
/// A list of library paths to look for Bril files.
#[clap(short, long, action, multiple_values = true)]
#[arg(short, long, action, num_args=1..)]
pub libs: Vec<PathBuf>,
}
26 changes: 17 additions & 9 deletions bril-rs/brild/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,23 @@ pub fn do_import<S: BuildHasher>(
path_map.insert(canonical_path.clone(), None);

// Find the correct parser for this path based on the extension
let f = match canonical_path.extension().and_then(std::ffi::OsStr::to_str) {
Some("bril") => |s| parse_abstract_program_from_read(s, true),
Some("json") => load_abstract_program_from_read,
Some(_) | None => {
return Err(BrildError::MissingOrUnknownFileExtension(
canonical_path.clone(),
))
}
};
let f: Box<dyn Fn(_) -> AbstractProgram> =
match canonical_path.extension().and_then(std::ffi::OsStr::to_str) {
Some("bril") => Box::new(|s| {
parse_abstract_program_from_read(
s,
true,
true,
Some(canonical_path.display().to_string()),
)
}),
Some("json") => Box::new(load_abstract_program_from_read),
Some(_) | None => {
return Err(BrildError::MissingOrUnknownFileExtension(
canonical_path.clone(),
))
}
};

// Get the AbstractProgram representation of the file
let program = f(File::open(&canonical_path)?);
Expand Down
2 changes: 1 addition & 1 deletion bril-rs/rs2bril/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ keywords = ["compiler", "bril", "parser", "data-structures", "language"]
[dependencies]
syn = {version = "1.0", features = ["full", "extra-traits"]}
proc-macro2 = {version = "1.0", features = ["span-locations"]}
clap = { version = "3.2", features = ["derive"] }
clap = { version = "4.0", features = ["derive"] }

[dependencies.bril-rs]
version = "0.1.0"
Expand Down
7 changes: 5 additions & 2 deletions bril-rs/rs2bril/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use clap::Parser;

#[derive(Parser)]
#[clap(about, version, author)] // keeps the cli synced with Cargo.toml
#[command(about, version, author)] // keeps the cli synced with Cargo.toml
pub struct Cli {
/// The bril file to statically link. stdin is assumed if file is not provided.
#[arg(short, long, action)]
pub file: Option<String>,
/// Flag for whether position information should be included
#[clap(short, action)]
#[arg(short, action)]
pub position: bool,
}
Loading