Implement instant block transpiling

This commit is contained in:
Shunsuke Shibayama 2022-11-28 23:45:51 +09:00
parent 4b62802b1a
commit c77bb8b336

View file

@ -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",