aboutsummaryrefslogtreecommitdiff
path: root/tools/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-09 15:43:39 +0100
committerAleksey Kladov <[email protected]>2018-08-09 15:43:39 +0100
commitd8b2a5efc0e5de3b0d72f29ccc86185f0827c9d3 (patch)
tree46f8e8feb046ece8511ac1981f53bfa1762d3af3 /tools/src
parent36bd28633baf6015b767e9e70d2d53185271db50 (diff)
Generate AST
Diffstat (limited to 'tools/src')
-rw-r--r--tools/src/main.rs41
1 files changed, 30 insertions, 11 deletions
diff --git a/tools/src/main.rs b/tools/src/main.rs
index 714158f55..b5c966f74 100644
--- a/tools/src/main.rs
+++ b/tools/src/main.rs
@@ -23,6 +23,8 @@ const INLINE_TESTS_DIR: &str = "tests/data/parser/inline";
23const GRAMMAR: &str = "./src/grammar.ron"; 23const GRAMMAR: &str = "./src/grammar.ron";
24const SYNTAX_KINDS: &str = "./src/syntax_kinds/generated.rs"; 24const SYNTAX_KINDS: &str = "./src/syntax_kinds/generated.rs";
25const SYNTAX_KINDS_TEMPLATE: &str = "./src/syntax_kinds/generated.rs.tera"; 25const SYNTAX_KINDS_TEMPLATE: &str = "./src/syntax_kinds/generated.rs.tera";
26const AST: &str = "./src/ast/generated.rs";
27const AST_TEMPLATE: &str = "./src/ast/generated.rs.tera";
26 28
27fn main() -> Result<()> { 29fn main() -> Result<()> {
28 let matches = App::new("tasks") 30 let matches = App::new("tasks")
@@ -47,10 +49,16 @@ fn main() -> Result<()> {
47 49
48fn run_gen_command(name: &str, verify: bool) -> Result<()> { 50fn run_gen_command(name: &str, verify: bool) -> Result<()> {
49 match name { 51 match name {
50 "gen-kinds" => update(Path::new(SYNTAX_KINDS), &get_kinds()?, verify), 52 "gen-kinds" => {
51 "gen-tests" => gen_tests(verify), 53 update(Path::new(SYNTAX_KINDS), &render_template(SYNTAX_KINDS_TEMPLATE)?, verify)?;
54 update(Path::new(AST), &render_template(AST_TEMPLATE)?, verify)?;
55 },
56 "gen-tests" => {
57 gen_tests(verify)?
58 },
52 _ => unreachable!(), 59 _ => unreachable!(),
53 } 60 }
61 Ok(())
54} 62}
55 63
56fn update(path: &Path, contents: &str, verify: bool) -> Result<()> { 64fn update(path: &Path, contents: &str, verify: bool) -> Result<()> {
@@ -68,13 +76,30 @@ fn update(path: &Path, contents: &str, verify: bool) -> Result<()> {
68 Ok(()) 76 Ok(())
69} 77}
70 78
71fn get_kinds() -> Result<String> { 79fn render_template(template: &str) -> Result<String> {
72 let grammar = grammar()?; 80 let grammar: ron::value::Value = {
73 let template = fs::read_to_string(SYNTAX_KINDS_TEMPLATE)?; 81 let text = fs::read_to_string(GRAMMAR)?;
82 ron::de::from_str(&text)?
83 };
84 let template = fs::read_to_string(template)?;
74 let mut tera = tera::Tera::default(); 85 let mut tera = tera::Tera::default();
75 tera.add_raw_template("grammar", &template) 86 tera.add_raw_template("grammar", &template)
76 .map_err(|e| format_err!("template error: {:?}", e))?; 87 .map_err(|e| format_err!("template error: {:?}", e))?;
77 tera.register_global_function("concat", Box::new(concat)); 88 tera.register_global_function("concat", Box::new(concat));
89 tera.register_filter("camel", |arg, _| {
90 Ok(arg.as_str().unwrap()
91 .split("_")
92 .flat_map(|word| {
93 word.chars()
94 .next().unwrap()
95 .to_uppercase()
96 .chain(
97 word.chars().skip(1).flat_map(|c| c.to_lowercase())
98 )
99 })
100 .collect::<String>()
101 .into())
102 });
78 let ret = tera 103 let ret = tera
79 .render("grammar", &grammar) 104 .render("grammar", &grammar)
80 .map_err(|e| format_err!("template error: {:?}", e))?; 105 .map_err(|e| format_err!("template error: {:?}", e))?;
@@ -94,12 +119,6 @@ fn get_kinds() -> Result<String> {
94 } 119 }
95} 120}
96 121
97fn grammar() -> Result<ron::value::Value> {
98 let text = fs::read_to_string(GRAMMAR)?;
99 let ret = ron::de::from_str(&text)?;
100 Ok(ret)
101}
102
103fn gen_tests(verify: bool) -> Result<()> { 122fn gen_tests(verify: bool) -> Result<()> {
104 let tests = tests_from_dir(Path::new(GRAMMAR_DIR))?; 123 let tests = tests_from_dir(Path::new(GRAMMAR_DIR))?;
105 124