This commit is contained in:
Shunsuke Shibayama 2022-09-29 18:57:27 +09:00
parent e717b43c40
commit f9e35aab2d

View file

@ -343,6 +343,9 @@ pub struct CodeGenerator {
cfg: ErgConfig,
str_cache: CacheSet<str>,
prelude_loaded: bool,
record_type_loaded: bool,
module_type_loaded: bool,
abc_loaded: bool,
unit_size: usize,
units: CodeGenStack,
}
@ -353,6 +356,9 @@ impl CodeGenerator {
cfg,
str_cache: CacheSet::new(),
prelude_loaded: false,
record_type_loaded: false,
module_type_loaded: false,
abc_loaded: false,
unit_size: 0,
units: CodeGenStack::empty(),
}
@ -587,8 +593,8 @@ impl CodeGenerator {
.unwrap_or_else(|| self.register_name(escaped));
self.write_instr(IMPORT_NAME);
self.write_arg(name.idx as u8);
self.stack_inc_n(items_len);
self.stack_dec(); // (level + from_list) -> module object
self.stack_inc_n(items_len - 1);
}
fn emit_import_from_instr(&mut self, ident: Identifier) {
@ -603,26 +609,26 @@ impl CodeGenerator {
}
/// item: (name, renamed)
fn emit_import_items(
fn emit_global_import_items(
&mut self,
module: Identifier,
items: Vec<(Identifier, Option<Identifier>)>,
) {
self.emit_load_const(0);
let item_names = items
let item_name_tuple = items
.iter()
.map(|ident| ValueObj::Str(ident.0.inspect().clone()))
.collect::<Vec<_>>();
let items_len = item_names.len();
self.emit_load_const(item_names);
let items_len = item_name_tuple.len();
self.emit_load_const(item_name_tuple);
self.emit_import_name_instr(module, items_len);
for (item, renamed) in items.into_iter() {
if let Some(renamed) = renamed {
self.emit_import_from_instr(item);
self.emit_store_instr(renamed, Name);
self.emit_store_global_instr(renamed);
} else {
self.emit_import_from_instr(item.clone());
self.emit_store_instr(item, Name);
self.emit_store_global_instr(item);
}
}
}
@ -703,6 +709,20 @@ impl CodeGenerator {
}
}
/// used for importing Erg builtin objects, etc. normally, this is not used
// Ergの組み込みオブジェクトをimportするときなどに使う、通常は使わない
fn emit_store_global_instr(&mut self, ident: Identifier) {
log!(info "entered {} ({ident})", fn_name!());
let escaped = escape_name(ident);
let name = self
.local_search(&escaped, Name)
.unwrap_or_else(|| self.register_name(escaped));
let instr = Opcode::STORE_GLOBAL;
self.write_instr(instr);
self.write_arg(name.idx as u8);
self.stack_dec();
}
/// Ergの文法として、属性への代入は存在しない(必ずオブジェクトはすべての属性を初期化しなくてはならないため)
/// この関数はPythonへ落とし込むときに使う
fn store_acc(&mut self, acc: Accessor) {
@ -823,6 +843,10 @@ impl CodeGenerator {
}
fn emit_trait_def(&mut self, def: Def) {
if !self.abc_loaded {
self.load_abc();
self.abc_loaded = true;
}
self.write_instr(Opcode::LOAD_BUILD_CLASS);
self.write_arg(0);
self.stack_inc();
@ -1352,6 +1376,14 @@ impl CodeGenerator {
"for" | "for!" => self.emit_for_instr(args),
"if" | "if!" => self.emit_if_instr(args),
"match" | "match!" => self.emit_match_instr(args, true),
"import" => {
if !self.module_type_loaded {
self.load_module_type();
self.module_type_loaded = true;
}
self.emit_load_name_instr(local);
self.emit_args(args, Name);
}
_ => {
self.emit_load_name_instr(local);
self.emit_args(args, Name);
@ -1475,6 +1507,10 @@ impl CodeGenerator {
#[allow(clippy::identity_op)]
fn emit_record(&mut self, rec: Record) {
log!(info "entered {} ({rec})", fn_name!());
if !self.record_type_loaded {
self.load_record_type();
self.record_type_loaded = true;
}
let attrs_len = rec.attrs.len();
// making record type
let ident = Identifier::private(Str::ever("#NamedTuple"));
@ -1592,6 +1628,10 @@ impl CodeGenerator {
self.emit_load_const(code);
}
Expr::Compound(chunks) => {
if !self.module_type_loaded {
self.load_module_type();
self.module_type_loaded = true;
}
self.emit_frameless_block(chunks, vec![]);
}
Expr::TypeAsc(tasc) => {
@ -1841,14 +1881,12 @@ impl CodeGenerator {
}
fn load_prelude(&mut self) {
self.init_record();
self.load_abc();
self.load_module_type();
// TODO:
}
fn init_record(&mut self) {
fn load_record_type(&mut self) {
// importing namedtuple
self.emit_import_items(
self.emit_global_import_items(
Identifier::public("collections"),
vec![(
Identifier::public("namedtuple"),
@ -1859,7 +1897,7 @@ impl CodeGenerator {
}
fn load_abc(&mut self) {
self.emit_import_items(
self.emit_global_import_items(
Identifier::public("abc"),
vec![
(
@ -1875,7 +1913,7 @@ impl CodeGenerator {
}
fn load_module_type(&mut self) {
self.emit_import_items(
self.emit_global_import_items(
Identifier::public("types"),
vec![(
Identifier::public("ModuleType"),