mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-01 17:33:29 +00:00
Follow clippy warnings
This commit is contained in:
parent
9783813ae0
commit
d956c3f61d
34 changed files with 448 additions and 450 deletions
|
@ -146,33 +146,20 @@ impl Default for ErgConfig {
|
|||
} else {
|
||||
Input::REPL
|
||||
};
|
||||
Self::new("exec", 1, false, None, 10, input, "<module>", 2)
|
||||
Self {
|
||||
mode: "exec",
|
||||
opt_level: 1,
|
||||
dump_as_pyc: false,
|
||||
python_ver: None,
|
||||
py_server_timeout: 10,
|
||||
input,
|
||||
module: "<module>",
|
||||
verbose: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ErgConfig {
|
||||
pub const fn new(
|
||||
mode: &'static str,
|
||||
opt_level: u8,
|
||||
dump_as_pyc: bool,
|
||||
python_ver: Option<u32>,
|
||||
py_server_timeout: u64,
|
||||
input: Input,
|
||||
module: &'static str,
|
||||
verbose: u8,
|
||||
) -> Self {
|
||||
Self {
|
||||
mode,
|
||||
opt_level,
|
||||
dump_as_pyc,
|
||||
python_ver,
|
||||
py_server_timeout,
|
||||
input,
|
||||
module,
|
||||
verbose,
|
||||
}
|
||||
}
|
||||
|
||||
/// cloneのエイリアス(実際のcloneコストは低いので)
|
||||
#[inline]
|
||||
pub fn copy(&self) -> Self {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::collections::hash_map::{IntoIter, IntoValues, Iter, IterMut, Keys, Values, ValuesMut};
|
||||
use std::collections::hash_map::{IntoValues, Iter, IterMut, Keys, Values, ValuesMut};
|
||||
use std::fmt::{self, Write};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::FromIterator;
|
||||
|
@ -119,11 +119,6 @@ impl<K, V> Dict<K, V> {
|
|||
self.dict.iter()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_iter(self) -> IntoIter<K, V> {
|
||||
self.dict.into_iter()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn iter_mut(&mut self) -> IterMut<K, V> {
|
||||
self.dict.iter_mut()
|
||||
|
@ -134,6 +129,15 @@ impl<K, V> Dict<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<K, V> IntoIterator for Dict<K, V> {
|
||||
type Item = (K, V);
|
||||
type IntoIter = <FxHashMap<K, V> as IntoIterator>::IntoIter;
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.dict.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq, V> Dict<K, V> {
|
||||
#[inline]
|
||||
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
//! エラー処理に関する汎用的なコンポーネントを提供する
|
||||
use std::cmp;
|
||||
use std::fmt;
|
||||
use std::io::{stderr, BufWriter, Write};
|
||||
use std::fmt::Write as _;
|
||||
use std::io::{stderr, BufWriter, Write as _};
|
||||
|
||||
use crate::color::*;
|
||||
use crate::config::Input;
|
||||
|
@ -362,7 +363,7 @@ pub trait ErrorDisplay {
|
|||
/// As for the internal error, do not put the fn name here.
|
||||
fn caused_by(&self) -> &str;
|
||||
/// the previous error that caused this error.
|
||||
fn ref_inner(&self) -> Option<&Box<Self>>;
|
||||
fn ref_inner(&self) -> Option<&Self>;
|
||||
|
||||
fn write_to_stderr(&self) {
|
||||
let mut writer = BufWriter::new(stderr());
|
||||
|
@ -469,10 +470,12 @@ pub trait ErrorDisplay {
|
|||
} else {
|
||||
pointer += &"^".repeat(cmp::max(1, codes[i].len()));
|
||||
}
|
||||
res += &format!(
|
||||
"{lineno}{VBAR_UNICODE} {code}\n{pointer}\n",
|
||||
writeln!(
|
||||
res,
|
||||
"{lineno}{VBAR_UNICODE} {code}\n{pointer}",
|
||||
code = codes[i]
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
res + RESET
|
||||
}
|
||||
|
|
|
@ -7,13 +7,20 @@ pub fn levenshtein(lhs: &str, rhs: &str) -> usize {
|
|||
let r_len = rhs.len();
|
||||
// l_len+1 × r_len+1 array
|
||||
let mut table = vec![vec![0; r_len + 1]; l_len + 1];
|
||||
for i in 0..l_len + 1 {
|
||||
table[i][0] = i;
|
||||
}
|
||||
for i in 0..r_len + 1 {
|
||||
table[0][i] = i;
|
||||
}
|
||||
let _ = table
|
||||
.iter_mut()
|
||||
.take(l_len + 1)
|
||||
.enumerate()
|
||||
.map(|(i, row)| row[0] = i)
|
||||
.collect::<()>();
|
||||
let _ = table[0]
|
||||
.iter_mut()
|
||||
.take(r_len + 1)
|
||||
.enumerate()
|
||||
.map(|(i, elem)| *elem = i)
|
||||
.collect::<()>();
|
||||
for i1 in 0..l_len {
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i2 in 0..r_len {
|
||||
let cost = if lhs[i1] == rhs[i2] { 0 } else { 1 };
|
||||
table[i1 + 1][i2 + 1] = *[
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::collections::hash_set::{IntoIter, Iter};
|
||||
use std::collections::hash_set::Iter;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::FromIterator;
|
||||
|
@ -105,9 +105,13 @@ impl<T: Hash> Set<T> {
|
|||
pub fn iter(&self) -> Iter<'_, T> {
|
||||
self.elems.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Hash> IntoIterator for Set<T> {
|
||||
type Item = T;
|
||||
type IntoIter = <FxHashSet<T> as IntoIterator>::IntoIter;
|
||||
#[inline]
|
||||
pub fn into_iter(self) -> IntoIter<T> {
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.elems.into_iter()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,12 @@ impl Borrow<str> for Str {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for Str {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.borrow()
|
||||
}
|
||||
}
|
||||
|
||||
impl Str {
|
||||
pub const fn ever(s: &'static str) -> Self {
|
||||
Str::Static(s)
|
||||
|
@ -120,10 +126,6 @@ impl Str {
|
|||
Str::Rc(s.into())
|
||||
}
|
||||
|
||||
pub fn as_ref(&self) -> &str {
|
||||
self.borrow()
|
||||
}
|
||||
|
||||
pub fn into_rc(self) -> RcStr {
|
||||
match self {
|
||||
Str::Rc(s) => s,
|
||||
|
|
|
@ -63,6 +63,7 @@ fn dfs<T: Eq + Hash + Clone, U>(
|
|||
}
|
||||
|
||||
/// perform topological sort on a graph
|
||||
#[allow(clippy::result_unit_err)]
|
||||
pub fn tsort<T: Eq + Hash + Clone, U>(g: Graph<T, U>) -> Result<Graph<T, U>, ()> {
|
||||
let n = g.len();
|
||||
let mut idx = Vec::with_capacity(n);
|
||||
|
|
|
@ -32,7 +32,8 @@ use crate::hir::{
|
|||
use AccessKind::*;
|
||||
|
||||
fn is_python_global(name: &str) -> bool {
|
||||
match name {
|
||||
matches!(
|
||||
name,
|
||||
"ArithmeticError"
|
||||
| "AssertionError"
|
||||
| "AttributeError"
|
||||
|
@ -186,9 +187,8 @@ fn is_python_global(name: &str) -> bool {
|
|||
| "tuple"
|
||||
| "type"
|
||||
| "vars"
|
||||
| "zip" => true,
|
||||
_ => false,
|
||||
}
|
||||
| "zip"
|
||||
)
|
||||
}
|
||||
|
||||
fn convert_to_python_attr(class: &str, uniq_obj_name: Option<&str>, name: Str) -> Str {
|
||||
|
@ -732,7 +732,7 @@ impl CodeGenerator {
|
|||
self.write_arg(cellvars_len);
|
||||
opcode_flag += 8;
|
||||
}
|
||||
self.emit_load_const(name.clone());
|
||||
self.emit_load_const(name);
|
||||
self.write_instr(MAKE_FUNCTION);
|
||||
self.write_arg(opcode_flag);
|
||||
// stack_dec: <code obj> + <name> -> <function>
|
||||
|
@ -1225,6 +1225,7 @@ impl CodeGenerator {
|
|||
self.write_instr(CALL_FUNCTION);
|
||||
self.write_arg(2);
|
||||
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
|
||||
#[allow(clippy::identity_op)]
|
||||
self.stack_dec_n((1 + 2 + 0) - 1);
|
||||
let ident = Identifier::private(Str::ever("#rec"));
|
||||
self.emit_store_instr(ident, Name);
|
||||
|
@ -1237,6 +1238,7 @@ impl CodeGenerator {
|
|||
self.write_instr(CALL_FUNCTION);
|
||||
self.write_arg(attrs_len as u8);
|
||||
// (1 (subroutine) + argc + kwsc) input objects -> 1 return object
|
||||
#[allow(clippy::identity_op)]
|
||||
self.stack_dec_n((1 + attrs_len + 0) - 1);
|
||||
}
|
||||
other => {
|
||||
|
|
|
@ -33,7 +33,7 @@ impl TypeCmpCache {
|
|||
where
|
||||
SubtypePair: Borrow<Q>,
|
||||
{
|
||||
self.cache.get(pair).map(|b| *b)
|
||||
self.cache.get(pair).copied()
|
||||
}
|
||||
|
||||
pub fn register(&mut self, pair: SubtypePair, b: bool) {
|
||||
|
|
|
@ -171,15 +171,15 @@ impl Context {
|
|||
&& subr
|
||||
.non_default_params
|
||||
.iter()
|
||||
.all(|pt| self.supertype_of(&Type, &pt.typ()))
|
||||
.all(|pt| self.supertype_of(&Type, pt.typ()))
|
||||
&& subr
|
||||
.default_params
|
||||
.iter()
|
||||
.all(|pt| self.supertype_of(&Type, &pt.typ()))
|
||||
.all(|pt| self.supertype_of(&Type, pt.typ()))
|
||||
&& subr
|
||||
.var_params
|
||||
.as_ref()
|
||||
.map(|va| self.supertype_of(&Type, &va.typ()))
|
||||
.map(|va| self.supertype_of(&Type, va.typ()))
|
||||
.unwrap_or(true)
|
||||
&& self.supertype_of(&Type, &subr.return_t),
|
||||
),
|
||||
|
@ -251,20 +251,14 @@ impl Context {
|
|||
if let Some(res) = self.inquire_cache(rhs, lhs) {
|
||||
return res;
|
||||
}
|
||||
match self.classes_supertype_of(lhs, rhs) {
|
||||
(Absolutely, judge) => {
|
||||
if let (Absolutely, judge) = self.classes_supertype_of(lhs, rhs) {
|
||||
self.register_cache(rhs, lhs, judge);
|
||||
return judge;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
match self.trait_supertype_of(lhs, rhs) {
|
||||
(Absolutely, judge) => {
|
||||
if let (Absolutely, judge) = self.trait_supertype_of(lhs, rhs) {
|
||||
self.register_cache(rhs, lhs, judge);
|
||||
return judge;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
for patch in self.patches.values() {
|
||||
if let ContextKind::GluePatch(tr_inst) = &patch.kind {
|
||||
if tr_inst.sub_type.has_qvar() || tr_inst.sup_trait.has_qvar() {
|
||||
|
@ -277,13 +271,13 @@ impl Context {
|
|||
if self.supertype_of(&tr_inst.sub_type, rhs)
|
||||
&& self.subtype_of(&tr_inst.sup_trait, lhs)
|
||||
{
|
||||
self.register_cache(&rhs, &lhs, true);
|
||||
self.register_cache(rhs, lhs, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.register_cache(&rhs, &lhs, false);
|
||||
self.register_cache(rhs, lhs, false);
|
||||
false
|
||||
}
|
||||
|
||||
|
@ -620,6 +614,7 @@ impl Context {
|
|||
// if `rhs` is {S: Str | ... }, `defined_rhs` will be Str
|
||||
let (defined_rhs, _) = self.rec_get_nominal_type_ctx(rhs).unwrap();
|
||||
let super_traits = self.rec_get_nominal_super_trait_ctxs(rhs);
|
||||
#[allow(clippy::useless_conversion)]
|
||||
for (sup_trait, _) in super_traits.into_iter() {
|
||||
if self.sup_conforms(lhs, defined_rhs, sup_trait) {
|
||||
return true;
|
||||
|
@ -636,8 +631,8 @@ impl Context {
|
|||
pub(crate) fn poly_supertype_of(
|
||||
&self,
|
||||
typ: &Type,
|
||||
lparams: &Vec<TyParam>,
|
||||
rparams: &Vec<TyParam>,
|
||||
lparams: &[TyParam],
|
||||
rparams: &[TyParam],
|
||||
) -> bool {
|
||||
let (_, ctx) = self
|
||||
.rec_get_nominal_type_ctx(typ)
|
||||
|
@ -754,6 +749,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub(crate) fn into_refinement(&self, t: Type) -> RefinementType {
|
||||
match t {
|
||||
Nat => {
|
||||
|
|
|
@ -70,8 +70,7 @@ impl Context {
|
|||
fn register_type(&mut self, t: Type, ctx: Self, muty: Mutability) {
|
||||
if t.typarams_len().is_none() {
|
||||
self.register_mono_type(t, ctx, muty);
|
||||
} else {
|
||||
if t.is_class() {
|
||||
} else if t.is_class() {
|
||||
self.register_poly_class(t, ctx, muty);
|
||||
} else if t.is_trait() {
|
||||
self.register_poly_trait(t, ctx, muty);
|
||||
|
@ -79,7 +78,6 @@ impl Context {
|
|||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn register_mono_type(&mut self, t: Type, ctx: Self, muty: Mutability) {
|
||||
if self.mono_types.contains_key(&t.name()) {
|
||||
|
@ -218,7 +216,7 @@ impl Context {
|
|||
static_instance("R", Type)
|
||||
},
|
||||
);
|
||||
eq.register_decl("__eq__", op_t.clone(), Public);
|
||||
eq.register_decl("__eq__", op_t, Public);
|
||||
let mut partial_ord = Self::poly_trait(
|
||||
"PartialOrd",
|
||||
vec![PS::t("R", WithDefault)],
|
||||
|
@ -233,7 +231,7 @@ impl Context {
|
|||
static_instance("R", Type)
|
||||
},
|
||||
);
|
||||
partial_ord.register_decl("__lt__", op_t.clone(), Public);
|
||||
partial_ord.register_decl("__lt__", op_t, Public);
|
||||
let ord = Self::mono_trait(
|
||||
"Ord",
|
||||
vec![poly_trait("Eq", vec![]), poly_trait("PartialOrd", vec![])],
|
||||
|
@ -270,7 +268,7 @@ impl Context {
|
|||
seq.register_decl("get", t, Public);
|
||||
let params = vec![PS::t("T", NonDefault)];
|
||||
let input = Self::poly_trait("Input", params.clone(), vec![], Self::TOP_LEVEL);
|
||||
let output = Self::poly_trait("Output", params.clone(), vec![], Self::TOP_LEVEL);
|
||||
let output = Self::poly_trait("Output", params, vec![], Self::TOP_LEVEL);
|
||||
let r = mono_q("R");
|
||||
let r_bound = static_instance("R", Type);
|
||||
let params = vec![PS::t("R", WithDefault)];
|
||||
|
@ -310,13 +308,13 @@ impl Context {
|
|||
mul.register_decl("MulO", Type, Public);
|
||||
let mut div = Self::poly_trait(
|
||||
"Div",
|
||||
params.clone(),
|
||||
params,
|
||||
vec![poly_trait("Output", vec![ty_tp(mono_q("R"))])],
|
||||
Self::TOP_LEVEL,
|
||||
);
|
||||
let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "DivO"));
|
||||
let self_bound = subtypeof(mono_q("Self"), poly_trait("Div", ty_params.clone()));
|
||||
let op_t = quant(op_t, set! {r_bound.clone(), self_bound});
|
||||
let op_t = quant(op_t, set! {r_bound, self_bound});
|
||||
div.register_decl("__div__", op_t, Public);
|
||||
div.register_decl("DivO", Type, Public);
|
||||
self.register_type(trait_("Named"), named, Const);
|
||||
|
@ -609,7 +607,7 @@ impl Context {
|
|||
let m = mono_q_tp("M");
|
||||
let array_t = array(mono_q("T"), n.clone());
|
||||
let t = fn_met(
|
||||
array_t.clone(),
|
||||
array_t,
|
||||
vec![param_t("rhs", array(mono_q("T"), m.clone()))],
|
||||
None,
|
||||
vec![],
|
||||
|
@ -622,8 +620,8 @@ impl Context {
|
|||
array_.register_impl("concat", t, Immutable, Public);
|
||||
let n = mono_q_tp("N");
|
||||
let array_inner = mono_q("T");
|
||||
let array_t = array(array_inner.clone(), n.clone());
|
||||
let proj_t = mono_proj(array_inner.clone(), "ImmutType");
|
||||
let array_t = array(array_inner.clone(), n);
|
||||
let proj_t = mono_proj(array_inner, "ImmutType");
|
||||
let t = fn_met(
|
||||
array_t.clone(),
|
||||
vec![param_t(
|
||||
|
@ -1189,12 +1187,12 @@ impl Context {
|
|||
},
|
||||
);
|
||||
self.register_impl("__mul__", op_t, Const, Private);
|
||||
let op_t = bin_op(l.clone(), r.clone(), mono_proj(mono_q("L"), "DivO"));
|
||||
let op_t = bin_op(l.clone(), r, mono_proj(mono_q("L"), "DivO"));
|
||||
let op_t = quant(
|
||||
op_t,
|
||||
set! {
|
||||
static_instance("R", Type),
|
||||
subtypeof(l, poly_trait("Mul", params.clone()))
|
||||
subtypeof(l, poly_trait("Mul", params))
|
||||
},
|
||||
);
|
||||
self.register_impl("__div__", op_t, Const, Private);
|
||||
|
@ -1223,7 +1221,7 @@ impl Context {
|
|||
self.register_impl("__or__", bin_op(Bool, Bool, Bool), Const, Private);
|
||||
let t = mono_q("T");
|
||||
let op_t = bin_op(t.clone(), t.clone(), range(t.clone()));
|
||||
let op_t = quant(op_t, set! {subtypeof(t.clone(), trait_("Ord"))});
|
||||
let op_t = quant(op_t, set! {subtypeof(t, trait_("Ord"))});
|
||||
self.register_decl("__rng__", op_t.clone(), Private);
|
||||
self.register_decl("__lorng__", op_t.clone(), Private);
|
||||
self.register_decl("__rorng__", op_t.clone(), Private);
|
||||
|
|
|
@ -171,7 +171,7 @@ impl Context {
|
|||
.collect::<Vec<_>>();
|
||||
let mut return_t = branch_ts[0].typ().return_t().unwrap().clone();
|
||||
for arg_t in branch_ts.iter().skip(1) {
|
||||
return_t = self.rec_union(&return_t, &arg_t.typ().return_t().unwrap());
|
||||
return_t = self.rec_union(&return_t, arg_t.typ().return_t().unwrap());
|
||||
}
|
||||
let param_ty = ParamTy::anonymous(match_target_expr_t.clone());
|
||||
let param_ts = [vec![param_ty], branch_ts.to_vec()].concat();
|
||||
|
@ -520,8 +520,7 @@ impl Context {
|
|||
Type::Subr(subr) => {
|
||||
let callee = if let Some(name) = method_name {
|
||||
let attr = hir::Attribute::new(obj.clone(), name.clone(), Type::Ellipsis);
|
||||
let acc = hir::Expr::Accessor(hir::Accessor::Attr(attr));
|
||||
acc
|
||||
hir::Expr::Accessor(hir::Accessor::Attr(attr))
|
||||
} else {
|
||||
obj.clone()
|
||||
};
|
||||
|
@ -668,7 +667,7 @@ impl Context {
|
|||
&self,
|
||||
callee: &hir::Expr,
|
||||
arg: &hir::KwArg,
|
||||
default_params: &Vec<ParamTy>,
|
||||
default_params: &[ParamTy],
|
||||
passed_params: &mut Set<Str>,
|
||||
) -> TyCheckResult<()> {
|
||||
let arg_t = arg.expr.ref_t();
|
||||
|
@ -744,7 +743,7 @@ impl Context {
|
|||
);
|
||||
self.substitute_call(obj, method_name, &instance, pos_args, kw_args)?;
|
||||
log!(info "Substituted:\ninstance: {instance}");
|
||||
let res = self.eval.eval_t_params(instance, &self, self.level)?;
|
||||
let res = self.eval.eval_t_params(instance, self, self.level)?;
|
||||
log!(info "Params evaluated:\nres: {res}\n");
|
||||
self.propagate(&res, obj)?;
|
||||
log!(info "Propagated:\nres: {res}\n");
|
||||
|
@ -981,7 +980,7 @@ impl Context {
|
|||
ctx.super_classes
|
||||
.iter()
|
||||
.chain(ctx.super_traits.iter())
|
||||
.map(|sup| self.rec_get_nominal_type_ctx(&sup).unwrap()),
|
||||
.map(|sup| self.rec_get_nominal_type_ctx(sup).unwrap()),
|
||||
)
|
||||
} else {
|
||||
todo!("{t} not found")
|
||||
|
|
|
@ -103,7 +103,7 @@ impl TyVarContext {
|
|||
params: Vec<TyParam>,
|
||||
ctx: &Context,
|
||||
) -> Type {
|
||||
if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(&name) {
|
||||
if let Some(temp_defaults) = ctx.rec_get_const_param_defaults(name) {
|
||||
let (_, ctx) = ctx
|
||||
.rec_get_nominal_type_ctx(&poly_trait(name.clone(), params.clone()))
|
||||
.unwrap_or_else(|| panic!("{} not found", name));
|
||||
|
@ -123,7 +123,7 @@ impl TyVarContext {
|
|||
.collect();
|
||||
let mut inst_defaults = vec![];
|
||||
for template in temp_defaults
|
||||
.into_iter()
|
||||
.iter()
|
||||
.take(defined_params_len - given_params_len)
|
||||
{
|
||||
let tp = self.instantiate_const_template(&tvar_name, name, template);
|
||||
|
@ -197,8 +197,7 @@ impl TyVarContext {
|
|||
&named_free_var(name.clone(), self.level, constraint),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if let Some(tp) = self.typaram_instances.get(&name) {
|
||||
} else if let Some(tp) = self.typaram_instances.get(&name) {
|
||||
tp.update_constraint(constraint);
|
||||
} else {
|
||||
self.push_or_init_typaram(
|
||||
|
@ -209,7 +208,6 @@ impl TyVarContext {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn _instantiate_pred(&self, _pred: Predicate) -> Predicate {
|
||||
todo!()
|
||||
|
@ -471,7 +469,7 @@ impl Context {
|
|||
};
|
||||
if let Some(decl_pt) = opt_decl_t {
|
||||
self.sub_unify(
|
||||
&decl_pt.typ(),
|
||||
decl_pt.typ(),
|
||||
&spec_t,
|
||||
None,
|
||||
sig.t_spec.as_ref().map(|s| s.loc()),
|
||||
|
@ -530,7 +528,7 @@ impl Context {
|
|||
|
||||
pub(crate) fn instantiate_const_expr(&self, expr: &ast::ConstExpr) -> TyParam {
|
||||
match expr {
|
||||
ast::ConstExpr::Lit(lit) => TyParam::Value(eval_lit(&lit)),
|
||||
ast::ConstExpr::Lit(lit) => TyParam::Value(eval_lit(lit)),
|
||||
ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => {
|
||||
TyParam::Mono(name.inspect().clone())
|
||||
}
|
||||
|
@ -836,16 +834,14 @@ impl Context {
|
|||
pub(crate) fn instantiate(&self, quantified: Type, callee: &hir::Expr) -> TyCheckResult<Type> {
|
||||
match quantified {
|
||||
Quantified(quant) => {
|
||||
let mut tv_ctx = TyVarContext::new(self.level, quant.bounds, &self);
|
||||
let mut tv_ctx = TyVarContext::new(self.level, quant.bounds, self);
|
||||
let t = Self::instantiate_t(*quant.unbound_callable, &mut tv_ctx);
|
||||
match &t {
|
||||
Type::Subr(subr) => match subr.kind.self_t() {
|
||||
Some(l) => {
|
||||
if let Type::Subr(subr) = &t {
|
||||
if let Some(l) = subr.kind.self_t() {
|
||||
self.unify(l, callee.ref_t(), None, Some(callee.loc()))?;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
Ok(t)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! Defines `Context`.
|
||||
//!
|
||||
//! `Context` is used for type inference and type checking.
|
||||
#![allow(clippy::result_unit_err)]
|
||||
pub mod cache;
|
||||
pub mod compare;
|
||||
pub mod hint;
|
||||
|
@ -91,7 +93,7 @@ impl TyParamIdx {
|
|||
TyParam::Type(t) if t.as_ref() == target => return Some(Self::Nth(i)),
|
||||
TyParam::Type(t) if t.is_monomorphic() => {}
|
||||
TyParam::Type(inner) => {
|
||||
if let Some(inner) = Self::search(&inner, target) {
|
||||
if let Some(inner) = Self::search(inner, target) {
|
||||
return Some(Self::nested(i, inner));
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +113,7 @@ impl TyParamIdx {
|
|||
match self {
|
||||
Self::Nth(n) => {
|
||||
let tps = from.typarams();
|
||||
let tp = tps.iter().nth(n).unwrap();
|
||||
let tp = tps.get(n).unwrap();
|
||||
match tp {
|
||||
TyParam::Type(t) => *t.clone(),
|
||||
_ => todo!(),
|
||||
|
@ -328,6 +330,7 @@ impl Context {
|
|||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn with_capacity(
|
||||
name: Str,
|
||||
kind: ContextKind,
|
||||
|
|
|
@ -274,14 +274,14 @@ impl Context {
|
|||
let sub_t = if sig.ident.is_procedural() {
|
||||
proc(
|
||||
non_default_params.clone(),
|
||||
var_args.as_ref().map(|v| *(*v).clone()),
|
||||
var_args.cloned(),
|
||||
default_params.clone(),
|
||||
body_t.clone(),
|
||||
)
|
||||
} else {
|
||||
func(
|
||||
non_default_params.clone(),
|
||||
var_args.as_ref().map(|v| *(*v).clone()),
|
||||
var_args.cloned(),
|
||||
default_params.clone(),
|
||||
body_t.clone(),
|
||||
)
|
||||
|
|
|
@ -63,9 +63,9 @@ impl Context {
|
|||
pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> {
|
||||
let t = mono_q("T");
|
||||
let eq = poly_trait("Eq", vec![TyParam::t(t.clone())]);
|
||||
let bound = TyBound::subtype_of(t.clone(), eq.clone());
|
||||
let bound = TyBound::subtype_of(t.clone(), eq);
|
||||
let bounds = set! {bound};
|
||||
let unbound_t = func1(t.clone(), t.clone());
|
||||
let unbound_t = func1(t.clone(), t);
|
||||
let quantified = quant(unbound_t.clone(), bounds.clone());
|
||||
println!("quantified : {quantified}");
|
||||
let mut tv_ctx = TyVarContext::new(self.level + 1, bounds, self);
|
||||
|
|
|
@ -28,7 +28,7 @@ impl Context {
|
|||
pub const GENERIC_LEVEL: usize = usize::MAX;
|
||||
|
||||
/// 型を非依存化する
|
||||
fn _independentise<'a>(_t: Type, _ts: &[Type]) -> Type {
|
||||
fn _independentise(_t: Type, _ts: &[Type]) -> Type {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ impl Context {
|
|||
let sub = self.generalize_t_inner(sub.clone(), bounds, lazy_inits);
|
||||
let sup = self.generalize_t_inner(sup.clone(), bounds, lazy_inits);
|
||||
// let bs = sub_bs.concat(sup_bs);
|
||||
bounds.insert(TyBound::sandwiched(sub, mono_q(name.clone()), sup));
|
||||
bounds.insert(TyBound::sandwiched(sub, mono_q(name), sup));
|
||||
}
|
||||
Constraint::TypeOf(t) => {
|
||||
let t = self.generalize_t_inner(t.clone(), bounds, lazy_inits);
|
||||
|
@ -378,7 +378,7 @@ impl Context {
|
|||
pub(crate) fn deref_toplevel(&mut self, mut hir: hir::HIR) -> TyCheckResult<hir::HIR> {
|
||||
self.level = 0;
|
||||
for chunk in hir.module.iter_mut() {
|
||||
self.deref_expr_t(chunk).map_err(|e| e)?;
|
||||
self.deref_expr_t(chunk)?;
|
||||
}
|
||||
Ok(hir)
|
||||
}
|
||||
|
@ -805,7 +805,7 @@ impl Context {
|
|||
{
|
||||
self.unify(l.typ(), r.typ(), lhs_loc, rhs_loc)?;
|
||||
}
|
||||
for (l, r) in ls.var_params.as_ref().zip(rs.var_params.as_ref()) {
|
||||
if let Some((l, r)) = ls.var_params.as_ref().zip(rs.var_params.as_ref()) {
|
||||
self.unify(l.typ(), r.typ(), lhs_loc, rhs_loc)?;
|
||||
}
|
||||
for lpt in ls.default_params.iter() {
|
||||
|
@ -1051,7 +1051,7 @@ impl Context {
|
|||
rfv.update_constraint(new_constraint);
|
||||
lfv.link(maybe_sup);
|
||||
}
|
||||
return Ok(())
|
||||
Ok(())
|
||||
}
|
||||
(_, Type::FreeVar(rfv)) if rfv.is_unbound() => {
|
||||
// NOTE: cannot `borrow_mut` because of cycle reference
|
||||
|
@ -1107,7 +1107,7 @@ impl Context {
|
|||
},
|
||||
_ => {}
|
||||
}
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
(Type::FreeVar(lfv), _) if lfv.is_unbound() => {
|
||||
let lfv_ref = &mut *lfv.borrow_mut();
|
||||
|
@ -1156,7 +1156,7 @@ impl Context {
|
|||
},
|
||||
_ => {}
|
||||
}
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
(Type::FreeVar(_fv), _r) => todo!(),
|
||||
(Type::Subr(lsub), Type::Subr(rsub)) => {
|
||||
|
@ -1169,7 +1169,7 @@ impl Context {
|
|||
|(l, r)| self.unify(l.typ(), r.typ(), sub_loc, sup_loc),
|
||||
)?;
|
||||
self.unify(&lsub.return_t, &rsub.return_t, sub_loc, sup_loc)?;
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
(Type::MonoProj { .. }, _) => todo!(),
|
||||
(_, Type::MonoProj { .. }) => todo!(),
|
||||
|
|
|
@ -118,7 +118,7 @@ impl ErrorDisplay for CompileError {
|
|||
fn caused_by(&self) -> &str {
|
||||
&self.caused_by
|
||||
}
|
||||
fn ref_inner(&self) -> Option<&Box<Self>> {
|
||||
fn ref_inner(&self) -> Option<&Self> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ impl ErrorDisplay for TyCheckError {
|
|||
fn caused_by(&self) -> &str {
|
||||
&self.caused_by
|
||||
}
|
||||
fn ref_inner(&self) -> Option<&Box<Self>> {
|
||||
fn ref_inner(&self) -> Option<&Self> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,13 +176,7 @@ impl Evaluator {
|
|||
|
||||
fn eval_const_acc(&self, _acc: &Accessor, ctx: &Context) -> Option<ValueObj> {
|
||||
match _acc {
|
||||
Accessor::Local(local) => {
|
||||
if let Some(val) = ctx.rec_get_const_obj(local.inspect()) {
|
||||
Some(val.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Accessor::Local(local) => ctx.rec_get_const_obj(local.inspect()).cloned(),
|
||||
Accessor::Attr(attr) => {
|
||||
let _obj = self.eval_const_expr(&attr.obj, ctx)?;
|
||||
todo!()
|
||||
|
@ -220,7 +214,7 @@ impl Evaluator {
|
|||
if let Expr::Accessor(acc) = call.obj.as_ref() {
|
||||
match acc {
|
||||
Accessor::Local(name) if name.is_const() => {
|
||||
if let Some(ValueObj::Subr(subr)) = ctx.rec_get_const_obj(&name.inspect()) {
|
||||
if let Some(ValueObj::Subr(subr)) = ctx.rec_get_const_obj(name.inspect()) {
|
||||
let args = self.eval_args(&call.args)?;
|
||||
Some(subr.call(args))
|
||||
} else {
|
||||
|
@ -382,9 +376,7 @@ impl Evaluator {
|
|||
|
||||
fn eval_unary_tp(&self, op: OpKind, val: &TyParam) -> EvalResult<TyParam> {
|
||||
match val {
|
||||
TyParam::Value(c) => self
|
||||
.eval_unary_lit(op, c.clone())
|
||||
.map(|v| TyParam::Value(v)),
|
||||
TyParam::Value(c) => self.eval_unary_lit(op, c.clone()).map(TyParam::Value),
|
||||
TyParam::FreeVar(fv) if fv.is_linked() => self.eval_unary_tp(op, &*fv.crack()),
|
||||
e @ TyParam::Erased(_) => Ok(e.clone()),
|
||||
other => todo!("{op} {other}"),
|
||||
|
|
|
@ -703,12 +703,12 @@ impl RecordAttrs {
|
|||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Def> {
|
||||
self.0.iter()
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn into_iter(self) -> impl Iterator<Item = Def> {
|
||||
self.0.into_iter()
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Def> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Def> {
|
||||
|
@ -720,6 +720,14 @@ impl RecordAttrs {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for RecordAttrs {
|
||||
type Item = Def;
|
||||
type IntoIter = <Vec<Self::Item> as IntoIterator>::IntoIter;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Record {
|
||||
l_brace: Token,
|
||||
|
@ -772,7 +780,7 @@ pub struct BinOp {
|
|||
|
||||
impl NestedDisplay for BinOp {
|
||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
||||
write!(f, "`{}`(: {}):\n", self.op.content, self.sig_t)?;
|
||||
writeln!(f, "`{}`(: {}):", self.op.content, self.sig_t)?;
|
||||
self.lhs.fmt_nest(f, level + 1)?;
|
||||
writeln!(f)?;
|
||||
self.rhs.fmt_nest(f, level + 1)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//! defines the compiler for Erg (ergc).
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
extern crate erg_common;
|
||||
pub extern crate erg_parser;
|
||||
|
||||
|
|
|
@ -500,7 +500,7 @@ impl ASTLowerer {
|
|||
let found_body_t = block.ref_t();
|
||||
let expect_body_t = t.return_t().unwrap();
|
||||
if let Err(e) =
|
||||
self.return_t_check(sig.loc(), sig.ident.inspect(), &expect_body_t, found_body_t)
|
||||
self.return_t_check(sig.loc(), sig.ident.inspect(), expect_body_t, found_body_t)
|
||||
{
|
||||
self.errs.push(e);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! defines `Expr` (Expression, the minimum executing unit of Erg).
|
||||
use std::borrow::Borrow;
|
||||
use std::fmt;
|
||||
use std::fmt::Write as _;
|
||||
|
||||
use erg_common::error::Location;
|
||||
use erg_common::set::Set as HashSet;
|
||||
|
@ -134,7 +135,7 @@ pub struct Args {
|
|||
impl NestedDisplay for Args {
|
||||
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
|
||||
fmt_lines(self.pos_args.iter(), f, level)?;
|
||||
writeln!(f, "")?;
|
||||
writeln!(f)?;
|
||||
fmt_lines(self.kw_args.iter(), f, level)
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +505,7 @@ impl NestedDisplay for ArrayComprehension {
|
|||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||
let mut generators = String::new();
|
||||
for (name, gen) in self.generators.iter() {
|
||||
generators.push_str(&format!("{} <- {}, ", name, gen));
|
||||
write!(generators, "{} <- {}, ", name, gen).unwrap();
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
|
@ -678,8 +679,12 @@ impl RecordAttrs {
|
|||
pub fn iter(&self) -> impl Iterator<Item = &Def> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_iter(self) -> impl IntoIterator<Item = Def> {
|
||||
impl IntoIterator for RecordAttrs {
|
||||
type Item = Def;
|
||||
type IntoIter = <Vec<Def> as IntoIterator>::IntoIter;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
@ -1220,7 +1225,7 @@ pub struct ConstArgs {
|
|||
impl NestedDisplay for ConstArgs {
|
||||
fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
|
||||
fmt_lines(self.pos_args(), f, level)?;
|
||||
writeln!(f, "")?;
|
||||
writeln!(f)?;
|
||||
fmt_lines(self.kw_args(), f, level)
|
||||
}
|
||||
}
|
||||
|
@ -1713,6 +1718,7 @@ impl VarName {
|
|||
Self(Token::static_symbol(symbol))
|
||||
}
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn from_str(symbol: Str) -> Self {
|
||||
Self(Token::from_str(TokenKind::Symbol, &symbol))
|
||||
}
|
||||
|
@ -1817,7 +1823,7 @@ impl Identifier {
|
|||
}
|
||||
|
||||
pub const fn inspect(&self) -> &Str {
|
||||
&self.name.inspect()
|
||||
self.name.inspect()
|
||||
}
|
||||
|
||||
pub fn is_procedural(&self) -> bool {
|
||||
|
@ -2298,6 +2304,12 @@ impl Locational for Params {
|
|||
}
|
||||
}
|
||||
|
||||
type RawParams = (
|
||||
Vec<ParamSignature>,
|
||||
Option<Box<ParamSignature>>,
|
||||
Vec<ParamSignature>,
|
||||
Option<(Token, Token)>,
|
||||
);
|
||||
impl Params {
|
||||
pub fn new(
|
||||
non_defaults: Vec<ParamSignature>,
|
||||
|
@ -2313,14 +2325,7 @@ impl Params {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn deconstruct(
|
||||
self,
|
||||
) -> (
|
||||
Vec<ParamSignature>,
|
||||
Option<Box<ParamSignature>>,
|
||||
Vec<ParamSignature>,
|
||||
Option<(Token, Token)>,
|
||||
) {
|
||||
pub fn deconstruct(self) -> RawParams {
|
||||
(self.non_defaults, self.var_args, self.defaults, self.parens)
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ impl ErrorDisplay for ParserRunnerError {
|
|||
fn caused_by(&self) -> &str {
|
||||
""
|
||||
}
|
||||
fn ref_inner(&self) -> Option<&Box<Self>> {
|
||||
fn ref_inner(&self) -> Option<&Self> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ impl Lexer /*<'a>*/ {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn from_str(src: Str) -> Self {
|
||||
let escaped = normalize_newline(&src);
|
||||
Lexer {
|
||||
|
@ -769,7 +770,7 @@ impl Iterator for Lexer /*<'a>*/ {
|
|||
}
|
||||
None => {
|
||||
let token = self.emit_token(Illegal, "-");
|
||||
return Some(Err(LexError::simple_syntax_error(0, token.loc())));
|
||||
Some(Err(LexError::simple_syntax_error(0, token.loc())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Implements `Parser` for Erg. `Parser` parses the source code to generate `AST`,
|
||||
//! and performs type checking and other optimizations if necessary.
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
extern crate erg_common;
|
||||
|
||||
pub mod ast;
|
||||
|
|
|
@ -163,7 +163,7 @@ impl Parser {
|
|||
self.tokens.insert(0, token);
|
||||
}
|
||||
|
||||
fn stack_dec(&mut self) -> () {
|
||||
fn stack_dec(&mut self) {
|
||||
self.level -= 1;
|
||||
}
|
||||
}
|
||||
|
@ -221,8 +221,10 @@ impl ParserRunner {
|
|||
|
||||
/// Parses with default configuration
|
||||
pub fn parse_with_default_config(input: Input) -> Result<AST, ParserRunnerErrors> {
|
||||
let mut cfg = ErgConfig::default();
|
||||
cfg.input = input;
|
||||
let cfg = ErgConfig {
|
||||
input,
|
||||
..Default::default()
|
||||
};
|
||||
let mut self_ = Self::new(cfg);
|
||||
self_.parse()
|
||||
}
|
||||
|
@ -278,12 +280,11 @@ impl Parser {
|
|||
Some(t) if t.is(Indent) || t.is(Dedent) => {
|
||||
switch_unreachable!()
|
||||
}
|
||||
Some(_) => match self.try_reduce_chunk(true) {
|
||||
Ok(expr) => {
|
||||
Some(_) => {
|
||||
if let Ok(expr) = self.try_reduce_chunk(true) {
|
||||
chunks.push(expr);
|
||||
}
|
||||
Err(_) => {}
|
||||
},
|
||||
}
|
||||
_ => switch_unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -318,16 +319,13 @@ impl Parser {
|
|||
} else if t.is(EOF) {
|
||||
break;
|
||||
}
|
||||
match self.try_reduce_chunk(true) {
|
||||
Ok(expr) => {
|
||||
if let Ok(expr) = self.try_reduce_chunk(true) {
|
||||
block.push(expr);
|
||||
if self.cur_is(Dedent) {
|
||||
self.skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
_ => switch_unreachable!(),
|
||||
}
|
||||
|
@ -1281,12 +1279,9 @@ impl Parser {
|
|||
}
|
||||
let mut expr = self.try_reduce_expr(true).map_err(|_| self.stack_dec())?;
|
||||
let rparen = self.lpop();
|
||||
match &mut expr {
|
||||
Expr::Tuple(Tuple::Normal(tup)) => {
|
||||
if let Expr::Tuple(Tuple::Normal(tup)) = &mut expr {
|
||||
tup.elems.paren = Some((lparen, rparen));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
self.level -= 1;
|
||||
Ok(expr)
|
||||
}
|
||||
|
@ -1328,7 +1323,7 @@ impl Parser {
|
|||
self.level -= 1;
|
||||
let err = self.skip_and_throw_syntax_err(caused_by!());
|
||||
self.errs.push(err);
|
||||
return Err(());
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,16 @@ fn parse_test2_advanced_syntax() -> Result<(), ParserRunnerErrors> {
|
|||
|
||||
fn parse_test_from_code(file_path: &'static str) -> Result<(), ParserRunnerErrors> {
|
||||
let input = Input::File(file_path.into());
|
||||
let cfg = ErgConfig::new("exec", 1, false, None, 100, input.clone(), "<module>", 2);
|
||||
let cfg = ErgConfig {
|
||||
mode: "exec",
|
||||
opt_level: 1,
|
||||
dump_as_pyc: false,
|
||||
python_ver: None,
|
||||
py_server_timeout: 100,
|
||||
input: input.clone(),
|
||||
module: "<module>",
|
||||
verbose: 2,
|
||||
};
|
||||
let lexer = Lexer::new(input.clone());
|
||||
let mut parser = ParserRunner::new(cfg);
|
||||
match parser.parse_token_stream(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::fmt;
|
||||
use std::fmt::Write as _;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read, Write};
|
||||
use std::io::{BufReader, Read, Write as _};
|
||||
use std::path::Path;
|
||||
|
||||
use erg_common::impl_display_from_debug;
|
||||
|
@ -171,44 +172,6 @@ impl Default for CodeObj {
|
|||
}
|
||||
|
||||
impl CodeObj {
|
||||
pub fn new<S: Into<Str>>(
|
||||
argcount: u32,
|
||||
posonlyargcount: u32,
|
||||
kwonlyargcount: u32,
|
||||
nlocals: u32,
|
||||
stacksize: u32,
|
||||
flags: u32,
|
||||
code: Vec<u8>,
|
||||
consts: Vec<ValueObj>,
|
||||
names: Vec<Str>,
|
||||
varnames: Vec<Str>,
|
||||
freevars: Vec<Str>,
|
||||
cellvars: Vec<Str>,
|
||||
filename: Str,
|
||||
name: S,
|
||||
firstlineno: u32,
|
||||
lnotab: Vec<u8>,
|
||||
) -> Self {
|
||||
Self {
|
||||
argcount,
|
||||
posonlyargcount,
|
||||
kwonlyargcount,
|
||||
nlocals,
|
||||
stacksize,
|
||||
flags,
|
||||
code,
|
||||
consts,
|
||||
names,
|
||||
varnames,
|
||||
freevars,
|
||||
cellvars,
|
||||
filename,
|
||||
name: name.into(),
|
||||
firstlineno,
|
||||
lnotab,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty<S: Into<Str>, T: Into<Str>>(
|
||||
params: Vec<Str>,
|
||||
filename: S,
|
||||
|
@ -269,7 +232,7 @@ impl CodeObj {
|
|||
let name = des.deserialize_str(v, python_ver)?;
|
||||
let firstlineno = Deserializer::deserialize_u32(v);
|
||||
let lnotab = des.deserialize_bytes(v)?;
|
||||
Ok(CodeObj::new(
|
||||
Ok(CodeObj {
|
||||
argcount,
|
||||
posonlyargcount,
|
||||
kwonlyargcount,
|
||||
|
@ -286,7 +249,7 @@ impl CodeObj {
|
|||
name,
|
||||
firstlineno,
|
||||
lnotab,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn into_bytes(self, python_ver: u32) -> Vec<u8> {
|
||||
|
@ -337,54 +300,54 @@ impl CodeObj {
|
|||
tables += "Constants:\n";
|
||||
}
|
||||
for (i, obj) in self.consts.iter().enumerate() {
|
||||
tables += &format!(" {}: {}\n", i, obj);
|
||||
writeln!(tables, " {}: {}", i, obj).unwrap();
|
||||
}
|
||||
if !self.names.is_empty() {
|
||||
tables += "Names:\n";
|
||||
}
|
||||
for (i, name) in self.names.iter().enumerate() {
|
||||
tables += &format!(" {}: {}\n", i, name);
|
||||
writeln!(tables, " {}: {}", i, name).unwrap();
|
||||
}
|
||||
if !self.varnames.is_empty() {
|
||||
tables += "Varnames:\n";
|
||||
}
|
||||
for (i, varname) in self.varnames.iter().enumerate() {
|
||||
tables += &format!(" {}: {}\n", i, varname);
|
||||
writeln!(tables, " {}: {}", i, varname).unwrap();
|
||||
}
|
||||
if !self.cellvars.is_empty() {
|
||||
tables += "Cellvars:\n";
|
||||
}
|
||||
for (i, cellvar) in self.cellvars.iter().enumerate() {
|
||||
tables += &format!(" {}: {}\n", i, cellvar);
|
||||
writeln!(tables, " {}: {}", i, cellvar).unwrap();
|
||||
}
|
||||
if !self.freevars.is_empty() {
|
||||
tables += "Freevars:\n";
|
||||
}
|
||||
for (i, freevar) in self.freevars.iter().enumerate() {
|
||||
tables += &format!(" {}: {}\n", i, freevar);
|
||||
writeln!(tables, " {}: {}\n", i, freevar).unwrap();
|
||||
}
|
||||
tables
|
||||
}
|
||||
|
||||
fn attrs_info(&self) -> String {
|
||||
let mut attrs = "".to_string();
|
||||
attrs += &format!("Name: {}\n", self.name);
|
||||
attrs += &format!("FileName: {}\n", self.filename);
|
||||
attrs += &format!("Argument count: {}\n", self.argcount);
|
||||
attrs += &format!("Positional-only arguments: {}\n", self.posonlyargcount);
|
||||
attrs += &format!("Kw-only arguments: {}\n", self.kwonlyargcount);
|
||||
attrs += &format!("Number of locals: {}\n", self.nlocals);
|
||||
attrs += &format!("Stack size: {}\n", self.stacksize);
|
||||
writeln!(attrs, "Name: {}", self.name).unwrap();
|
||||
writeln!(attrs, "FileName: {}", self.filename).unwrap();
|
||||
writeln!(attrs, "Argument count: {}", self.argcount).unwrap();
|
||||
writeln!(attrs, "Positional-only arguments: {}", self.posonlyargcount).unwrap();
|
||||
writeln!(attrs, "Kw-only arguments: {}", self.kwonlyargcount).unwrap();
|
||||
writeln!(attrs, "Number of locals: {}", self.nlocals).unwrap();
|
||||
writeln!(attrs, "Stack size: {}", self.stacksize).unwrap();
|
||||
let mut flagged = "".to_string();
|
||||
for i in 0..32 {
|
||||
if (self.flags & (1 << i)) != 0 {
|
||||
let flag: CodeObjFlags = 2u32.pow(i).into();
|
||||
flagged += &format!("{:?}, ", flag);
|
||||
write!(flagged, "{:?}, ", flag).unwrap();
|
||||
}
|
||||
}
|
||||
flagged.pop();
|
||||
flagged.pop();
|
||||
attrs += &format!("Flags: {}\n", flagged);
|
||||
writeln!(attrs, "Flags: {}", flagged).unwrap();
|
||||
attrs
|
||||
}
|
||||
|
||||
|
@ -397,22 +360,22 @@ impl CodeObj {
|
|||
let mut sdelta = lnotab_iter.next().unwrap_or(&0);
|
||||
let mut ldelta = lnotab_iter.next().unwrap_or(&0);
|
||||
let mut instrs = "".to_string();
|
||||
instrs += &format!("lnotab: {:?}\n", self.lnotab);
|
||||
writeln!(instrs, "lnotab: {:?}", self.lnotab).unwrap();
|
||||
if *sdelta != 0 {
|
||||
instrs += &format!("{}:\n", lineno);
|
||||
writeln!(instrs, "{}:", lineno).unwrap();
|
||||
}
|
||||
loop {
|
||||
if *sdelta == line_offset {
|
||||
line_offset = 0;
|
||||
lineno += ldelta;
|
||||
instrs += &format!("{}:\n", lineno);
|
||||
writeln!(instrs, "{}:", lineno).unwrap();
|
||||
sdelta = 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()) {
|
||||
let op = Opcode::from(*op);
|
||||
let s_op = op.to_string();
|
||||
instrs += &format!("{:>15} {:<25}", idx, s_op);
|
||||
write!(instrs, "{:>15} {:<25}", idx, s_op).unwrap();
|
||||
match op {
|
||||
Opcode::COMPARE_OP => {
|
||||
let op = match arg {
|
||||
|
@ -424,7 +387,7 @@ impl CodeObj {
|
|||
5 => ">=",
|
||||
_ => "?",
|
||||
};
|
||||
instrs += &format!("{} ({})", arg, op);
|
||||
write!(instrs, "{} ({})", arg, op).unwrap();
|
||||
}
|
||||
Opcode::STORE_NAME
|
||||
| Opcode::LOAD_NAME
|
||||
|
@ -435,30 +398,52 @@ impl CodeObj {
|
|||
| Opcode::LOAD_METHOD
|
||||
| Opcode::IMPORT_NAME
|
||||
| Opcode::IMPORT_FROM => {
|
||||
instrs += &format!("{} ({})", arg, self.names.get(*arg as usize).unwrap());
|
||||
write!(
|
||||
instrs,
|
||||
"{} ({})",
|
||||
arg,
|
||||
self.names.get(*arg as usize).unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
Opcode::STORE_DEREF | Opcode::LOAD_DEREF => {
|
||||
instrs +=
|
||||
&format!("{} ({})", arg, self.freevars.get(*arg as usize).unwrap());
|
||||
write!(
|
||||
instrs,
|
||||
"{} ({})",
|
||||
arg,
|
||||
self.freevars.get(*arg as usize).unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
Opcode::STORE_FAST | Opcode::LOAD_FAST => {
|
||||
instrs +=
|
||||
&format!("{} ({})", arg, self.varnames.get(*arg as usize).unwrap());
|
||||
write!(
|
||||
instrs,
|
||||
"{} ({})",
|
||||
arg,
|
||||
self.varnames.get(*arg as usize).unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
Opcode::LOAD_CONST => {
|
||||
instrs += &format!("{} ({})", arg, self.consts.get(*arg as usize).unwrap());
|
||||
write!(
|
||||
instrs,
|
||||
"{} ({})",
|
||||
arg,
|
||||
self.consts.get(*arg as usize).unwrap()
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
Opcode::FOR_ITER => {
|
||||
instrs += &format!("{} (to {})", arg, idx + arg * 2 + 2);
|
||||
write!(instrs, "{} (to {})", arg, idx + arg * 2 + 2).unwrap();
|
||||
}
|
||||
Opcode::JUMP_FORWARD => {
|
||||
instrs += &format!("{} (to {})", arg, idx + arg * 2 + 2);
|
||||
write!(instrs, "{} (to {})", arg, idx + arg * 2 + 2).unwrap();
|
||||
}
|
||||
Opcode::JUMP_ABSOLUTE => {
|
||||
instrs += &format!("{} (to {})", arg, arg * 2);
|
||||
write!(instrs, "{} (to {})", arg, arg * 2).unwrap();
|
||||
}
|
||||
Opcode::POP_JUMP_IF_FALSE | Opcode::POP_JUMP_IF_TRUE => {
|
||||
instrs += &format!("{} (to {})", arg, arg * 2);
|
||||
write!(instrs, "{} (to {})", arg, arg * 2).unwrap();
|
||||
}
|
||||
Opcode::MAKE_FUNCTION => {
|
||||
let flag = match arg {
|
||||
|
@ -466,17 +451,17 @@ impl CodeObj {
|
|||
// TODO:
|
||||
_ => "",
|
||||
};
|
||||
instrs += &format!("{} {}", arg, flag);
|
||||
write!(instrs, "{} {}", arg, flag).unwrap();
|
||||
}
|
||||
// Ergでは引数で型キャストする
|
||||
Opcode::BINARY_ADD
|
||||
| Opcode::BINARY_SUBTRACT
|
||||
| Opcode::BINARY_MULTIPLY
|
||||
| Opcode::BINARY_TRUE_DIVIDE => {
|
||||
instrs += &format!("{} ({:?})", arg, TypePair::from(*arg));
|
||||
write!(instrs, "{} ({:?})", arg, TypePair::from(*arg)).unwrap();
|
||||
}
|
||||
other if other.take_arg() => {
|
||||
instrs += &format!("{}", arg);
|
||||
write!(instrs, "{}", arg).unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -492,7 +477,7 @@ impl CodeObj {
|
|||
|
||||
pub fn code_info(&self) -> String {
|
||||
let mut info = "".to_string();
|
||||
info += &format!("Disassembly of {:?}:\n", self);
|
||||
writeln!(info, "Disassembly of {:?}:", self).unwrap();
|
||||
info += &self.attrs_info();
|
||||
info += &self.tables_info();
|
||||
info += &self.instr_info();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[inline]
|
||||
|
@ -54,11 +56,15 @@ pub fn enum_t(s: Set<ValueObj>) -> Type {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn int_interval<P: Into<TyParam>, Q: Into<TyParam>>(op: IntervalOp, l: P, r: Q) -> Type {
|
||||
let l = l.into();
|
||||
let r = r.into();
|
||||
let l = l.try_into().unwrap_or_else(|l| todo!("{l}"));
|
||||
let r = r.try_into().unwrap_or_else(|r| todo!("{r}"));
|
||||
pub fn int_interval<P, PErr, Q, QErr>(op: IntervalOp, l: P, r: Q) -> Type
|
||||
where
|
||||
P: TryInto<TyParam, Error = PErr>,
|
||||
PErr: fmt::Debug,
|
||||
Q: TryInto<TyParam, Error = QErr>,
|
||||
QErr: fmt::Debug,
|
||||
{
|
||||
let l = l.try_into().unwrap_or_else(|l| todo!("{l:?}"));
|
||||
let r = r.try_into().unwrap_or_else(|r| todo!("{r:?}"));
|
||||
let name = Str::from(fresh_varname());
|
||||
let pred = match op {
|
||||
IntervalOp::LeftOpen if l == TyParam::value(NegInf) => Predicate::le(name.clone(), r),
|
||||
|
@ -165,8 +171,8 @@ pub fn func2(l: Type, r: Type, return_t: Type) -> Type {
|
|||
pub fn bin_op(l: Type, r: Type, return_t: Type) -> Type {
|
||||
nd_func(
|
||||
vec![
|
||||
ParamTy::kw(Str::ever("lhs"), l.clone()),
|
||||
ParamTy::kw(Str::ever("rhs"), r.clone()),
|
||||
ParamTy::kw(Str::ever("lhs"), l),
|
||||
ParamTy::kw(Str::ever("rhs"), r),
|
||||
],
|
||||
None,
|
||||
return_t,
|
||||
|
|
|
@ -216,7 +216,7 @@ impl Deserializer {
|
|||
let name = self.deserialize_str(v, python_ver)?;
|
||||
let firstlineno = Self::deserialize_u32(v);
|
||||
let lnotab = self.deserialize_bytes(v)?;
|
||||
Ok(ValueObj::from(CodeObj::new(
|
||||
Ok(ValueObj::from(CodeObj {
|
||||
argcount,
|
||||
posonlyargcount,
|
||||
kwonlyargcount,
|
||||
|
@ -233,7 +233,7 @@ impl Deserializer {
|
|||
name,
|
||||
firstlineno,
|
||||
lnotab,
|
||||
)))
|
||||
}))
|
||||
}
|
||||
DataTypePrefix::None => Ok(ValueObj::None),
|
||||
other => Err(DeserializeError::new(
|
||||
|
|
|
@ -212,9 +212,8 @@ impl Constraint {
|
|||
}
|
||||
|
||||
pub fn update_cyclicity(&mut self, new_cyclicity: Cyclicity) {
|
||||
match self {
|
||||
Self::Sandwiched { cyclicity, .. } => *cyclicity = cyclicity.combine(new_cyclicity),
|
||||
_ => (),
|
||||
if let Self::Sandwiched { cyclicity, .. } = self {
|
||||
*cyclicity = cyclicity.combine(new_cyclicity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//! defines `Type` (type kind).
|
||||
//!
|
||||
//! Type(コンパイラ等で使われる「型」を表現する)を定義する
|
||||
#![allow(clippy::derive_hash_xor_eq)]
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
pub mod codeobj;
|
||||
pub mod constructors;
|
||||
pub mod deserialize;
|
||||
|
@ -47,11 +49,11 @@ pub trait HasType {
|
|||
}
|
||||
#[inline]
|
||||
fn lhs_t(&self) -> &Type {
|
||||
&self.ref_t().non_default_params().unwrap()[0].typ()
|
||||
self.ref_t().non_default_params().unwrap()[0].typ()
|
||||
}
|
||||
#[inline]
|
||||
fn rhs_t(&self) -> &Type {
|
||||
&self.ref_t().non_default_params().unwrap()[1].typ()
|
||||
self.ref_t().non_default_params().unwrap()[1].typ()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -697,7 +699,7 @@ impl LimitedDisplay for SubrType {
|
|||
param.typ().limited_fmt(f, limit - 1)?;
|
||||
}
|
||||
if let Some(var_params) = &self.var_params {
|
||||
if self.non_default_params.len() != 0 {
|
||||
if !self.non_default_params.is_empty() {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "...")?;
|
||||
|
@ -1495,9 +1497,9 @@ impl HasLevel for Type {
|
|||
for pt in subr.non_default_params.iter() {
|
||||
pt.typ().update_level(level);
|
||||
}
|
||||
subr.var_params
|
||||
.as_ref()
|
||||
.map(|pt| pt.typ().update_level(level));
|
||||
if let Some(pt) = subr.var_params.as_ref() {
|
||||
pt.typ().update_level(level);
|
||||
}
|
||||
for pt in subr.default_params.iter() {
|
||||
pt.typ().update_level(level);
|
||||
}
|
||||
|
@ -1551,7 +1553,9 @@ impl HasLevel for Type {
|
|||
for pt in subr.non_default_params.iter() {
|
||||
pt.typ().lift();
|
||||
}
|
||||
subr.var_params.as_ref().map(|pt| pt.typ().lift());
|
||||
if let Some(pt) = subr.var_params.as_ref() {
|
||||
pt.typ().lift();
|
||||
}
|
||||
for pt in subr.default_params.iter() {
|
||||
pt.typ().lift();
|
||||
}
|
||||
|
@ -1892,10 +1896,7 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn is_monomorphic(&self) -> bool {
|
||||
match self.typarams_len() {
|
||||
Some(0) | None => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(self.typarams_len(), Some(0) | None)
|
||||
}
|
||||
|
||||
pub const fn is_callable(&self) -> bool {
|
||||
|
@ -2092,13 +2093,13 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn var_args(&self) -> Option<&Box<ParamTy>> {
|
||||
pub fn var_args(&self) -> Option<&ParamTy> {
|
||||
match self {
|
||||
Self::FreeVar(_) => panic!("fv"),
|
||||
Self::Subr(SubrType {
|
||||
var_params: var_args,
|
||||
..
|
||||
}) => var_args.as_ref(),
|
||||
}) => var_args.as_deref(),
|
||||
Self::Callable { param_ts: _, .. } => todo!(),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -2133,21 +2134,15 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn update_constraint(&self, new_constraint: Constraint) {
|
||||
match self {
|
||||
Self::FreeVar(fv) => {
|
||||
if let Self::FreeVar(fv) = self {
|
||||
fv.update_constraint(new_constraint);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_cyclicity(&self, new_cyclicity: Cyclicity) {
|
||||
match self {
|
||||
Self::FreeVar(fv) => {
|
||||
if let Self::FreeVar(fv) = self {
|
||||
fv.update_cyclicity(new_cyclicity);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -633,9 +633,8 @@ impl TyParam {
|
|||
}
|
||||
|
||||
pub fn update_constraint(&self, new_constraint: Constraint) {
|
||||
match self {
|
||||
Self::Type(t) => t.update_constraint(new_constraint),
|
||||
_ => {}
|
||||
if let Self::Type(t) = self {
|
||||
t.update_constraint(new_constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue