mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 12:14:43 +00:00
fix: symbol mangling
This commit is contained in:
parent
6c23d85fc4
commit
d4c566477f
4 changed files with 66 additions and 10 deletions
|
@ -68,11 +68,17 @@ fn debind(ident: &Identifier) -> Option<Str> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn escape_name(name: &str, vis: &VisibilityModifier) -> Str {
|
fn escape_name(name: &str, vis: &VisibilityModifier, def_line: u32, def_col: u32) -> Str {
|
||||||
let name = name.replace('!', "__erg_proc__");
|
let name = name.replace('!', "__erg_proc__");
|
||||||
let name = name.replace('$', "__erg_shared__");
|
let name = name.replace('$', "__erg_shared__");
|
||||||
if vis.is_private() {
|
if vis.is_private() {
|
||||||
Str::from("::".to_string() + &name)
|
let line_mangling = match (def_line, def_col) {
|
||||||
|
(0, 0) => "".to_string(),
|
||||||
|
(0, _) => format!("_C{def_col}"),
|
||||||
|
(_, 0) => format!("_L{def_line}"),
|
||||||
|
(_, _) => format!("_L{def_line}_C{def_col}"),
|
||||||
|
};
|
||||||
|
Str::from(format!("::{name}{line_mangling}"))
|
||||||
} else {
|
} else {
|
||||||
Str::from(name)
|
Str::from(name)
|
||||||
}
|
}
|
||||||
|
@ -83,7 +89,12 @@ fn escape_ident(ident: Identifier) -> Str {
|
||||||
if let Some(py_name) = ident.vi.py_name {
|
if let Some(py_name) = ident.vi.py_name {
|
||||||
py_name
|
py_name
|
||||||
} else {
|
} else {
|
||||||
escape_name(ident.inspect(), vis)
|
escape_name(
|
||||||
|
ident.inspect(),
|
||||||
|
vis,
|
||||||
|
ident.vi.def_loc.loc.ln_begin().unwrap_or(0),
|
||||||
|
ident.vi.def_loc.loc.col_begin().unwrap_or(0),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -889,9 +900,12 @@ impl PyCodeGenerator {
|
||||||
params
|
params
|
||||||
.non_defaults
|
.non_defaults
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| p.inspect().map(|s| &s[..]).unwrap_or("_"))
|
.map(|p| (p.inspect().map(|s| &s[..]).unwrap_or("_"), &p.vi))
|
||||||
.chain(if let Some(var_args) = ¶ms.var_params {
|
.chain(if let Some(var_args) = ¶ms.var_params {
|
||||||
vec![var_args.inspect().map(|s| &s[..]).unwrap_or("_")]
|
vec![(
|
||||||
|
var_args.inspect().map(|s| &s[..]).unwrap_or("_"),
|
||||||
|
&var_args.vi,
|
||||||
|
)]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
})
|
})
|
||||||
|
@ -899,14 +913,20 @@ impl PyCodeGenerator {
|
||||||
params
|
params
|
||||||
.defaults
|
.defaults
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| p.inspect().map(|s| &s[..]).unwrap_or("_")),
|
.map(|p| (p.inspect().map(|s| &s[..]).unwrap_or("_"), &p.sig.vi)),
|
||||||
)
|
)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, s)| {
|
.map(|(i, (s, vi))| {
|
||||||
if s == "_" {
|
if s == "_" {
|
||||||
format!("_{i}")
|
format!("_{i}")
|
||||||
} else {
|
} else {
|
||||||
escape_name(s, &VisibilityModifier::Private).to_string()
|
escape_name(
|
||||||
|
s,
|
||||||
|
&VisibilityModifier::Private,
|
||||||
|
vi.def_loc.loc.ln_begin().unwrap_or(0),
|
||||||
|
vi.def_loc.loc.col_begin().unwrap_or(0),
|
||||||
|
)
|
||||||
|
.to_string()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|s| self.get_cached(&s))
|
.map(|s| self.get_cached(&s))
|
||||||
|
@ -1930,7 +1950,7 @@ impl PyCodeGenerator {
|
||||||
match param.raw.pat {
|
match param.raw.pat {
|
||||||
ParamPattern::VarName(name) => {
|
ParamPattern::VarName(name) => {
|
||||||
let ident = erg_parser::ast::Identifier::private_from_varname(name);
|
let ident = erg_parser::ast::Identifier::private_from_varname(name);
|
||||||
let ident = Identifier::bare(ident);
|
let ident = Identifier::new(ident, None, param.vi);
|
||||||
self.emit_store_instr(ident, AccessKind::Name);
|
self.emit_store_instr(ident, AccessKind::Name);
|
||||||
}
|
}
|
||||||
ParamPattern::Discard(_) => {
|
ParamPattern::Discard(_) => {
|
||||||
|
@ -2195,7 +2215,7 @@ impl PyCodeGenerator {
|
||||||
let kw = if is_py_api {
|
let kw = if is_py_api {
|
||||||
arg.keyword.content
|
arg.keyword.content
|
||||||
} else {
|
} else {
|
||||||
escape_name(&arg.keyword.content, &VisibilityModifier::Private)
|
escape_name(&arg.keyword.content, &VisibilityModifier::Private, 0, 0)
|
||||||
};
|
};
|
||||||
kws.push(ValueObj::Str(kw));
|
kws.push(ValueObj::Str(kw));
|
||||||
self.emit_expr(arg.expr);
|
self.emit_expr(arg.expr);
|
||||||
|
|
|
@ -35,6 +35,9 @@ class BoolMut(NatMut):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.value.__repr__()
|
return self.value.__repr__()
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return bool(self.value)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return self.value.__hash__()
|
return self.value.__hash__()
|
||||||
|
|
||||||
|
|
28
tests/should_ok/mangling.er
Normal file
28
tests/should_ok/mangling.er
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
for! [1, 2], i =>
|
||||||
|
print! i
|
||||||
|
|
||||||
|
assert i == 0 # Python: 2
|
||||||
|
|
||||||
|
if! True, do!:
|
||||||
|
i = "a"
|
||||||
|
print! i
|
||||||
|
|
||||||
|
assert i == 0 # Python: "a"
|
||||||
|
|
||||||
|
flg = !True
|
||||||
|
while! do! flg, do!:
|
||||||
|
i = "b"
|
||||||
|
print! i
|
||||||
|
flg.invert!()
|
||||||
|
|
||||||
|
assert i == 0 # Python: "b"
|
||||||
|
|
||||||
|
match! i:
|
||||||
|
0 =>
|
||||||
|
i = 3
|
||||||
|
print! "OK: i = \{i}"
|
||||||
|
_ => print! "Unreachable"
|
||||||
|
|
||||||
|
assert i == 0 # Python: 3
|
|
@ -112,6 +112,11 @@ fn exec_long() -> Result<(), ()> {
|
||||||
expect_success("tests/should_ok/long.er", 257)
|
expect_success("tests/should_ok/long.er", 257)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exec_mangling() -> Result<(), ()> {
|
||||||
|
expect_success("tests/should_ok/mangling.er", 0)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exec_map() -> Result<(), ()> {
|
fn exec_map() -> Result<(), ()> {
|
||||||
expect_success("tests/should_ok/map.er", 0)
|
expect_success("tests/should_ok/map.er", 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue