mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-03 18:29:00 +00:00
fix: transpiler TODOs
This commit is contained in:
parent
952e6ccd2e
commit
07e37c878c
2 changed files with 91 additions and 17 deletions
|
@ -6,6 +6,7 @@ use erg_common::dict;
|
|||
use erg_common::dict::Dict as HashMap;
|
||||
use erg_common::error::MultiErrorDisplay;
|
||||
use erg_common::log;
|
||||
use erg_common::set::Set as HashSet;
|
||||
use erg_common::traits::{ExitStatus, Locational, Runnable, Stream};
|
||||
use erg_common::Str;
|
||||
|
||||
|
@ -309,6 +310,7 @@ impl Transpiler {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct PyScriptGenerator {
|
||||
globals: HashSet<String>,
|
||||
level: usize,
|
||||
fresh_var_n: usize,
|
||||
namedtuple_loaded: bool,
|
||||
|
@ -322,8 +324,9 @@ pub struct PyScriptGenerator {
|
|||
}
|
||||
|
||||
impl PyScriptGenerator {
|
||||
pub const fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
globals: HashSet::new(),
|
||||
level: 0,
|
||||
fresh_var_n: 0,
|
||||
namedtuple_loaded: false,
|
||||
|
@ -676,18 +679,20 @@ impl PyScriptGenerator {
|
|||
ParamPattern::Discard(token) => token,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
code += &format!("{}__ ", ¶m.content);
|
||||
code += &format!("{}__ ", replace_non_symbolic(¶m.content));
|
||||
code += &format!("in {}:\n", self.transpile_expr(iter));
|
||||
code += &self.transpile_block(block.body, Discard);
|
||||
code
|
||||
}
|
||||
Some("while" | "while!") => {
|
||||
let mut code = "while ".to_string();
|
||||
let cond = call.args.remove(0);
|
||||
let Expr::Lambda(mut cond) = call.args.remove(0) else {
|
||||
todo!()
|
||||
};
|
||||
let Expr::Lambda(block) = call.args.remove(0) else {
|
||||
todo!()
|
||||
};
|
||||
code += &format!("{}:\n", self.transpile_expr(cond));
|
||||
code += &format!("{}:\n", self.transpile_expr(cond.body.remove(0)));
|
||||
code += &self.transpile_block(block.body, Discard);
|
||||
code
|
||||
}
|
||||
|
@ -767,7 +772,39 @@ impl PyScriptGenerator {
|
|||
let target = arm.params.non_defaults.get(0).unwrap();
|
||||
match &target.raw.pat {
|
||||
ParamPattern::VarName(param) => {
|
||||
code += &format!("case {}__:\n", ¶m.token().content);
|
||||
let param = if ¶m.token().content == "_" {
|
||||
"_".to_string()
|
||||
} else {
|
||||
replace_non_symbolic(¶m.token().content) + "__"
|
||||
};
|
||||
match target.raw.t_spec.as_ref().map(|t| &t.t_spec) {
|
||||
Some(TypeSpec::Enum(enum_t)) => {
|
||||
let values = ValueObj::vec_from_const_args(enum_t.clone());
|
||||
let patterns = values
|
||||
.iter()
|
||||
.map(|v| v.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" | ");
|
||||
code += &format!("case ({patterns}) as {param}:\n");
|
||||
}
|
||||
Some(other) => {
|
||||
if let Some(Expr::Set(Set::Normal(set))) = &target.t_spec_as_expr {
|
||||
let patterns = set
|
||||
.elems
|
||||
.pos_args
|
||||
.iter()
|
||||
.map(|elem| self.transpile_expr(elem.expr.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" | ");
|
||||
code += &format!("case ({patterns}) as {param}:\n");
|
||||
} else {
|
||||
todo!("{other}")
|
||||
}
|
||||
}
|
||||
None => {
|
||||
code += &format!("case {param}:\n");
|
||||
}
|
||||
}
|
||||
code += &self.transpile_block(arm.body, StoreTmp(tmp.clone()));
|
||||
self.level -= 1;
|
||||
}
|
||||
|
@ -775,11 +812,12 @@ impl PyScriptGenerator {
|
|||
match target.raw.t_spec.as_ref().map(|t| &t.t_spec) {
|
||||
Some(TypeSpec::Enum(enum_t)) => {
|
||||
let values = ValueObj::vec_from_const_args(enum_t.clone());
|
||||
if values.len() == 1 {
|
||||
code += &format!("case {}:\n", values[0]);
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
let patterns = values
|
||||
.iter()
|
||||
.map(|v| v.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" | ");
|
||||
code += &format!("case {patterns}:\n");
|
||||
}
|
||||
Some(_) => todo!(),
|
||||
None => {
|
||||
|
@ -851,7 +889,7 @@ impl PyScriptGenerator {
|
|||
}
|
||||
let name = ident.inspect().to_string();
|
||||
let name = replace_non_symbolic(&name);
|
||||
if ident.vis().is_public() {
|
||||
if ident.vis().is_public() || &name == "_" {
|
||||
name
|
||||
} else {
|
||||
format!("{name}__")
|
||||
|
@ -939,11 +977,13 @@ impl PyScriptGenerator {
|
|||
let mut code = if self.level == 0 {
|
||||
"".to_string()
|
||||
} else {
|
||||
format!(
|
||||
"global {}\n{}",
|
||||
Self::transpile_ident(def.sig.ident().clone()),
|
||||
" ".repeat(self.level)
|
||||
)
|
||||
let name = Self::transpile_ident(def.sig.ident().clone());
|
||||
if self.globals.contains(&name) {
|
||||
"".to_string()
|
||||
} else {
|
||||
self.globals.insert(name.clone());
|
||||
format!("global {name}\n{}", " ".repeat(self.level))
|
||||
}
|
||||
};
|
||||
match def.sig {
|
||||
Signature::Var(var) => {
|
||||
|
@ -1152,7 +1192,7 @@ impl JsonGenerator {
|
|||
if let Some(val) = self.binds.get(&acc.var_info().def_loc) {
|
||||
val.to_string()
|
||||
} else {
|
||||
acc.to_string()
|
||||
replace_non_symbolic(&acc.to_string())
|
||||
}
|
||||
}
|
||||
Expr::Array(array) => match array {
|
||||
|
|
|
@ -36,6 +36,40 @@ fn test_transpiler_embedding() -> Result<(), ()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transpiler_embedding2() -> Result<(), ()> {
|
||||
let mut trans = Transpiler::default();
|
||||
let res = trans
|
||||
.transpile(
|
||||
"
|
||||
print!(0, end:=\"\")
|
||||
i = match [1, 2]:
|
||||
[2, 1] -> 0
|
||||
[1, 2] -> 1
|
||||
print!(i, end:=\"\")
|
||||
j = if False:
|
||||
do: 1
|
||||
do: 2
|
||||
print!(j, end:=\"\")
|
||||
for! [3, 4], i =>
|
||||
print!(i, end:=\"\")
|
||||
c = !5
|
||||
while! do! c < 7, do!:
|
||||
print!(c, end:=\"\")
|
||||
c.inc!()
|
||||
"
|
||||
.into(),
|
||||
"exec",
|
||||
)
|
||||
.map_err(|es| {
|
||||
es.errors.write_all_stderr();
|
||||
})?;
|
||||
let res = exec_py_code_with_output(res.object.code(), &[]).map_err(|_| ())?;
|
||||
assert!(res.status.success());
|
||||
assert_eq!(res.stdout, b"0123456");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_builder() -> Result<(), ()> {
|
||||
let mods = ["math", "time"];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue