diff --git a/Cargo.lock b/Cargo.lock index a66d53f..14317d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,7 +288,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.13.4" +version = "0.13.5" dependencies = [ "display_source", "lalrpop", diff --git a/Cargo.toml b/Cargo.toml index 98637d1..cca8e63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.13.4" +version = "0.13.5" edition = "2021" authors = ["A4-Tacks "] diff --git a/build.rs b/build.rs index a7f981c..60fa05a 100644 --- a/build.rs +++ b/build.rs @@ -1,18 +1,21 @@ extern crate lalrpop; -use std::fs::remove_dir_all; +use std::{fs::remove_dir_all, path::Path}; fn main() { //lalrpop::process_root().unwrap(); // build to cargo tmp // build to src - // 最多尝试构建三次 + // 最多尝试构建 let mut res = Ok(()); - for _ in 0..3 { + for _ in 0..5 { res = lalrpop::Configuration::new() - .generate_in_source_tree() .always_use_colors() - .process(); + .set_in_dir(Path::new("src")) + .set_out_dir(Path::new("src")) + .emit_comments(false) + .process() + ; if res.is_ok() { break; } @@ -36,5 +39,7 @@ fn remove_incremental() { }, "/incremental" ].concat(); - remove_dir_all(incremental_path).unwrap(); + remove_dir_all(incremental_path).unwrap_or_else(|e| { + eprintln!("Warn: 删除增量目录失败 {e}") + }); } diff --git a/src/main.rs b/src/main.rs index 58ada11..c15be3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ use mindustry_logic_bang_lang::{ Expand, Meta }, - syntax::def::TopLevelParser, + syntax::{def::TopLevelParser, line_first_add}, tag_code::TagCodes, }; @@ -208,18 +208,26 @@ fn display_ast(ast: &Expand) -> String { } fn build_tag_down(meta: &mut CompileMeta) { - let tag_codes = meta.tag_codes_mut(); - tag_codes.build_tagdown() - .unwrap_or_else(|(_line, tag)| { - let (tag_str, _id) = meta.tags_map() - .iter() - .filter(|&(_k, v)| *v == tag) - .take(1) - .last() - .unwrap(); - err!("重复的标记: {:?}", tag_str); - exit(4) - }) + let result = meta.tag_codes_mut().build_tagdown(); + result.unwrap_or_else(|(_line, tag)| { + let (tag_str, _id) = meta.tags_map() + .iter() + .filter(|&(_k, v)| *v == tag) + .take(1) + .last() + .unwrap(); + let mut tags_map = meta.debug_tags_map(); + let mut tag_codes = meta.tag_codes().iter().map(ToString::to_string).collect(); + line_first_add(&mut tags_map, "\t"); + line_first_add(&mut tag_codes, "\t"); + err!( + "TagCode:\n{}\nTagsMap:\n{}\n重复的标记: {:?}", + tag_codes.join("\n"), + tags_map.join("\n"), + tag_str, + ); + exit(4) + }) } type ParseResult<'a> = Result, Error>>; diff --git a/src/syntax/def.lalrpop b/src/syntax/def.lalrpop index 4a82e3f..564fcc2 100644 --- a/src/syntax/def.lalrpop +++ b/src/syntax/def.lalrpop @@ -126,9 +126,9 @@ pub Value: Value = { }, "." => ValueBind(value.into(), attr).into(), // consted-dexp - "const" ConstStart => { + "const" ConstStart => { let tmp_name = meta.get_tmp_var(); - let dexp_const = Const(tmp_name.clone(), <>.into(), meta.pop_label_scope()); + let dexp_const = Const(tmp_name.clone(), dexp.into(), labels); DExp::new("__".into(), vec![ dexp_const.into(), LogicLine::SetResultHandle(tmp_name.into()), @@ -573,7 +573,7 @@ OpExprAtom: OpExprInfo = { // 开始一个const, 开启了必须负责清理 ConstStart: () = () => meta.add_label_scope(); -ConstStop: Vec = () => meta.pop_label_scope(); +ConstStop: Vec = () => Vec::from_iter(meta.pop_label_scope()); pub BuiltinCommand: LogicLine = { "const" "=" ConstStart )+> LEnd diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 56699d0..c2e56e1 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -3,7 +3,7 @@ pub mod def; use std::{ ops::Deref, num::ParseIntError, - collections::HashMap, + collections::{HashMap, HashSet}, iter::{ zip, repeat_with, @@ -475,7 +475,7 @@ pub struct Meta { tmp_var_count: usize, tag_number: usize, /// 被跳转的label - defined_labels: Vec>, + defined_labels: Vec>, break_labels: Vec>, continue_labels: Vec>, } @@ -484,7 +484,7 @@ impl Default for Meta { Self { tmp_var_count: 0, tag_number: 0, - defined_labels: vec![Vec::new()], + defined_labels: vec![HashSet::new()], break_labels: Vec::new(), continue_labels: Vec::new(), } @@ -509,26 +509,26 @@ impl Meta { pub fn get_tag(&mut self) -> String { let tag = self.tag_number; self.tag_number += 1; - format!("___{}", tag) + self.add_defined_label(format!("___{}", tag)) } /// 添加一个被跳转的label到当前作用域 /// 使用克隆的形式 pub fn add_defined_label(&mut self, label: Var) -> Var { // 至少有一个基层定义域 - self.defined_labels.last_mut().unwrap().push(label.clone()); + self.defined_labels.last_mut().unwrap().insert(label.clone()); label } /// 添加一个标签作用域, /// 用于const定义起始 pub fn add_label_scope(&mut self) { - self.defined_labels.push(Vec::new()) + self.defined_labels.push(HashSet::new()) } /// 弹出一个标签作用域, /// 用于const定义完成收集信息 - pub fn pop_label_scope(&mut self) -> Vec { + pub fn pop_label_scope(&mut self) -> HashSet { self.defined_labels.pop().unwrap() } @@ -2729,13 +2729,14 @@ impl CompileMeta { = self.get_const_value(name).unwrap(); let mut labels_map = HashMap::with_capacity(labels.len()); for (tmp_tag, label) in zip(tmp_tags, labels.iter().cloned()) { - let maped_label = format!( - "{}_const_{}_{}", - tmp_tag, - &name, - &label - ); - labels_map.insert(label, maped_label); + labels_map.entry(label).or_insert_with_key(|label| { + format!( + "{}_const_{}_{}", + tmp_tag, + &name, + &label + ) + }); } let res = value.clone(); self.const_expand_tag_name_map.push(labels_map); diff --git a/tools/tag_code/Cargo.lock b/tools/tag_code/Cargo.lock index d74e50b..bb852d4 100644 --- a/tools/tag_code/Cargo.lock +++ b/tools/tag_code/Cargo.lock @@ -4,4 +4,4 @@ version = 3 [[package]] name = "tag_code" -version = "0.1.2" +version = "0.1.3" diff --git a/tools/tag_code/src/lib.rs b/tools/tag_code/src/lib.rs index 631cf2d..30593b5 100644 --- a/tools/tag_code/src/lib.rs +++ b/tools/tag_code/src/lib.rs @@ -618,6 +618,7 @@ impl TagCodes { // :b // :b // ``` + self.lines = lines; return Err((i, tag)); } map_stack.push(tag); @@ -633,6 +634,7 @@ impl TagCodes { if let &mut Some(tag) = tag { if tag_alias_map.get(&tag).is_some() { // 映射到的目标是重复的 + self.lines = lines; return Err((i, tag)); } tag_alias_map.insert(tag, tag); // 将自己插入