mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 21:01:10 +00:00
Add DefKind
This commit is contained in:
parent
1a3f204879
commit
bd17bf3299
5 changed files with 145 additions and 96 deletions
|
@ -17,6 +17,7 @@ use erg_common::{
|
||||||
switch_unreachable,
|
switch_unreachable,
|
||||||
};
|
};
|
||||||
use erg_parser::ast::DefId;
|
use erg_parser::ast::DefId;
|
||||||
|
use erg_parser::ast::DefKind;
|
||||||
use erg_type::codeobj::{CodeObj, CodeObjFlags};
|
use erg_type::codeobj::{CodeObj, CodeObjFlags};
|
||||||
use Opcode::*;
|
use Opcode::*;
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ use crate::compile::{AccessKind, Name, StoreLoadKind};
|
||||||
use crate::context::eval::eval_lit;
|
use crate::context::eval::eval_lit;
|
||||||
use crate::error::{CompileError, CompileErrors, CompileResult};
|
use crate::error::{CompileError, CompileErrors, CompileResult};
|
||||||
use crate::hir::{
|
use crate::hir::{
|
||||||
Accessor, Args, Array, AttrDef, Attribute, BinOp, Block, Call, ClassDef, DefBody, Expr,
|
Accessor, Args, Array, AttrDef, Attribute, BinOp, Block, Call, ClassDef, Def, DefBody, Expr,
|
||||||
Identifier, Lambda, Literal, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp,
|
Identifier, Lambda, Literal, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp,
|
||||||
VarSignature, HIR,
|
VarSignature, HIR,
|
||||||
};
|
};
|
||||||
|
@ -771,8 +772,73 @@ impl CodeGenerator {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_acc(&mut self, acc: Accessor) {
|
||||||
|
log!(info "entered {} ({acc})", fn_name!());
|
||||||
|
match acc {
|
||||||
|
Accessor::Ident(ident) => {
|
||||||
|
self.emit_load_name_instr(ident).unwrap_or_else(|err| {
|
||||||
|
self.errs.push(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Accessor::Attr(a) => {
|
||||||
|
let class = a.obj.ref_t().name();
|
||||||
|
let uniq_obj_name = a.obj.__name__().map(Str::rc);
|
||||||
|
// C = Class ...
|
||||||
|
// C.
|
||||||
|
// a = C.x
|
||||||
|
// ↓
|
||||||
|
// class C:
|
||||||
|
// a = x
|
||||||
|
if Some(&self.cur_block_codeobj().name[..]) != a.obj.__name__() {
|
||||||
|
self.codegen_expr(*a.obj);
|
||||||
|
self.emit_load_attr_instr(
|
||||||
|
&class,
|
||||||
|
uniq_obj_name.as_ref().map(|s| &s[..]),
|
||||||
|
a.ident,
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
self.errs.push(err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.emit_load_name_instr(a.ident).unwrap_or_else(|err| {
|
||||||
|
self.errs.push(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessor::TupleAttr(t_attr) => {
|
||||||
|
self.codegen_expr(*t_attr.obj);
|
||||||
|
self.emit_load_const(t_attr.index.value);
|
||||||
|
self.write_instr(BINARY_SUBSCR);
|
||||||
|
self.write_arg(0);
|
||||||
|
self.stack_dec();
|
||||||
|
}
|
||||||
|
Accessor::Subscr(subscr) => {
|
||||||
|
self.codegen_expr(*subscr.obj);
|
||||||
|
self.codegen_expr(*subscr.index);
|
||||||
|
self.write_instr(BINARY_SUBSCR);
|
||||||
|
self.write_arg(0);
|
||||||
|
self.stack_dec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_def(&mut self, def: Def) {
|
||||||
|
log!(info "entered {} ({})", fn_name!(), def.sig);
|
||||||
|
if def.def_kind().is_trait() {
|
||||||
|
return self.emit_trait_def(def);
|
||||||
|
}
|
||||||
|
match def.sig {
|
||||||
|
Signature::Subr(sig) => self.emit_subr_def(None, sig, def.body),
|
||||||
|
Signature::Var(sig) => self.emit_var_def(sig, def.body),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_trait_def(&mut self, def: Def) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_class_def(&mut self, class_def: ClassDef) {
|
fn emit_class_def(&mut self, class_def: ClassDef) {
|
||||||
log!(info "entered {} ({class_def})", fn_name!());
|
log!(info "entered {} ({})", fn_name!(), class_def.sig);
|
||||||
let ident = class_def.sig.ident().clone();
|
let ident = class_def.sig.ident().clone();
|
||||||
let kind = class_def.kind;
|
let kind = class_def.kind;
|
||||||
let require_or_sup = class_def.require_or_sup.clone();
|
let require_or_sup = class_def.require_or_sup.clone();
|
||||||
|
@ -794,10 +860,6 @@ impl CodeGenerator {
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _emit_trait_def() {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: use `TypeVar`, `Generic` in `typing` module
|
// NOTE: use `TypeVar`, `Generic` in `typing` module
|
||||||
// fn emit_poly_type_def(&mut self, sig: SubrSignature, body: DefBody) {}
|
// fn emit_poly_type_def(&mut self, sig: SubrSignature, body: DefBody) {}
|
||||||
|
|
||||||
|
@ -1243,7 +1305,7 @@ impl CodeGenerator {
|
||||||
let acc = enum_unwrap!(obj, Expr::Accessor);
|
let acc = enum_unwrap!(obj, Expr::Accessor);
|
||||||
let func = args.remove_left_or_key("f").unwrap();
|
let func = args.remove_left_or_key("f").unwrap();
|
||||||
self.codegen_expr(func);
|
self.codegen_expr(func);
|
||||||
self.codegen_acc(acc.clone());
|
self.emit_acc(acc.clone());
|
||||||
self.write_instr(CALL_FUNCTION);
|
self.write_instr(CALL_FUNCTION);
|
||||||
self.write_arg(1);
|
self.write_arg(1);
|
||||||
// (1 (subroutine) + argc) input objects -> 1 return object
|
// (1 (subroutine) + argc) input objects -> 1 return object
|
||||||
|
@ -1352,14 +1414,9 @@ impl CodeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Lit(lit) => {
|
Expr::Lit(lit) => self.emit_load_const(lit.value),
|
||||||
self.emit_load_const(lit.value);
|
Expr::Accessor(acc) => self.emit_acc(acc),
|
||||||
}
|
Expr::Def(def) => self.emit_def(def),
|
||||||
Expr::Accessor(acc) => self.codegen_acc(acc),
|
|
||||||
Expr::Def(def) => match def.sig {
|
|
||||||
Signature::Subr(sig) => self.emit_subr_def(None, sig, def.body),
|
|
||||||
Signature::Var(sig) => self.emit_var_def(sig, def.body),
|
|
||||||
},
|
|
||||||
Expr::ClassDef(class) => self.emit_class_def(class),
|
Expr::ClassDef(class) => self.emit_class_def(class),
|
||||||
Expr::AttrDef(attr) => self.emit_attr_def(attr),
|
Expr::AttrDef(attr) => self.emit_attr_def(attr),
|
||||||
Expr::Lambda(lambda) => self.emit_lambda(lambda),
|
Expr::Lambda(lambda) => self.emit_lambda(lambda),
|
||||||
|
@ -1413,56 +1470,6 @@ impl CodeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn codegen_acc(&mut self, acc: Accessor) {
|
|
||||||
log!(info "entered {} ({acc})", fn_name!());
|
|
||||||
match acc {
|
|
||||||
Accessor::Ident(ident) => {
|
|
||||||
self.emit_load_name_instr(ident).unwrap_or_else(|err| {
|
|
||||||
self.errs.push(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Accessor::Attr(a) => {
|
|
||||||
let class = a.obj.ref_t().name();
|
|
||||||
let uniq_obj_name = a.obj.__name__().map(Str::rc);
|
|
||||||
// C = Class ...
|
|
||||||
// C.
|
|
||||||
// a = C.x
|
|
||||||
// ↓
|
|
||||||
// class C:
|
|
||||||
// a = x
|
|
||||||
if Some(&self.cur_block_codeobj().name[..]) != a.obj.__name__() {
|
|
||||||
self.codegen_expr(*a.obj);
|
|
||||||
self.emit_load_attr_instr(
|
|
||||||
&class,
|
|
||||||
uniq_obj_name.as_ref().map(|s| &s[..]),
|
|
||||||
a.ident,
|
|
||||||
)
|
|
||||||
.unwrap_or_else(|err| {
|
|
||||||
self.errs.push(err);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
self.emit_load_name_instr(a.ident).unwrap_or_else(|err| {
|
|
||||||
self.errs.push(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessor::TupleAttr(t_attr) => {
|
|
||||||
self.codegen_expr(*t_attr.obj);
|
|
||||||
self.emit_load_const(t_attr.index.value);
|
|
||||||
self.write_instr(BINARY_SUBSCR);
|
|
||||||
self.write_arg(0);
|
|
||||||
self.stack_dec();
|
|
||||||
}
|
|
||||||
Accessor::Subscr(subscr) => {
|
|
||||||
self.codegen_expr(*subscr.obj);
|
|
||||||
self.codegen_expr(*subscr.index);
|
|
||||||
self.write_instr(BINARY_SUBSCR);
|
|
||||||
self.write_arg(0);
|
|
||||||
self.stack_dec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// forブロックなどで使う
|
/// forブロックなどで使う
|
||||||
fn codegen_frameless_block(&mut self, block: Block, params: Vec<Str>) {
|
fn codegen_frameless_block(&mut self, block: Block, params: Vec<Str>) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
|
|
|
@ -26,6 +26,7 @@ use erg_common::vis::Visibility;
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
use erg_common::{fn_name, get_hash, log};
|
use erg_common::{fn_name, get_hash, log};
|
||||||
|
|
||||||
|
use erg_parser::ast::DefKind;
|
||||||
use erg_type::typaram::TyParam;
|
use erg_type::typaram::TyParam;
|
||||||
use erg_type::value::ValueObj;
|
use erg_type::value::ValueObj;
|
||||||
use erg_type::{Predicate, TyBound, Type};
|
use erg_type::{Predicate, TyBound, Type};
|
||||||
|
@ -230,6 +231,17 @@ pub enum ContextKind {
|
||||||
Dummy,
|
Dummy,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<DefKind> for ContextKind {
|
||||||
|
fn from(kind: DefKind) -> Self {
|
||||||
|
match kind {
|
||||||
|
DefKind::Class | DefKind::Inherit => Self::Class,
|
||||||
|
DefKind::Trait | DefKind::Subsume => Self::Trait,
|
||||||
|
DefKind::StructuralTrait => Self::StructuralTrait,
|
||||||
|
DefKind::Other => Self::Instant,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ContextKind {
|
impl ContextKind {
|
||||||
pub const fn is_method_def(&self) -> bool {
|
pub const fn is_method_def(&self) -> bool {
|
||||||
matches!(self, Self::MethodDefs)
|
matches!(self, Self::MethodDefs)
|
||||||
|
|
|
@ -11,7 +11,7 @@ use erg_common::{
|
||||||
impl_stream_for_wrapper,
|
impl_stream_for_wrapper,
|
||||||
};
|
};
|
||||||
|
|
||||||
use erg_parser::ast::{fmt_lines, DefId, Params, TypeSpec, VarName};
|
use erg_parser::ast::{fmt_lines, DefId, DefKind, Params, TypeSpec, VarName};
|
||||||
use erg_parser::token::{Token, TokenKind};
|
use erg_parser::token::{Token, TokenKind};
|
||||||
|
|
||||||
use erg_type::constructors::{array, tuple};
|
use erg_type::constructors::{array, tuple};
|
||||||
|
@ -1306,6 +1306,30 @@ impl Def {
|
||||||
pub const fn new(sig: Signature, body: DefBody) -> Self {
|
pub const fn new(sig: Signature, body: DefBody) -> Self {
|
||||||
Self { sig, body }
|
Self { sig, body }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn def_kind(&self) -> DefKind {
|
||||||
|
match self.body.block.first().unwrap() {
|
||||||
|
Expr::Call(call) => match call.obj.show_acc().as_ref().map(|n| &n[..]) {
|
||||||
|
Some("Class") => DefKind::Class,
|
||||||
|
Some("Inherit") => DefKind::Inherit,
|
||||||
|
Some("Trait") => DefKind::Trait,
|
||||||
|
Some("Subsume") => DefKind::Subsume,
|
||||||
|
Some("Inheritable") => {
|
||||||
|
if let Some(Expr::Call(inner)) = call.args.get_left_or_key("Class") {
|
||||||
|
match inner.obj.show_acc().as_ref().map(|n| &n[..]) {
|
||||||
|
Some("Class") => DefKind::Class,
|
||||||
|
Some("Inherit") => DefKind::Inherit,
|
||||||
|
_ => DefKind::Other,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DefKind::Other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => DefKind::Other,
|
||||||
|
},
|
||||||
|
_ => DefKind::Other,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -564,13 +564,7 @@ impl ASTLowerer {
|
||||||
name,
|
name,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let kind = if def.is_class_def() {
|
let kind = ContextKind::from(def.def_kind());
|
||||||
ContextKind::Class
|
|
||||||
} else if def.is_trait_def() {
|
|
||||||
ContextKind::Trait
|
|
||||||
} else {
|
|
||||||
ContextKind::Instant
|
|
||||||
};
|
|
||||||
self.ctx.grow(name, kind, def.sig.vis())?;
|
self.ctx.grow(name, kind, def.sig.vis())?;
|
||||||
let res = match def.sig {
|
let res = match def.sig {
|
||||||
ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body),
|
ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body),
|
||||||
|
|
|
@ -2832,6 +2832,22 @@ impl TypeAscription {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub enum DefKind {
|
||||||
|
Class,
|
||||||
|
Inherit,
|
||||||
|
Trait,
|
||||||
|
Subsume,
|
||||||
|
StructuralTrait,
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DefKind {
|
||||||
|
pub const fn is_trait(&self) -> bool {
|
||||||
|
matches!(self, Self::Trait | Self::Subsume | Self::StructuralTrait)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct DefBody {
|
pub struct DefBody {
|
||||||
pub op: Token,
|
pub op: Token,
|
||||||
|
@ -2877,33 +2893,29 @@ impl Def {
|
||||||
matches!(&self.sig, Signature::Subr(_))
|
matches!(&self.sig, Signature::Subr(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_class_def(&self) -> bool {
|
pub fn def_kind(&self) -> DefKind {
|
||||||
match self.body.block.first().unwrap() {
|
match self.body.block.first().unwrap() {
|
||||||
Expr::Call(call)
|
Expr::Call(call) => match call.obj.get_name().map(|n| &n[..]) {
|
||||||
if call.obj.get_name().map(|n| &n[..]) == Some("Class")
|
Some("Class") => DefKind::Class,
|
||||||
|| call.obj.get_name().map(|n| &n[..]) == Some("Inherit") =>
|
Some("Inherit") => DefKind::Inherit,
|
||||||
{
|
Some("Trait") => DefKind::Trait,
|
||||||
true
|
Some("Subsume") => DefKind::Subsume,
|
||||||
}
|
Some("Inheritable") => {
|
||||||
Expr::Call(call) if call.obj.get_name().map(|n| &n[..]) == Some("Inheritable") => {
|
|
||||||
if let Some(Expr::Call(inner)) = call.args.get_left_or_key("Class") {
|
if let Some(Expr::Call(inner)) = call.args.get_left_or_key("Class") {
|
||||||
inner.obj.get_name().map(|n| &n[..]) == Some("Class")
|
match inner.obj.get_name().map(|n| &n[..]) {
|
||||||
|| inner.obj.get_name().map(|n| &n[..]) == Some("Inherit")
|
Some("Class") => DefKind::Class,
|
||||||
|
Some("Inherit") => DefKind::Inherit,
|
||||||
|
_ => DefKind::Other,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
DefKind::Other
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => DefKind::Other,
|
||||||
|
},
|
||||||
|
_ => DefKind::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_trait_def(&self) -> bool {
|
|
||||||
matches!(
|
|
||||||
self.body.block.first().unwrap(),
|
|
||||||
Expr::Call(call) if call.obj.get_name().map(|n| &n[..]) == Some("Trait")
|
|
||||||
|| call.obj.get_name().map(|n| &n[..]) == Some("Subsume")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// e.g.
|
/// e.g.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue