Skip to content

Commit

Permalink
Refactor updating of var_type for JoinTerms (#59)
Browse files Browse the repository at this point in the history
* Refactor updating of var_type for JoinTerms

* Remove is_variable attribute from JoinTerm (replaced with var_type being an Option)

* Test that parse_write() crashes with missing var

* Simplify python template

---------

Co-authored-by: ellnix <103502144+ellnix@users.noreply.github.com>
  • Loading branch information
daxida and ellnix authored Apr 25, 2024
1 parent f48b232 commit c71a73d
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 50 deletions.
2 changes: 1 addition & 1 deletion config/stub_templates/cpp/write_join.cpp.jinja
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{%- set_global out = "" -%}
{%- for term in terms -%}
{%- if term.is_variable -%}
{%- if term.var_type -%}
{%- set_global out = out ~ term.ident -%}
{%- else -%}
{%- set_global out = out ~ '"' ~ term.ident ~ '"' -%}
Expand Down
10 changes: 4 additions & 6 deletions config/stub_templates/python/write_join.py.jinja
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
{%- set_global out = "" -%}
{%- for term in terms -%}
{%- if term.is_variable -%}
{%- if term.var_type == "String" or term.var_type == "Word" -%}
{%- set_global out = out ~ term.ident -%}
{%- else -%}
{%- set_global out = out ~ "str(" ~ term.ident ~ ")" -%}
{%- endif -%}
{%- if term.var_type == "String" or term.var_type == "Word" -%}
{%- set_global out = out ~ term.ident -%}
{%- elif term.var_type -%}
{%- set_global out = out ~ "str(" ~ term.ident ~ ")" -%}
{%- else -%}
{%- set_global out = out ~ '"' ~ term.ident ~ '"' -%}
{%- endif -%}
Expand Down
2 changes: 1 addition & 1 deletion config/stub_templates/ruby/write_join.rb.jinja
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
puts "
{%- for term in terms -%}
{%- if term.is_variable -%}
{%- if term.var_type -%}
{{- '#{' }}{{ term.ident }}{{ '}' -}}
{%- else -%}
{{- term.ident -}}
Expand Down
17 changes: 2 additions & 15 deletions src/stub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,12 @@ impl VariableCommand {
#[derive(Serialize, Clone, Debug)]
pub struct JoinTerm {
pub ident: String,
pub is_variable: bool,
pub var_type: Option<VarType>,
}

impl JoinTerm {
pub fn new_literal(ident: String) -> Self {
Self {
ident,
is_variable: false,
var_type: None,
}
}

pub fn new_variable(ident: String) -> Self {
Self {
ident,
is_variable: true,
var_type: None,
}
pub fn new(ident: String, var_type: Option<VarType>) -> JoinTerm {
JoinTerm { ident, var_type }
}
}

Expand Down
36 changes: 12 additions & 24 deletions src/stub/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub fn parse_generator_stub(generator: &str) -> Result<Stub> {
/// Exists solely to be consumed with `.parse()`
struct Parser<'a> {
token_stream: Box<dyn Iterator<Item = &'a str> + 'a>,
read_pairings: std::collections::BTreeMap<String, VarType>,
}

impl<'a> Parser<'a> {
Expand All @@ -26,6 +27,7 @@ impl<'a> Parser<'a> {
let token_stream = stub.lines().flat_map(|line| line.split(' ').chain(iter::once("\n")));
Self {
token_stream: Box::new(token_stream),
read_pairings: std::collections::BTreeMap::new(),
}
}

Expand All @@ -48,25 +50,6 @@ impl<'a> Parser<'a> {
};
}

// Update WriteJoin terms with their respective var_type.
let mut read_pairings = std::collections::BTreeMap::new();
for read_cmd in &stub.commands {
if let Cmd::Read(var_cmds) = read_cmd {
for var_cmd in var_cmds {
read_pairings.insert(var_cmd.ident.clone(), var_cmd.var_type);
}
}
}
for cmd in &mut stub.commands {
if let Cmd::WriteJoin { join_terms, output_comment: _ } = cmd {
for term in join_terms.iter_mut() {
if let Some(var_type) = read_pairings.get(&term.ident) {
term.var_type = Some(*var_type);
}
}
}
}

Ok(stub)
}

Expand Down Expand Up @@ -124,10 +107,14 @@ impl<'a> Parser<'a> {
.split(',')
.map(|term| {
if term.contains('"') {
let term_name = term.trim_matches(|c| c != '"').trim_matches('"').to_string();
JoinTerm::new_literal(term_name)
let ident = term.trim_matches(|c| c != '"').trim_matches('"').to_string();
JoinTerm::new(ident, None)
} else {
JoinTerm::new_variable(term.trim().to_string())
let ident = term.trim().to_string();
match self.read_pairings.get(&ident) {
Some(var_type) => JoinTerm::new(ident, Some(*var_type)),
None => panic!("The JoinTerm '{}' was not previously initialized.", &ident),
}
}
})
.collect();
Expand Down Expand Up @@ -174,10 +161,10 @@ impl<'a> Parser<'a> {
panic!("Empty line after read keyword")
};

tokens.into_iter().filter_map(Self::parse_variable).collect()
tokens.into_iter().filter_map(|token| self.parse_variable(token)).collect()
}

fn parse_variable(token: &str) -> Option<VariableCommand> {
fn parse_variable(&mut self, token: &str) -> Option<VariableCommand> {
// A token may be empty if extra spaces were present: "read x:int "
if token.is_empty() {
return None
Expand All @@ -186,6 +173,7 @@ impl<'a> Parser<'a> {
panic!("Variable must have type")
};
let (var_type, max_length) = Self::extract_type_and_length(type_string);
self.read_pairings.insert(String::from(ident), var_type);

Some(VariableCommand::new(ident.to_string(), var_type, max_length))
}
Expand Down
15 changes: 13 additions & 2 deletions src/stub/parser/parser_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,21 @@ fn parse_write_captures_lines_of_text_until_empty_line() {
assert_eq!(lines, vec!["hello", "world"]);
}

#[test]
#[should_panic]
fn parse_write_errors_on_write_join_with_undeclared_vars() {
Parser::new("join(\"hello\", world)").parse_write();
}

#[test]
fn parse_write_returns_write_joins() {
let mut parser = Parser::new("join(\"hello\", world)");
let Cmd::WriteJoin { join_terms, .. } = parser.parse_write() else { panic!() };
let mut parser = Parser::new(indoc! {r##"
world:int
join("hello", world)
"##});

parser.parse_read();
let Cmd::WriteJoin { join_terms, output_comment: _} = parser.parse_write() else { panic!() };

let [
JoinTerm { ident: first_term, .. },
Expand Down
2 changes: 1 addition & 1 deletion src/stub/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl Renderer {
.iter()
.cloned()
.map(|mut term| {
if term.is_variable {
if term.var_type.is_some() {
term.ident = self.lang.variable_name_options.transform_variable_name(&term.ident);
}
term
Expand Down

0 comments on commit c71a73d

Please sign in to comment.