mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 21:01:10 +00:00
Implement instant block transpiling
This commit is contained in:
parent
4b62802b1a
commit
c77bb8b336
1 changed files with 43 additions and 16 deletions
|
@ -157,6 +157,7 @@ impl Transpiler {
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ScriptGenerator {
|
pub struct ScriptGenerator {
|
||||||
level: usize,
|
level: usize,
|
||||||
|
fresh_var_n: usize,
|
||||||
namedtuple_loaded: bool,
|
namedtuple_loaded: bool,
|
||||||
range_ops_loaded: bool,
|
range_ops_loaded: bool,
|
||||||
prelude: String,
|
prelude: String,
|
||||||
|
@ -166,6 +167,7 @@ impl ScriptGenerator {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
level: 0,
|
level: 0,
|
||||||
|
fresh_var_n: 0,
|
||||||
namedtuple_loaded: false,
|
namedtuple_loaded: false,
|
||||||
range_ops_loaded: false,
|
range_ops_loaded: false,
|
||||||
prelude: String::new(),
|
prelude: String::new(),
|
||||||
|
@ -283,9 +285,16 @@ impl ScriptGenerator {
|
||||||
for mut attr in rec.attrs.into_iter() {
|
for mut attr in rec.attrs.into_iter() {
|
||||||
attrs += &format!("'{}',", Self::transpile_ident(attr.sig.into_ident()));
|
attrs += &format!("'{}',", Self::transpile_ident(attr.sig.into_ident()));
|
||||||
if attr.body.block.len() > 1 {
|
if attr.body.block.len() > 1 {
|
||||||
todo!("transpile instant blocks")
|
let name = format!("instant_block_{}__", self.fresh_var_n);
|
||||||
|
self.fresh_var_n += 1;
|
||||||
|
let mut code = format!("def {name}():\n");
|
||||||
|
code += &self.transpile_block(attr.body.block, true);
|
||||||
|
self.prelude += &code;
|
||||||
|
values += &format!("{name}(),");
|
||||||
|
} else {
|
||||||
|
let expr = attr.body.block.remove(0);
|
||||||
|
values += &format!("{},", self.transpile_expr(expr));
|
||||||
}
|
}
|
||||||
values += &format!("{},", self.transpile_expr(attr.body.block.remove(0)));
|
|
||||||
}
|
}
|
||||||
attrs += "]";
|
attrs += "]";
|
||||||
values += ")";
|
values += ")";
|
||||||
|
@ -332,12 +341,18 @@ impl ScriptGenerator {
|
||||||
Expr::AttrDef(mut adef) => {
|
Expr::AttrDef(mut adef) => {
|
||||||
let mut code = format!("{} = ", self.transpile_expr(Expr::Accessor(adef.attr)));
|
let mut code = format!("{} = ", self.transpile_expr(Expr::Accessor(adef.attr)));
|
||||||
if adef.block.len() > 1 {
|
if adef.block.len() > 1 {
|
||||||
todo!("transpile instant blocks")
|
let name = format!("instant_block_{}__", self.fresh_var_n);
|
||||||
}
|
self.fresh_var_n += 1;
|
||||||
|
let mut code = format!("def {name}():\n");
|
||||||
|
code += &self.transpile_block(adef.block, true);
|
||||||
|
self.prelude += &code;
|
||||||
|
format!("{name}()")
|
||||||
|
} else {
|
||||||
let expr = adef.block.remove(0);
|
let expr = adef.block.remove(0);
|
||||||
code += &self.transpile_expr(expr);
|
code += &self.transpile_expr(expr);
|
||||||
code
|
code
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// TODO:
|
// TODO:
|
||||||
Expr::Compound(comp) => {
|
Expr::Compound(comp) => {
|
||||||
let mut code = "".to_string();
|
let mut code = "".to_string();
|
||||||
|
@ -474,27 +489,39 @@ impl ScriptGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transpile_lambda(&mut self, lambda: Lambda) -> String {
|
fn transpile_lambda(&mut self, lambda: Lambda) -> String {
|
||||||
let mut code = format!("(lambda {}:", self.transpile_params(lambda.params));
|
|
||||||
if lambda.body.len() > 1 {
|
if lambda.body.len() > 1 {
|
||||||
todo!("multi line lambda");
|
let name = format!("lambda_{}__", self.fresh_var_n);
|
||||||
}
|
self.fresh_var_n += 1;
|
||||||
|
let mut code = format!("def {name}({}):\n", self.transpile_params(lambda.params));
|
||||||
|
code += &self.transpile_block(lambda.body, true);
|
||||||
|
self.prelude += &code;
|
||||||
|
name
|
||||||
|
} else {
|
||||||
|
let mut code = format!("(lambda {}:", self.transpile_params(lambda.params));
|
||||||
code += &self.transpile_block(lambda.body, false);
|
code += &self.transpile_block(lambda.body, false);
|
||||||
code.pop(); // \n
|
code.pop(); // \n
|
||||||
code.push(')');
|
code.push(')');
|
||||||
code
|
code
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn transpile_def(&mut self, mut def: Def) -> String {
|
fn transpile_def(&mut self, mut def: Def) -> String {
|
||||||
match def.sig {
|
match def.sig {
|
||||||
Signature::Var(var) => {
|
Signature::Var(var) => {
|
||||||
let mut code = format!("{} = ", Self::transpile_ident(var.ident));
|
let mut code = format!("{} = ", Self::transpile_ident(var.ident));
|
||||||
if def.body.block.len() > 1 {
|
if def.body.block.len() > 1 {
|
||||||
todo!("transpile instant blocks")
|
let name = format!("instant_block_{}__", self.fresh_var_n);
|
||||||
}
|
self.fresh_var_n += 1;
|
||||||
|
let mut code = format!("def {name}():\n");
|
||||||
|
code += &self.transpile_block(def.body.block, true);
|
||||||
|
self.prelude += &code;
|
||||||
|
format!("{name}()")
|
||||||
|
} else {
|
||||||
let expr = def.body.block.remove(0);
|
let expr = def.body.block.remove(0);
|
||||||
code += &self.transpile_expr(expr);
|
code += &self.transpile_expr(expr);
|
||||||
code
|
code
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Signature::Subr(subr) => {
|
Signature::Subr(subr) => {
|
||||||
let mut code = format!(
|
let mut code = format!(
|
||||||
"def {}({}):\n",
|
"def {}({}):\n",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue