aboutsummaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2017-12-28 22:21:54 +0000
committerAleksey Kladov <[email protected]>2017-12-28 22:21:54 +0000
commit5276a7d3be01687e3ea7054ec103711587c9d36e (patch)
treec8b4d79a49cc74c3dd1a588b636196e1bcfa311c /src/bin
parent5e1e8ed34a46738dda507a4a0f4e73065be74e57 (diff)
Grammar in ron
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/gen.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/bin/gen.rs b/src/bin/gen.rs
new file mode 100644
index 000000000..d3539321e
--- /dev/null
+++ b/src/bin/gen.rs
@@ -0,0 +1,82 @@
1extern crate serde;
2#[macro_use]
3extern crate serde_derive;
4
5extern crate ron;
6extern crate file;
7
8use std::path::PathBuf;
9use std::ascii::AsciiExt;
10use std::fmt::Write;
11
12fn main() {
13 let grammar = Grammar::read();
14 let text = grammar.to_syntax_kinds();
15 file::put_text(&generated_file(), &text).unwrap();
16}
17
18#[derive(Deserialize)]
19struct Grammar {
20 syntax_kinds: Vec<String>,
21}
22
23impl Grammar {
24 fn read() -> Grammar {
25 let text = file::get_text(&grammar_file()).unwrap();
26 ron::de::from_str(&text).unwrap()
27 }
28
29 fn to_syntax_kinds(&self) -> String {
30 let mut acc = String::new();
31 acc.push_str("// Generated from grammar.ron\n");
32 acc.push_str("use tree::{SyntaxKind, SyntaxInfo};\n");
33 acc.push_str("\n");
34 for (idx, kind) in self.syntax_kinds.iter().enumerate() {
35 let sname = scream(kind);
36 write!(
37 acc,
38 "pub const {}: SyntaxKind = SyntaxKind({});\n",
39 sname, idx
40 ).unwrap();
41 }
42 acc.push_str("\n");
43 for kind in self.syntax_kinds.iter() {
44 let sname = scream(kind);
45 write!(
46 acc,
47 "static {sname}_INFO: SyntaxInfo = SyntaxInfo {{\n name: \"{sname}\",\n}};\n",
48 sname = sname
49 ).unwrap();
50 }
51 acc.push_str("\n");
52
53 acc.push_str("pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {\n");
54 acc.push_str(" match kind {\n");
55 for kind in self.syntax_kinds.iter() {
56 let sname = scream(kind);
57 write!(
58 acc,
59 " {sname} => &{sname}_INFO,\n",
60 sname = sname
61 ).unwrap();
62 }
63 acc.push_str(" _ => unreachable!()\n");
64 acc.push_str(" }\n");
65 acc.push_str("}\n");
66 acc
67 }
68}
69
70fn grammar_file() -> PathBuf {
71 let dir = env!("CARGO_MANIFEST_DIR");
72 PathBuf::from(dir).join("grammar.ron")
73}
74
75fn generated_file() -> PathBuf {
76 let dir = env!("CARGO_MANIFEST_DIR");
77 PathBuf::from(dir).join("src/syntax_kinds.rs")
78}
79
80fn scream(word: &str) -> String {
81 word.chars().map(|c| c.to_ascii_uppercase()).collect()
82} \ No newline at end of file