1use std::{fs::File, io::Read};
3
4#[derive(Debug)] pub struct Grammar {
6 pub def: String,
7 pub new: String,
8}
9
10pub fn process_files(
12 input_file: &str,
13 user_grammar_file: Option<&str>,
14 neit_file: Option<&str>,
15) -> String {
16 let mut nc = String::new();
17 let defengine = gen_grm();
18 let mut usrgrm: Vec<Grammar> = Vec::new();
19
20 if !input_file.is_empty() {
22 process_grammar_file(input_file, &mut usrgrm);
23 }
24
25 if let Some(file) = user_grammar_file {
27 process_grammar_file(file, &mut usrgrm);
28 }
29
30 if let Some(file) = neit_file {
32 nc = process_neit_file(file, &usrgrm, &defengine);
33 }
34 nc
35}
36
37fn process_grammar_file(file_path: &str, usrgrm: &mut Vec<Grammar>) {
39 match File::open(file_path) {
40 Ok(mut file) => {
41 let mut content = String::new();
42 if let Err(e) = file.read_to_string(&mut content) {
43 eprintln!(
44 "Error reading the source grammar file '{}': {}",
45 file_path, e
46 );
47 std::process::exit(1);
48 }
49 let mut index = 1;
50 for ln in content.lines() {
51 if ln.starts_with("#") {
52 continue; } else {
54 let pts: Vec<&str> = ln.split("~").collect();
55 if pts.len() != 2 {
56 eprintln!(
57 "Error on line({}) in the file '{}' : {}",
58 index, file_path, ln
59 );
60 std::process::exit(1);
61 }
62 let ogv = pts[0].trim(); let nv = pts[1].trim(); usrgrm.push(Grammar {
66 def: ogv.to_string(),
67 new: nv.to_string(),
68 });
69 }
70 index += 1;
71 }
72 }
73 Err(_) => {
74 eprintln!(
75 "Could not find the grammar file '{}'. Ensure it exists.",
76 file_path
77 );
78 std::process::exit(1);
79 }
80 }
81}
82
83fn process_neit_file(file_path: &str, usrgrm: &[Grammar], defengine: &[Grammar]) -> String {
85 let mut nc = String::new();
86 match File::open(file_path) {
87 Ok(mut file) => {
88 let mut content = String::new();
89 if let Err(e) = file.read_to_string(&mut content) {
90 eprintln!("Error reading file '{}': {}", file_path, e);
91 std::process::exit(1);
92 }
93 let mut modified_content = String::new();
94 let mut current_word = String::new();
95 let mut in_string_mode = false;
96
97 for c in content.chars() {
98 if c == '"' {
99 in_string_mode = !in_string_mode;
100 modified_content.push(c);
101 continue;
102 }
103
104 if in_string_mode {
105 modified_content.push(c);
106 } else {
107 if c.is_whitespace() || c.is_ascii_punctuation() {
108 if !current_word.is_empty() {
109 let replaced_word = replace_word(¤t_word, usrgrm, defengine);
110 modified_content.push_str(&replaced_word);
111 current_word.clear();
112 }
113 modified_content.push(c);
114 } else {
115 current_word.push(c);
116 }
117 }
118 }
119
120 if !current_word.is_empty() {
122 let replaced_word: String = replace_word(¤t_word, usrgrm, defengine);
123 modified_content.push_str(&replaced_word);
124 }
125 nc.push_str(&modified_content.as_str());
126 }
127 Err(_) => {
128 eprintln!("Could not open neit file '{}'", file_path);
129 std::process::exit(1);
130 }
131 }
132 nc
133}
134
135fn replace_word(word: &str, usrgrm: &[Grammar], defengine: &[Grammar]) -> String {
137 for mapping in usrgrm.iter().chain(defengine.iter()) {
138 if word == mapping.new {
139 return mapping.def.clone();
140 }
141 }
142 word.to_string()
143}
144
145fn gen_grm() -> Vec<Grammar> {
147 vec![
148 Grammar {
149 def: "fn".to_string(),
150 new: "fn".to_string(),
151 },
152 Grammar {
153 def: "may".to_string(),
154 new: "may".to_string(),
155 },
156 Grammar {
157 def: "must".to_string(),
158 new: "must".to_string(),
159 },
160 Grammar {
161 def: "=".to_string(),
162 new: "=".to_string(),
163 },
164 Grammar {
165 def: "pub".to_string(),
166 new: "pub".to_string(),
167 },
168 Grammar {
169 def: "takein".to_string(),
170 new: "takein".to_string(),
171 },
172 Grammar {
173 def: "println".to_string(),
174 new: "println".to_string(),
175 },
176 Grammar {
177 def: "print".to_string(),
178 new: "print".to_string(),
179 },
180 ]
181}