Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions extensions/kvlang/language-configuration.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
{
"comments": { "lineComment": "#" },
"comments": { "lineComment": "//", "blockComment": ["/*", "*/"] },
"brackets": [
["(", ")"],
["[", "]"],
["{", "}"]
],
"autoClosingPairs": [
["\"\"\"", "\"\"\""],
["\"", "\""],
["`", "`"],
["'", "'"],
["(", ")"],
["[", "]"],
Expand Down
38 changes: 21 additions & 17 deletions extensions/kvlang/syntaxes/kvlang.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"fileTypes": [],
"patterns": [
{ "include": "#line_comment" },
{ "include": "#string_triple" },
{ "include": "#string_double" },
{ "include": "#block_comment" },
{ "include": "#string_raw" },
{ "include": "#string_double" },
{ "include": "#keypath_single" },
{ "include": "#keyword" },
{ "include": "#type" },
Expand All @@ -17,23 +17,27 @@
],
"repository": {
"line_comment": {
"name": "comment.line.kvlang",
"match": "(#|//).*$"
"name": "comment.line.double-slash.kvlang",
"match": "//.*$"
},
"string_triple": {
"name": "string.quoted.triple.kvlang",
"begin": "\"\"\"",
"end": "\"\"\""
"block_comment": {
"name": "comment.block.kvlang",
"begin": "/\\*",
"end": "\\*/",
"patterns": [{ "include": "#block_comment" }]
},
"string_raw": {
"name": "string.quoted.raw.kvlang",
"begin": "r(#*)\"",
"end": "\"\\1"
},
"string_double": {
"name": "string.quoted.double.kvlang",
"begin": "\"",
"end": "\""
},
"string_raw": {
"name": "string.quoted.raw.kvlang",
"begin": "`",
"end": "`"
"end": "\"",
"patterns": [
{ "name": "constant.character.escape.kvlang", "match": "\\\\." }
]
},
"keypath_single": {
"name": "string.quoted.single.kvlang",
Expand All @@ -42,23 +46,23 @@
},
"keyword": {
"name": "keyword.control.kvlang",
"match": "\\b(rwfunc|rwir|if|else|for|while|break|continue|return)\\b"
"match": "\\b(rwfunc|rwir|lib|if|else|for|while|break|continue|return)\\b"
},
"block_label": {
"name": "entity.name.label.kvlang",
"match": "^\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*:"
},
"type": {
"name": "storage.type.kvlang",
"match": "\\b(int8|int16|int32|int64|uint8|uint16|uint32|uint64|float32|float64|bool|charbyte)\\b"
"match": "\\b(int8|int16|int32|int64|uint8|uint16|uint32|uint64|float32|float64|bool|char|utf8|utf32|object|stringkeymap)\\b"
},
"number": {
"name": "constant.numeric.kvlang",
"match": "-?[0-9]+(\\.[0-9]+)?"
},
"operator": {
"name": "keyword.operator.kvlang",
"match": "[+\\-*/%]|==|!=|<=|>=|<|>|&&|\\|\\||!"
"match": "[+\\-×÷%]|==|!=|<=|>=|<|>|&&|\\|\\||!"
},
"arrow": {
"name": "keyword.operator.arrow.kvlang",
Expand Down
33 changes: 28 additions & 5 deletions layout/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ pub struct Expr {
pub op: String, // 算子/函数名("" = 叶节点)
pub args: Vec<Expr>, // 操作数(叶节点为空)
pub val: String, // 叶节点值
pub quote: u8, // 0=非字符串, '"'=双引号, '`'=反引号
pub quote: u8, // 0=非字符串, '"'=字符串(转义或原始,由 lit 区分)
pub lit: LitKind, // 字面量类型(仅叶节点有意义)
}

Expand Down Expand Up @@ -248,7 +248,7 @@ pub fn raw_str(v: &str) -> Expr {
op: String::new(),
args: Vec::new(),
val: v.to_string(),
quote: b'`',
quote: b'"',
lit: LitKind::LitRawString,
}
}
Expand Down Expand Up @@ -312,10 +312,10 @@ impl Expr {
fn string_prec(&self, outer_prec: i32) -> String {
if self.is_leaf() {
if self.quote != 0 {
if self.quote == b'"' {
return format!("\"{}\"", escape_string(&self.val));
if self.lit == LitKind::LitRawString {
return raw_string_lit(&self.val);
}
return format!("`{}`", self.val);
return format!("\"{}\"", escape_string(&self.val));
}
return self.val.clone();
}
Expand Down Expand Up @@ -799,6 +799,29 @@ fn escape_string(s: &str) -> String {
b
}

/// 把值渲染为 Rust 原始字符串 `r#"..."#`,井号数取最小可行值(保证内容不与闭合定界符冲突)。
fn raw_string_lit(v: &str) -> String {
let bytes = v.as_bytes();
let mut n = 0usize;
let mut k = 0;
while k < bytes.len() {
if bytes[k] == b'"' {
let mut h = 0;
let mut j = k + 1;
while j < bytes.len() && bytes[j] == b'#' {
h += 1;
j += 1;
}
if h + 1 > n {
n = h + 1;
}
}
k += 1;
}
let hashes = "#".repeat(n);
format!("r{hashes}\"{v}\"{hashes}")
}

fn is_operator_char(c: u8) -> bool {
symbol::scanner_one_char_ops().contains(&c)
}
6 changes: 3 additions & 3 deletions layout/src/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ pub fn dump(kv: &mut Kv, lib: &str) -> String {
let mut out = String::new();
emit_node(&mut out, &root, "");
for d in decls {
out.push_str("# ");
out.push_str("// ");
out.push_str(&d);
out.push('\n');
}
Expand Down Expand Up @@ -342,12 +342,12 @@ fn emit_func(out: &mut String, f: &DumpFunc, indent: &str) {
out.push('\n');
}
out.push_str(indent);
out.push_str("# ");
out.push_str("// ");
out.push_str(&f.dir);
out.push('\n');
for s in &f.slots {
out.push_str(indent);
out.push_str("# ");
out.push_str("// ");
out.push_str(s);
out.push('\n');
}
Expand Down
2 changes: 1 addition & 1 deletion layout/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,7 @@ impl Parser {
if t.quote == b'"' {
return Some(ast::str_lit(&v));
}
if t.quote == b'`' {
if t.quote == b'r' {
return Some(ast::raw_str(&v));
}
if !v.is_empty() && v.as_bytes()[0] == b'/' {
Expand Down
Loading
Loading