mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-03 05:54:33 +00:00
WIP
This commit is contained in:
parent
2283f4a3b1
commit
ed1afed052
4 changed files with 163 additions and 46 deletions
|
@ -14,9 +14,9 @@ pub mod help_messages;
|
||||||
pub mod levenshtein;
|
pub mod levenshtein;
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
pub mod opcode;
|
pub mod opcode;
|
||||||
|
pub mod opcode308;
|
||||||
pub mod opcode310;
|
pub mod opcode310;
|
||||||
pub mod opcode311;
|
pub mod opcode311;
|
||||||
pub mod opcode38;
|
|
||||||
pub mod python_util;
|
pub mod python_util;
|
||||||
pub mod serialize;
|
pub mod serialize;
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use crate::impl_u8_enum;
|
use crate::impl_u8_enum;
|
||||||
|
|
||||||
impl_u8_enum! {Opcode38;
|
impl_u8_enum! {Opcode308;
|
||||||
POP_TOP = 1,
|
POP_TOP = 1,
|
||||||
ROT_TWO = 2,
|
ROT_TWO = 2,
|
||||||
ROT_THREE = 3,
|
ROT_THREE = 3,
|
|
@ -13,9 +13,9 @@ use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::env::erg_std_path;
|
use erg_common::env::erg_std_path;
|
||||||
use erg_common::error::{ErrorDisplay, Location};
|
use erg_common::error::{ErrorDisplay, Location};
|
||||||
use erg_common::opcode::CommonOpcode;
|
use erg_common::opcode::CommonOpcode;
|
||||||
|
use erg_common::opcode308::Opcode308;
|
||||||
use erg_common::opcode310::Opcode310;
|
use erg_common::opcode310::Opcode310;
|
||||||
use erg_common::opcode311::{BinOpCode, Opcode311};
|
use erg_common::opcode311::{BinOpCode, Opcode311};
|
||||||
use erg_common::opcode38::Opcode38;
|
|
||||||
use erg_common::option_enum_unwrap;
|
use erg_common::option_enum_unwrap;
|
||||||
use erg_common::python_util::{python_version, PythonVersion};
|
use erg_common::python_util::{python_version, PythonVersion};
|
||||||
use erg_common::traits::{Locational, Stream};
|
use erg_common::traits::{Locational, Stream};
|
||||||
|
@ -335,10 +335,11 @@ impl CodeGenerator {
|
||||||
let is_nat = value.is_nat();
|
let is_nat = value.is_nat();
|
||||||
let is_bool = value.is_bool();
|
let is_bool = value.is_bool();
|
||||||
if !self.cfg.no_std {
|
if !self.cfg.no_std {
|
||||||
self.emit_push_null();
|
|
||||||
if is_bool {
|
if is_bool {
|
||||||
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::public("Bool"));
|
self.emit_load_name_instr(Identifier::public("Bool"));
|
||||||
} else if is_nat {
|
} else if is_nat {
|
||||||
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::public("Nat"));
|
self.emit_load_name_instr(Identifier::public("Nat"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,7 +356,7 @@ impl CodeGenerator {
|
||||||
self.write_arg(idx);
|
self.write_arg(idx);
|
||||||
self.stack_inc();
|
self.stack_inc();
|
||||||
if !self.cfg.no_std && is_nat {
|
if !self.cfg.no_std && is_nat {
|
||||||
self.emit_call_instr(1);
|
self.emit_call_instr(1, Name);
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,18 +741,22 @@ impl CodeGenerator {
|
||||||
if self.py_version.minor >= Some(11) {
|
if self.py_version.minor >= Some(11) {
|
||||||
self.write_instr(Opcode311::PUSH_NULL);
|
self.write_instr(Opcode311::PUSH_NULL);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.stack_inc();
|
// self.stack_inc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_call_instr(&mut self, argc: usize) {
|
fn emit_call_instr(&mut self, argc: usize, kind: AccessKind) {
|
||||||
if self.py_version.minor >= Some(11) {
|
if self.py_version.minor >= Some(11) {
|
||||||
self.write_instr(Opcode311::PRECALL);
|
self.write_instr(Opcode311::PRECALL);
|
||||||
self.write_arg(argc);
|
self.write_arg(argc);
|
||||||
self.write_instr(Opcode311::CALL);
|
self.write_instr(Opcode311::CALL);
|
||||||
self.write_arg(argc);
|
self.write_arg(argc);
|
||||||
|
// self.stack_dec();
|
||||||
} else {
|
} else {
|
||||||
self.write_instr(Opcode310::CALL_FUNCTION);
|
match kind {
|
||||||
|
AccessKind::Method => self.write_instr(Opcode310::CALL_METHOD),
|
||||||
|
_ => self.write_instr(Opcode310::CALL_FUNCTION),
|
||||||
|
}
|
||||||
self.write_arg(argc);
|
self.write_arg(argc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -761,6 +766,8 @@ impl CodeGenerator {
|
||||||
let idx = self.register_const(kws);
|
let idx = self.register_const(kws);
|
||||||
self.write_instr(Opcode311::KW_NAMES);
|
self.write_instr(Opcode311::KW_NAMES);
|
||||||
self.write_arg(idx);
|
self.write_arg(idx);
|
||||||
|
self.write_instr(Opcode311::PRECALL);
|
||||||
|
self.write_arg(argc);
|
||||||
self.write_instr(Opcode311::CALL);
|
self.write_instr(Opcode311::CALL);
|
||||||
self.write_arg(argc);
|
self.write_arg(argc);
|
||||||
} else {
|
} else {
|
||||||
|
@ -788,7 +795,12 @@ impl CodeGenerator {
|
||||||
self.emit_load_name_instr(Identifier::private("#ABCMeta"));
|
self.emit_load_name_instr(Identifier::private("#ABCMeta"));
|
||||||
let subclasses_len = 1;
|
let subclasses_len = 1;
|
||||||
self.emit_call_kw_instr(2 + subclasses_len, vec![ValueObj::from("metaclass")]);
|
self.emit_call_kw_instr(2 + subclasses_len, vec![ValueObj::from("metaclass")]);
|
||||||
self.stack_dec_n((1 + 2 + 1 + subclasses_len) - 1);
|
let sum = if self.py_version.minor >= Some(11) {
|
||||||
|
1 + 2 + subclasses_len
|
||||||
|
} else {
|
||||||
|
1 + 2 + 1 + subclasses_len
|
||||||
|
};
|
||||||
|
self.stack_dec_n(sum - 1);
|
||||||
self.emit_store_instr(def.sig.into_ident(), Name);
|
self.emit_store_instr(def.sig.into_ident(), Name);
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
}
|
}
|
||||||
|
@ -919,7 +931,7 @@ impl CodeGenerator {
|
||||||
self.write_instr(MAKE_FUNCTION);
|
self.write_instr(MAKE_FUNCTION);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
if deco_is_some {
|
if deco_is_some {
|
||||||
self.emit_call_instr(1);
|
self.emit_call_instr(1, Name);
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
}
|
}
|
||||||
// stack_dec: (<abstractmethod>) + <code obj> + <name> -> <function>
|
// stack_dec: (<abstractmethod>) + <code obj> + <name> -> <function>
|
||||||
|
@ -944,7 +956,7 @@ impl CodeGenerator {
|
||||||
self.emit_load_const(ident.inspect().clone());
|
self.emit_load_const(ident.inspect().clone());
|
||||||
// LOAD subclasses
|
// LOAD subclasses
|
||||||
let subclasses_len = self.emit_require_type(obj, *require_or_sup);
|
let subclasses_len = self.emit_require_type(obj, *require_or_sup);
|
||||||
self.emit_call_instr(2 + subclasses_len);
|
self.emit_call_instr(2 + subclasses_len, Name);
|
||||||
self.stack_dec_n((1 + 2 + subclasses_len) - 1);
|
self.stack_dec_n((1 + 2 + subclasses_len) - 1);
|
||||||
self.emit_store_instr(ident, Name);
|
self.emit_store_instr(ident, Name);
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
|
@ -1094,15 +1106,19 @@ impl CodeGenerator {
|
||||||
match &bin.op.kind {
|
match &bin.op.kind {
|
||||||
// l..<r == range(l, r)
|
// l..<r == range(l, r)
|
||||||
TokenKind::RightOpen => {
|
TokenKind::RightOpen => {
|
||||||
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::public("RightOpenRange"));
|
self.emit_load_name_instr(Identifier::public("RightOpenRange"));
|
||||||
}
|
}
|
||||||
TokenKind::LeftOpen => {
|
TokenKind::LeftOpen => {
|
||||||
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::public("LeftOpenRange"));
|
self.emit_load_name_instr(Identifier::public("LeftOpenRange"));
|
||||||
}
|
}
|
||||||
TokenKind::Closed => {
|
TokenKind::Closed => {
|
||||||
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::public("ClosedRange"));
|
self.emit_load_name_instr(Identifier::public("ClosedRange"));
|
||||||
}
|
}
|
||||||
TokenKind::Open => {
|
TokenKind::Open => {
|
||||||
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::public("OpenRange"));
|
self.emit_load_name_instr(Identifier::public("OpenRange"));
|
||||||
}
|
}
|
||||||
TokenKind::InOp => {
|
TokenKind::InOp => {
|
||||||
|
@ -1126,6 +1142,7 @@ impl CodeGenerator {
|
||||||
);
|
);
|
||||||
self.in_op_loaded = true;
|
self.in_op_loaded = true;
|
||||||
}
|
}
|
||||||
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::private("#in_operator"));
|
self.emit_load_name_instr(Identifier::private("#in_operator"));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -1133,8 +1150,12 @@ impl CodeGenerator {
|
||||||
let type_pair = TypePair::new(bin.lhs_t(), bin.rhs_t());
|
let type_pair = TypePair::new(bin.lhs_t(), bin.rhs_t());
|
||||||
self.emit_expr(*bin.lhs);
|
self.emit_expr(*bin.lhs);
|
||||||
self.emit_expr(*bin.rhs);
|
self.emit_expr(*bin.rhs);
|
||||||
|
if self.py_version.minor >= Some(11) {
|
||||||
|
self.emit_binop_instr_311(bin.op, type_pair);
|
||||||
|
} else {
|
||||||
self.emit_binop_instr_310(bin.op, type_pair);
|
self.emit_binop_instr_310(bin.op, type_pair);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_binop_instr_310(&mut self, binop: Token, type_pair: TypePair) {
|
fn emit_binop_instr_310(&mut self, binop: Token, type_pair: TypePair) {
|
||||||
let instr = match &binop.kind {
|
let instr = match &binop.kind {
|
||||||
|
@ -1198,6 +1219,81 @@ impl CodeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_binop_instr_311(&mut self, binop: Token, type_pair: TypePair) {
|
||||||
|
let instr = match &binop.kind {
|
||||||
|
TokenKind::Plus
|
||||||
|
| TokenKind::Minus
|
||||||
|
| TokenKind::Star
|
||||||
|
| TokenKind::Slash
|
||||||
|
| TokenKind::FloorDiv
|
||||||
|
| TokenKind::Pow
|
||||||
|
| TokenKind::Mod
|
||||||
|
| TokenKind::AndOp
|
||||||
|
| TokenKind::OrOp => Opcode311::BINARY_OP,
|
||||||
|
TokenKind::Less
|
||||||
|
| TokenKind::LessEq
|
||||||
|
| TokenKind::DblEq
|
||||||
|
| TokenKind::NotEq
|
||||||
|
| TokenKind::Gre
|
||||||
|
| TokenKind::GreEq => Opcode311::COMPARE_OP,
|
||||||
|
TokenKind::LeftOpen
|
||||||
|
| TokenKind::RightOpen
|
||||||
|
| TokenKind::Closed
|
||||||
|
| TokenKind::Open
|
||||||
|
| TokenKind::InOp => {
|
||||||
|
self.write_instr(Opcode311::PRECALL);
|
||||||
|
self.write_arg(2);
|
||||||
|
Opcode311::CALL
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
CompileError::feature_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
binop.loc(),
|
||||||
|
&binop.inspect().clone(),
|
||||||
|
AtomicStr::from(binop.content),
|
||||||
|
)
|
||||||
|
.write_to_stderr();
|
||||||
|
Opcode311::NOT_IMPLEMENTED
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let arg = match &binop.kind {
|
||||||
|
TokenKind::Plus => BinOpCode::Add as usize,
|
||||||
|
TokenKind::Minus => BinOpCode::Subtract as usize,
|
||||||
|
TokenKind::Star => BinOpCode::Multiply as usize,
|
||||||
|
TokenKind::Slash => BinOpCode::TrueDivide as usize,
|
||||||
|
TokenKind::FloorDiv => BinOpCode::FloorDiv as usize,
|
||||||
|
TokenKind::Pow => BinOpCode::Power as usize,
|
||||||
|
TokenKind::Mod => BinOpCode::Remainder as usize,
|
||||||
|
TokenKind::AndOp => BinOpCode::And as usize,
|
||||||
|
TokenKind::OrOp => BinOpCode::Or as usize,
|
||||||
|
TokenKind::Less => 0,
|
||||||
|
TokenKind::LessEq => 1,
|
||||||
|
TokenKind::DblEq => 2,
|
||||||
|
TokenKind::NotEq => 3,
|
||||||
|
TokenKind::Gre => 4,
|
||||||
|
TokenKind::GreEq => 5,
|
||||||
|
TokenKind::LeftOpen
|
||||||
|
| TokenKind::RightOpen
|
||||||
|
| TokenKind::Closed
|
||||||
|
| TokenKind::Open
|
||||||
|
| TokenKind::InOp => 2,
|
||||||
|
_ => type_pair as usize,
|
||||||
|
};
|
||||||
|
self.write_instr(instr);
|
||||||
|
self.write_arg(arg);
|
||||||
|
self.stack_dec();
|
||||||
|
match &binop.kind {
|
||||||
|
TokenKind::LeftOpen
|
||||||
|
| TokenKind::RightOpen
|
||||||
|
| TokenKind::Open
|
||||||
|
| TokenKind::Closed
|
||||||
|
| TokenKind::InOp => {
|
||||||
|
self.stack_dec();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_del_instr(&mut self, mut args: Args) {
|
fn emit_del_instr(&mut self, mut args: Args) {
|
||||||
let ident = enum_unwrap!(args.remove_left_or_key("obj").unwrap(), Expr::Accessor:(Accessor::Ident:(_)));
|
let ident = enum_unwrap!(args.remove_left_or_key("obj").unwrap(), Expr::Accessor:(Accessor::Ident:(_)));
|
||||||
log!(info "entered {} ({ident})", fn_name!());
|
log!(info "entered {} ({ident})", fn_name!());
|
||||||
|
@ -1490,7 +1586,7 @@ impl CodeGenerator {
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
self.emit_expr(expr);
|
self.emit_expr(expr);
|
||||||
let idx_setup_with = self.cur_block().lasti;
|
let idx_setup_with = self.cur_block().lasti;
|
||||||
self.write_instr(Opcode38::SETUP_WITH);
|
self.write_instr(Opcode308::SETUP_WITH);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
// push __exit__, __enter__() to the stack
|
// push __exit__, __enter__() to the stack
|
||||||
// self.stack_inc_n(2);
|
// self.stack_inc_n(2);
|
||||||
|
@ -1500,17 +1596,17 @@ impl CodeGenerator {
|
||||||
self.emit_store_instr(stash.clone(), Name);
|
self.emit_store_instr(stash.clone(), Name);
|
||||||
self.write_instr(POP_BLOCK);
|
self.write_instr(POP_BLOCK);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.write_instr(Opcode38::BEGIN_FINALLY);
|
self.write_instr(Opcode308::BEGIN_FINALLY);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.write_instr(Opcode38::WITH_CLEANUP_START);
|
self.write_instr(Opcode308::WITH_CLEANUP_START);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.edit_code(
|
self.edit_code(
|
||||||
idx_setup_with + 1,
|
idx_setup_with + 1,
|
||||||
(self.cur_block().lasti - idx_setup_with - 2) / 2,
|
(self.cur_block().lasti - idx_setup_with - 2) / 2,
|
||||||
);
|
);
|
||||||
self.write_instr(Opcode38::WITH_CLEANUP_FINISH);
|
self.write_instr(Opcode308::WITH_CLEANUP_FINISH);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.write_instr(Opcode38::END_FINALLY);
|
self.write_instr(Opcode308::END_FINALLY);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
self.emit_load_name_instr(stash);
|
self.emit_load_name_instr(stash);
|
||||||
}
|
}
|
||||||
|
@ -1593,7 +1689,7 @@ impl CodeGenerator {
|
||||||
}
|
}
|
||||||
self.emit_expr(var_args.expr.clone());
|
self.emit_expr(var_args.expr.clone());
|
||||||
if pos_len > 0 {
|
if pos_len > 0 {
|
||||||
self.write_instr(Opcode38::BUILD_TUPLE_UNPACK_WITH_CALL);
|
self.write_instr(Opcode308::BUILD_TUPLE_UNPACK_WITH_CALL);
|
||||||
self.write_arg(2);
|
self.write_arg(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1627,18 +1723,8 @@ impl CodeGenerator {
|
||||||
} else {
|
} else {
|
||||||
self.write_arg(1);
|
self.write_arg(1);
|
||||||
}
|
}
|
||||||
} else if self.py_version.minor >= Some(11) {
|
|
||||||
self.write_instr(Opcode311::PRECALL);
|
|
||||||
self.write_arg(argc);
|
|
||||||
self.write_instr(Opcode311::CALL);
|
|
||||||
self.write_arg(argc);
|
|
||||||
} else {
|
} else {
|
||||||
if kind.is_method() {
|
self.emit_call_instr(argc, kind);
|
||||||
self.write_instr(Opcode310::CALL_METHOD);
|
|
||||||
} else {
|
|
||||||
self.write_instr(Opcode310::CALL_FUNCTION);
|
|
||||||
}
|
|
||||||
self.write_arg(argc);
|
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -1753,7 +1839,7 @@ impl CodeGenerator {
|
||||||
other => todo!("{other}"),
|
other => todo!("{other}"),
|
||||||
}
|
}
|
||||||
if !self.cfg.no_std {
|
if !self.cfg.no_std {
|
||||||
self.emit_call_instr(1);
|
self.emit_call_instr(1, Name);
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1777,7 +1863,7 @@ impl CodeGenerator {
|
||||||
} else {
|
} else {
|
||||||
self.stack_dec_n(attrs_len - 1);
|
self.stack_dec_n(attrs_len - 1);
|
||||||
}
|
}
|
||||||
self.emit_call_instr(2);
|
self.emit_call_instr(2, Name);
|
||||||
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
|
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
|
||||||
self.stack_dec_n((1 + 2 + 0) - 1);
|
self.stack_dec_n((1 + 2 + 0) - 1);
|
||||||
let ident = Identifier::private("#rec");
|
let ident = Identifier::private("#rec");
|
||||||
|
@ -1788,7 +1874,7 @@ impl CodeGenerator {
|
||||||
for field in rec.attrs.into_iter() {
|
for field in rec.attrs.into_iter() {
|
||||||
self.emit_frameless_block(field.body.block, vec![]);
|
self.emit_frameless_block(field.body.block, vec![]);
|
||||||
}
|
}
|
||||||
self.emit_call_instr(attrs_len);
|
self.emit_call_instr(attrs_len, Name);
|
||||||
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
|
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
|
||||||
self.stack_dec_n((1 + attrs_len + 0) - 1);
|
self.stack_dec_n((1 + attrs_len + 0) - 1);
|
||||||
}
|
}
|
||||||
|
@ -2218,11 +2304,11 @@ impl CodeGenerator {
|
||||||
Some(Identifier::private("#path")),
|
Some(Identifier::private("#path")),
|
||||||
)],
|
)],
|
||||||
);
|
);
|
||||||
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(Identifier::private("#path"));
|
self.emit_load_name_instr(Identifier::private("#path"));
|
||||||
self.emit_load_method_instr(Identifier::public("append"));
|
self.emit_load_method_instr(Identifier::public("append"));
|
||||||
self.emit_load_const(erg_std_path().to_str().unwrap());
|
self.emit_load_const(erg_std_path().to_str().unwrap());
|
||||||
self.write_instr(Opcode310::CALL_METHOD);
|
self.emit_call_instr(1, Method);
|
||||||
self.write_arg(1);
|
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
self.emit_pop_top();
|
self.emit_pop_top();
|
||||||
let erg_std_mod = if self.py_version.minor >= Some(10) {
|
let erg_std_mod = if self.py_version.minor >= Some(10) {
|
||||||
|
@ -2319,7 +2405,7 @@ impl CodeGenerator {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.stack_inc();
|
self.stack_inc();
|
||||||
self.emit_call_instr(1);
|
self.emit_call_instr(1, Name);
|
||||||
}
|
}
|
||||||
self.stack_dec_n(self.cur_block().stack_len as usize);
|
self.stack_dec_n(self.cur_block().stack_len as usize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,10 @@ use std::path::Path;
|
||||||
|
|
||||||
use erg_common::impl_display_from_debug;
|
use erg_common::impl_display_from_debug;
|
||||||
use erg_common::opcode::CommonOpcode;
|
use erg_common::opcode::CommonOpcode;
|
||||||
|
use erg_common::opcode308::Opcode308;
|
||||||
use erg_common::opcode310::Opcode310;
|
use erg_common::opcode310::Opcode310;
|
||||||
use erg_common::opcode38::Opcode38;
|
use erg_common::opcode311::{BinOpCode, Opcode311};
|
||||||
use erg_common::python_util::{detect_magic_number, python_version, PythonVersion};
|
use erg_common::python_util::{detect_magic_number, PythonVersion};
|
||||||
use erg_common::serialize::*;
|
use erg_common::serialize::*;
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
|
|
||||||
|
@ -418,10 +419,12 @@ impl CodeObj {
|
||||||
ldelta = lnotab_iter.next().unwrap_or(&0);
|
ldelta = lnotab_iter.next().unwrap_or(&0);
|
||||||
}
|
}
|
||||||
if let (Some(op), Some(arg)) = (code_iter.next(), code_iter.next()) {
|
if let (Some(op), Some(arg)) = (code_iter.next(), code_iter.next()) {
|
||||||
if py_ver.unwrap_or_else(python_version).minor_is(3, 8) {
|
match py_ver.and_then(|pv| pv.minor) {
|
||||||
self.read_instr_3_8(op, arg, idx, &mut instrs);
|
Some(8) => self.read_instr_3_8(op, arg, idx, &mut instrs),
|
||||||
} else {
|
// Some(9) => self.read_instr_3_9(op, arg, idx, &mut instrs),
|
||||||
self.read_instr_3_10(op, arg, idx, &mut instrs);
|
Some(10) => self.read_instr_3_10(op, arg, idx, &mut instrs),
|
||||||
|
Some(11) => self.read_instr_3_11(op, arg, idx, &mut instrs),
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
idx += 2;
|
idx += 2;
|
||||||
line_offset += 2;
|
line_offset += 2;
|
||||||
|
@ -433,17 +436,17 @@ impl CodeObj {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_instr_3_8(&self, op: &u8, arg: &u8, idx: usize, instrs: &mut String) {
|
fn read_instr_3_8(&self, op: &u8, arg: &u8, idx: usize, instrs: &mut String) {
|
||||||
let op38 = Opcode38::from(*op);
|
let op38 = Opcode308::from(*op);
|
||||||
let s_op = op38.to_string();
|
let s_op = op38.to_string();
|
||||||
write!(instrs, "{:>15} {:<25}", idx, s_op).unwrap();
|
write!(instrs, "{:>15} {:<25}", idx, s_op).unwrap();
|
||||||
if let Ok(op) = CommonOpcode::try_from(*op) {
|
if let Ok(op) = CommonOpcode::try_from(*op) {
|
||||||
self.dump_additional_info(op, arg, idx, instrs);
|
self.dump_additional_info(op, arg, idx, instrs);
|
||||||
}
|
}
|
||||||
match op38 {
|
match op38 {
|
||||||
Opcode38::BINARY_ADD
|
Opcode308::BINARY_ADD
|
||||||
| Opcode38::BINARY_SUBTRACT
|
| Opcode308::BINARY_SUBTRACT
|
||||||
| Opcode38::BINARY_MULTIPLY
|
| Opcode308::BINARY_MULTIPLY
|
||||||
| Opcode38::BINARY_TRUE_DIVIDE => {
|
| Opcode308::BINARY_TRUE_DIVIDE => {
|
||||||
write!(instrs, "{} ({:?})", arg, TypePair::from(*arg)).unwrap();
|
write!(instrs, "{} ({:?})", arg, TypePair::from(*arg)).unwrap();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -473,6 +476,34 @@ impl CodeObj {
|
||||||
instrs.push('\n');
|
instrs.push('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_instr_3_11(&self, op: &u8, arg: &u8, idx: usize, instrs: &mut String) {
|
||||||
|
let op311 = Opcode311::from(*op);
|
||||||
|
let s_op = op311.to_string();
|
||||||
|
write!(instrs, "{:>15} {:<25}", idx, s_op).unwrap();
|
||||||
|
if let Ok(op) = CommonOpcode::try_from(*op) {
|
||||||
|
self.dump_additional_info(op, arg, idx, instrs);
|
||||||
|
}
|
||||||
|
match op311 {
|
||||||
|
Opcode311::PRECALL | Opcode311::CALL => {
|
||||||
|
write!(instrs, "{}", arg).unwrap();
|
||||||
|
}
|
||||||
|
Opcode311::KW_NAMES => {
|
||||||
|
write!(
|
||||||
|
instrs,
|
||||||
|
"{} ({})",
|
||||||
|
arg,
|
||||||
|
self.consts.get(*arg as usize).unwrap()
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Opcode311::BINARY_OP => {
|
||||||
|
write!(instrs, "{} ({:?})", arg, BinOpCode::from(*arg)).unwrap();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
instrs.push('\n');
|
||||||
|
}
|
||||||
|
|
||||||
fn dump_additional_info(&self, op: CommonOpcode, arg: &u8, idx: usize, instrs: &mut String) {
|
fn dump_additional_info(&self, op: CommonOpcode, arg: &u8, idx: usize, instrs: &mut String) {
|
||||||
match op {
|
match op {
|
||||||
CommonOpcode::COMPARE_OP => {
|
CommonOpcode::COMPARE_OP => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue