Skip to content

Commit

Permalink
添加一个调整noop展开的内置函数, 并在未命中内置函数时打印日志
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed May 1, 2024
1 parent fddab16 commit eb0049a
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 27 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mindustry_logic_bang_lang"
version = "0.15.10"
version = "0.15.11"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
7 changes: 7 additions & 0 deletions examples/builtin_functions.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
* * `IsString[str]`: 返回给定量是否是一个字符串
* * `RefArg`: 返回指定下标的上层参数句柄, 一般再用Const解开
* * `MissesMatch[enable]`: 当enable非0时, 将match失配打印日志功能开启
* * `SetNoOp[line]`: 根据给定的字串设置noop语句生成的行,
* 包含一层简单的反斜杠解释规则:
* `\\` => `\`
* `\'` => `"`
* `\` ch @ anychar => `\` + ch
* 需要注意的是, 字符串本身也会进行转义, 所以要注意一下
* 还要注意转义后双引号本身需要配对
*#

print Builtin.Type[x];
Expand Down
2 changes: 1 addition & 1 deletion tools/parser/tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parser-tests"
version = "0.1.19"
version = "0.1.20"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
60 changes: 60 additions & 0 deletions tools/parser/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5271,6 +5271,66 @@ fn builtin_func_test() {
"print 113",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
take Builtin.SetNoOp["set noop \\'noop\n\\'"];
select x {
print 1 2 3 4 5;
print 1 2 3;
print 1 2 3 4 5;
}
"#).unwrap()).compile().unwrap(),
vec![
r#"op mul __1 x 5"#,
r#"op add @counter @counter __1"#,
r#"print 1"#,
r#"print 2"#,
r#"print 3"#,
r#"print 4"#,
r#"print 5"#,
r#"print 1"#,
r#"print 2"#,
r#"print 3"#,
r#"jump 12 always 0 0"#,
r#"set noop "noop\n""#,
r#"print 1"#,
r#"print 2"#,
r#"print 3"#,
r#"print 4"#,
r#"print 5"#,
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
take Builtin.SetNoOp['\"str\"'];
select x {
print 1 2 3 4 5;
print 1 2 3;
print 1 2 3 4 5;
}
"#).unwrap()).compile().unwrap(),
vec![
r#"op mul __1 x 5"#,
r#"op add @counter @counter __1"#,
r#"print 1"#,
r#"print 2"#,
r#"print 3"#,
r#"print 4"#,
r#"print 5"#,
r#"print 1"#,
r#"print 2"#,
r#"print 3"#,
r#"jump 12 always 0 0"#,
r#""str""#,
r#"print 1"#,
r#"print 2"#,
r#"print 3"#,
r#"print 4"#,
r#"print 5"#,
],
);
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion tools/syntax/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "syntax"
version = "0.2.18"
version = "0.2.19"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
20 changes: 20 additions & 0 deletions tools/syntax/src/builtins.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::process;

use var_utils::escape_doublequote;

use crate::*;

#[derive(Clone)]
Expand Down Expand Up @@ -366,5 +368,23 @@ pub fn build_builtins() -> Vec<BuiltinFunc> {
Ok("__".into())
})
}
fn set_noop:SetNoOp(meta) [l:line] {
check_type!("var" Value::Var(line) = line.value() => {
let line = if Value::is_string(line) {
&line[1..line.len()-1]
} else {
line
};
let line = match escape_doublequote(line.trim()) {
Ok(s) => s,
Err(e) => return Err((2, e.into())),
};
if 0 != line.chars().filter(|&c| c == '"').count() & 1 {
return Err((2, "双引号未配对".into()));
}
meta.noop_line = line;
Ok("__".into())
})
}
}
}
36 changes: 26 additions & 10 deletions tools/syntax/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ impl TakeHandle for ClosuredValue {
let handle = meta.get_value_binded(
bind_handle.clone(),
var.clone(),
).clone();
);
Const(ConstKey::Var(var), handle.into(), Vec::new())
.compile(meta);
}
Expand Down Expand Up @@ -888,7 +888,7 @@ pub struct ValueBind(pub Box<Value>, pub Var);
impl ValueBind {
pub fn take_unfollow_handle(self, meta: &mut CompileMeta) -> Var {
let handle = self.0.take_handle(meta);
meta.get_value_binded(handle, self.1).clone()
meta.get_value_binded(handle, self.1)
}
}
impl TakeHandle for ValueBind {
Expand Down Expand Up @@ -2258,8 +2258,11 @@ impl Select {
tag_code::Jump::new_always(end_tag).into()
));
case.extend(
repeat_with(Default::default)
.take(insert_counts - 1)
repeat_with(||
LogicLine::NoOp
.compile_take(meta))
.take(insert_counts - 1)
.flatten()
);
case.push(TagLine::TagDown(end_tag));
},
Expand Down Expand Up @@ -2819,7 +2822,7 @@ pub enum LogicLine {
impl Compile for LogicLine {
fn compile(self, meta: &mut CompileMeta) {
match self {
Self::NoOp => meta.push("noop".into()),
Self::NoOp => meta.push(meta.noop_line.clone().into()),
Self::Label(mut lab) => {
// 如果在常量展开中, 尝试将这个标记替换
lab = meta.get_in_const_label(lab);
Expand Down Expand Up @@ -3176,6 +3179,7 @@ pub struct CompileMeta {
value_bind_global_consts: HashMap<Var, ConstData>,
last_builtin_exit_code: u8,
enable_misses_match_log_info: bool,
noop_line: String,
}
impl Debug for CompileMeta {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Expand Down Expand Up @@ -3211,6 +3215,8 @@ impl Default for CompileMeta {
}
}
impl CompileMeta {
const BUILTIN_FUNCS_BINDER: &'static str = "Builtin";

pub fn new() -> Self {
Self::default()
}
Expand All @@ -3233,8 +3239,9 @@ impl CompileMeta {
value_bind_global_consts: HashMap::new(),
last_builtin_exit_code: 0,
enable_misses_match_log_info: false,
noop_line: "noop".into(),
};
let builtin = String::from("Builtin");
let builtin = String::from(Self::BUILTIN_FUNCS_BINDER);
for builtin_func in build_builtins() {
let handle = format!("__{builtin}__{}", builtin_func.name());
let key = (builtin.clone().into(), builtin_func.name().into());
Expand Down Expand Up @@ -3283,12 +3290,21 @@ impl CompileMeta {
}

/// 获取绑定值, 如果绑定关系不存在则自动插入
pub fn get_value_binded(&mut self, value: Var, bind: Var) -> &Var {
pub fn get_value_binded(&mut self, value: Var, bind: Var) -> Var {
let mut warn_builtin = (value == Self::BUILTIN_FUNCS_BINDER)
.then_some((false, bind.clone()));
let key = (value, bind);
self.value_binds.entry(key)
let binded = self.value_binds.entry(key)
.or_insert_with(|| {
if let Some((ref mut warn, _)) = warn_builtin {
*warn = true;
}
self.tmp_var_count.get()
})
}).clone();
if let Some((true, bind)) = warn_builtin {
self.log_info(format_args!("Missed Builtin Call: {bind}"));
}
binded
}

/// 向已生成代码`push`
Expand Down Expand Up @@ -3444,7 +3460,7 @@ impl CompileMeta {
.set_binder(extra_binder
.unwrap_or_else(|| binder_handle.clone()));
let binded = self.get_value_binded(
binder_handle, name).clone();
binder_handle, name);
self.value_bind_global_consts
.insert(binded, data)
},
Expand Down
2 changes: 1 addition & 1 deletion tools/tag_code/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tag_code"
version = "0.1.4"
version = "0.1.5"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
5 changes: 0 additions & 5 deletions tools/tag_code/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,6 @@ impl Display for TagLine {
write!(f, "{}", res)
}
}
impl Default for TagLine {
fn default() -> Self {
Self::Line("noop".to_string().into())
}
}
impl std::fmt::Debug for TagLine {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn push_tag(s: &mut String, tag: Option<usize>, tail: bool) {
Expand Down
2 changes: 1 addition & 1 deletion tools/var_utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "var_utils"
version = "0.5.1"
version = "0.5.2"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
34 changes: 32 additions & 2 deletions tools/var_utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use lazy_regex::{regex,Lazy,Regex};
use lazy_regex::{regex, Lazy, Regex};
use std::{
collections::HashSet,
thread_local,
num::IntErrorKind,
thread_local,
};

/// 判断是否是一个标识符(包括数字)
Expand Down Expand Up @@ -224,5 +224,35 @@ pub fn string_unescape(s: &str) -> String {
res
}

/// 使用一种简单的转义允许双引号的输入
///
/// `\\` => `\`
/// `\'` => `"`
/// `\a` => `\a`
/// `x` => `x`
pub fn escape_doublequote(s: &str) -> Result<String, &'static str> {
let mut res = String::with_capacity(s.len());
let mut chars = s.chars();

loop {
let Some(ch) = chars.next() else { break; };
let escaped = match ch {
'\\' => match chars.next() {
Some('\'') => '"',
Some('\\') => '\\',
Some(ch) => {
res.push('\\');
ch
},
None => return Err("escaped eof"),
}
ch => ch,
};
res.push(escaped);
}

Ok(res)
}

#[cfg(test)]
mod tests;
15 changes: 15 additions & 0 deletions tools/var_utils/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,18 @@ fn string_unescape_test() {
assert_eq!(string_unescape(src), dst);
}
}

#[test]
fn escape_doublequote_test() {
let tests = [
(r#"abc"#, r#"abc"#),
(r#"abc\\def"#, r#"abc\def"#),
(r#"abc\def"#, r#"abc\def"#),
(r#"abc\'def"#, r#"abc"def"#),
(r#"'abc'def"#, r#"'abc'def"#),
];
for (src, dst) in tests {
let escaped = escape_doublequote(src);
assert_eq!(escaped.as_deref(), Ok(dst), "src: {src}");
}
}

0 comments on commit eb0049a

Please sign in to comment.