mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-01 13:11:11 +00:00
Fixed to register <builtins>
to mod_cache
This commit is contained in:
parent
f815a7df7b
commit
6f3f00a369
13 changed files with 133 additions and 83 deletions
|
@ -1,4 +1,4 @@
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::ErgConfig;
|
||||||
use erg_common::traits::{Runnable, Stream};
|
use erg_common::traits::{Runnable, Stream};
|
||||||
|
|
||||||
use erg_parser::ast::VarName;
|
use erg_parser::ast::VarName;
|
||||||
|
@ -31,25 +31,9 @@ impl HIRBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_and_cache(&mut self, var_name: VarName) -> Result<(), CompileErrors> {
|
pub fn build_and_cache(&mut self, var_name: VarName, mode: &str) -> Result<(), CompileErrors> {
|
||||||
let mut ast_builder = ASTBuilder::new(self.checker.cfg().copy());
|
let mut ast_builder = ASTBuilder::new(self.checker.cfg().copy());
|
||||||
let ast = ast_builder.build()?;
|
let ast = ast_builder.build()?;
|
||||||
let ast = Reorderer::new()
|
|
||||||
.reorder(ast)
|
|
||||||
.map_err(|errs| self.convert(errs))?;
|
|
||||||
let (hir, ctx) = self
|
|
||||||
.checker
|
|
||||||
.check(ast, "exec")
|
|
||||||
.map_err(|errs| self.convert(errs))?;
|
|
||||||
self.mod_cache.register(var_name, Some(hir), ctx);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_and_cache_main(&mut self, src: String, mode: &str) -> Result<(), CompileErrors> {
|
|
||||||
let mut cfg = self.checker.cfg().copy();
|
|
||||||
cfg.input = Input::Str(src);
|
|
||||||
let mut ast_builder = ASTBuilder::new(cfg);
|
|
||||||
let ast = ast_builder.build()?;
|
|
||||||
let ast = Reorderer::new()
|
let ast = Reorderer::new()
|
||||||
.reorder(ast)
|
.reorder(ast)
|
||||||
.map_err(|errs| self.convert(errs))?;
|
.map_err(|errs| self.convert(errs))?;
|
||||||
|
@ -57,8 +41,7 @@ impl HIRBuilder {
|
||||||
.checker
|
.checker
|
||||||
.check(ast, mode)
|
.check(ast, mode)
|
||||||
.map_err(|errs| self.convert(errs))?;
|
.map_err(|errs| self.convert(errs))?;
|
||||||
let name = VarName::from_static("<module>");
|
self.mod_cache.register(var_name, Some(hir), ctx);
|
||||||
self.mod_cache.register(name, Some(hir), ctx);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::error::MultiErrorDisplay;
|
use erg_common::error::MultiErrorDisplay;
|
||||||
use erg_common::traits::Runnable;
|
use erg_common::traits::Runnable;
|
||||||
|
|
||||||
|
@ -48,8 +48,12 @@ impl Runnable for Checker {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(&mut self, src: String) -> Result<String, TyCheckErrors> {
|
fn eval(&mut self, src: String) -> Result<String, TyCheckErrors> {
|
||||||
let mut builder = ASTBuilder::new(self.cfg().copy());
|
let cfg = ErgConfig {
|
||||||
let ast = builder.build_with_str(src)?;
|
input: Input::Str(src),
|
||||||
|
..self.cfg().copy()
|
||||||
|
};
|
||||||
|
let mut builder = ASTBuilder::new(cfg);
|
||||||
|
let ast = builder.build()?;
|
||||||
let (hir, _) = self.check(ast, "eval")?;
|
let (hir, _) = self.check(ast, "eval")?;
|
||||||
Ok(hir.to_string())
|
Ok(hir.to_string())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
//! コンパイラーを定義する
|
//! コンパイラーを定義する
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
use erg_common::traits::{Runnable, Stream};
|
use erg_common::traits::{Runnable, Stream};
|
||||||
|
use erg_parser::ast::VarName;
|
||||||
use erg_type::codeobj::CodeObj;
|
use erg_type::codeobj::CodeObj;
|
||||||
|
|
||||||
use crate::builder::HIRBuilder;
|
use crate::builder::HIRBuilder;
|
||||||
|
@ -148,8 +149,12 @@ impl Compiler {
|
||||||
|
|
||||||
pub fn compile(&mut self, src: String, mode: &str) -> Result<CodeObj, CompileErrors> {
|
pub fn compile(&mut self, src: String, mode: &str) -> Result<CodeObj, CompileErrors> {
|
||||||
log!(info "the compiling process has started.");
|
log!(info "the compiling process has started.");
|
||||||
let mut hir_builder = HIRBuilder::new(self.cfg.copy(), self.mod_cache.clone());
|
let cfg = ErgConfig {
|
||||||
hir_builder.build_and_cache_main(src, mode)?;
|
input: Input::Str(src),
|
||||||
|
..self.cfg.copy()
|
||||||
|
};
|
||||||
|
let mut hir_builder = HIRBuilder::new(cfg, self.mod_cache.clone());
|
||||||
|
hir_builder.build_and_cache(VarName::from_static("<module>"), mode)?;
|
||||||
let hir = Linker::link(self.mod_cache.clone());
|
let hir = Linker::link(self.mod_cache.clone());
|
||||||
let codeobj = self.code_generator.emit(hir);
|
let codeobj = self.code_generator.emit(hir);
|
||||||
log!(info "code object:\n{}", codeobj.code_info());
|
log!(info "code object:\n{}", codeobj.code_info());
|
||||||
|
|
|
@ -1770,7 +1770,7 @@ impl Context {
|
||||||
// ord.register_impl("__ge__", op_t, Const, Public);
|
// ord.register_impl("__ge__", op_t, Const, Public);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn init_builtins() -> Self {
|
pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) {
|
||||||
// TODO: capacityを正確に把握する
|
// TODO: capacityを正確に把握する
|
||||||
let mut ctx = Context::module("<builtins>".into(), None, 40);
|
let mut ctx = Context::module("<builtins>".into(), None, 40);
|
||||||
ctx.init_builtin_funcs();
|
ctx.init_builtin_funcs();
|
||||||
|
@ -1780,15 +1780,15 @@ impl Context {
|
||||||
ctx.init_builtin_traits();
|
ctx.init_builtin_traits();
|
||||||
ctx.init_builtin_classes();
|
ctx.init_builtin_classes();
|
||||||
ctx.init_builtin_patches();
|
ctx.init_builtin_patches();
|
||||||
ctx
|
mod_cache.register(VarName::from_static("<builtins>"), None, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_main_module(mod_cache: SharedModuleCache) -> Self {
|
pub fn new_module(mod_cache: SharedModuleCache) -> Self {
|
||||||
Context::new(
|
Context::new(
|
||||||
"<module>".into(),
|
"<module>".into(), // TODO:
|
||||||
ContextKind::Module,
|
ContextKind::Module,
|
||||||
vec![],
|
vec![],
|
||||||
Some(Context::init_builtins()),
|
None,
|
||||||
Some(mod_cache),
|
Some(mod_cache),
|
||||||
Context::TOP_LEVEL,
|
Context::TOP_LEVEL,
|
||||||
)
|
)
|
||||||
|
|
|
@ -206,7 +206,7 @@ impl Context {
|
||||||
self.validate_visibility(ident, vi, namespace)?;
|
self.validate_visibility(ident, vi, namespace)?;
|
||||||
Ok(vi.t())
|
Ok(vi.t())
|
||||||
} else {
|
} else {
|
||||||
if let Some(parent) = self.outer.as_ref() {
|
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
return parent.rec_get_var_t(ident, namespace);
|
return parent.rec_get_var_t(ident, namespace);
|
||||||
}
|
}
|
||||||
Err(TyCheckError::no_var_error(
|
Err(TyCheckError::no_var_error(
|
||||||
|
@ -267,7 +267,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: dependent type widening
|
// TODO: dependent type widening
|
||||||
if let Some(parent) = self.outer.as_ref() {
|
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
parent.rec_get_attr_t(obj, ident, namespace)
|
parent.rec_get_attr_t(obj, ident, namespace)
|
||||||
} else {
|
} else {
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
|
@ -849,7 +849,7 @@ impl Context {
|
||||||
if let Some(obj) = self.consts.get(name.inspect()) {
|
if let Some(obj) = self.consts.get(name.inspect()) {
|
||||||
Ok(obj.clone())
|
Ok(obj.clone())
|
||||||
} else {
|
} else {
|
||||||
if let Some(parent) = self.outer.as_ref() {
|
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
return parent.get_const_local(name, namespace);
|
return parent.get_const_local(name, namespace);
|
||||||
}
|
}
|
||||||
Err(TyCheckError::no_var_error(
|
Err(TyCheckError::no_var_error(
|
||||||
|
@ -883,7 +883,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: dependent type widening
|
// TODO: dependent type widening
|
||||||
if let Some(parent) = self.outer.as_ref() {
|
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
parent._get_const_attr(obj, name, namespace)
|
parent._get_const_attr(obj, name, namespace)
|
||||||
} else {
|
} else {
|
||||||
Err(TyCheckError::no_attr_error(
|
Err(TyCheckError::no_attr_error(
|
||||||
|
@ -912,7 +912,7 @@ impl Context {
|
||||||
.inspect();
|
.inspect();
|
||||||
let len = most_similar_name.len();
|
let len = most_similar_name.len();
|
||||||
if levenshtein(most_similar_name, name) >= len / 2 {
|
if levenshtein(most_similar_name, name) >= len / 2 {
|
||||||
let outer = self.outer.as_ref()?;
|
let outer = self.get_outer().or_else(|| self.get_builtins())?;
|
||||||
outer.get_similar_name(name)
|
outer.get_similar_name(name)
|
||||||
} else {
|
} else {
|
||||||
Some(most_similar_name)
|
Some(most_similar_name)
|
||||||
|
@ -1209,7 +1209,7 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
if let Some(outer) = &self.outer {
|
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
[current, outer.rec_get_trait_impls(name)].concat()
|
[current, outer.rec_get_trait_impls(name)].concat()
|
||||||
} else {
|
} else {
|
||||||
current
|
current
|
||||||
|
@ -1219,7 +1219,7 @@ impl Context {
|
||||||
pub(crate) fn _rec_get_patch(&self, name: &VarName) -> Option<&Context> {
|
pub(crate) fn _rec_get_patch(&self, name: &VarName) -> Option<&Context> {
|
||||||
if let Some(patch) = self.patches.get(name) {
|
if let Some(patch) = self.patches.get(name) {
|
||||||
Some(patch)
|
Some(patch)
|
||||||
} else if let Some(outer) = &self.outer {
|
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
outer._rec_get_patch(name)
|
outer._rec_get_patch(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1243,7 +1243,7 @@ impl Context {
|
||||||
return Some(val);
|
return Some(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(outer) = &self.outer {
|
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
outer.rec_get_const_obj(name)
|
outer.rec_get_const_obj(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1253,7 +1253,7 @@ impl Context {
|
||||||
pub(crate) fn rec_get_const_param_defaults(&self, name: &str) -> Option<&Vec<ConstTemplate>> {
|
pub(crate) fn rec_get_const_param_defaults(&self, name: &str) -> Option<&Vec<ConstTemplate>> {
|
||||||
if let Some(impls) = self.const_param_defaults.get(name) {
|
if let Some(impls) = self.const_param_defaults.get(name) {
|
||||||
Some(impls)
|
Some(impls)
|
||||||
} else if let Some(outer) = &self.outer {
|
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
outer.rec_get_const_param_defaults(name)
|
outer.rec_get_const_param_defaults(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1271,7 +1271,7 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else if let Some(outer) = &self.outer {
|
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
outer.rec_get_self_t()
|
outer.rec_get_self_t()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1281,7 +1281,7 @@ impl Context {
|
||||||
fn rec_get_mono_type(&self, name: &str) -> Option<(&Type, &Context)> {
|
fn rec_get_mono_type(&self, name: &str) -> Option<(&Type, &Context)> {
|
||||||
if let Some((t, ctx)) = self.mono_types.get(name) {
|
if let Some((t, ctx)) = self.mono_types.get(name) {
|
||||||
Some((t, ctx))
|
Some((t, ctx))
|
||||||
} else if let Some(outer) = &self.outer {
|
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
outer.rec_get_mono_type(name)
|
outer.rec_get_mono_type(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1291,7 +1291,7 @@ impl Context {
|
||||||
fn rec_get_poly_type(&self, name: &str) -> Option<(&Type, &Context)> {
|
fn rec_get_poly_type(&self, name: &str) -> Option<(&Type, &Context)> {
|
||||||
if let Some((t, ctx)) = self.poly_types.get(name) {
|
if let Some((t, ctx)) = self.poly_types.get(name) {
|
||||||
Some((t, ctx))
|
Some((t, ctx))
|
||||||
} else if let Some(outer) = &self.outer {
|
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
outer.rec_get_poly_type(name)
|
outer.rec_get_poly_type(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1302,6 +1302,7 @@ impl Context {
|
||||||
if let Some((t, ctx)) = self.mono_types.get_mut(name) {
|
if let Some((t, ctx)) = self.mono_types.get_mut(name) {
|
||||||
Some((t, ctx))
|
Some((t, ctx))
|
||||||
} else if let Some(outer) = self.outer.as_mut() {
|
} else if let Some(outer) = self.outer.as_mut() {
|
||||||
|
// builtins cannot be got as mutable
|
||||||
outer.rec_get_mut_mono_type(name)
|
outer.rec_get_mut_mono_type(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1323,7 +1324,7 @@ impl Context {
|
||||||
Some((t, ctx))
|
Some((t, ctx))
|
||||||
} else if let Some((t, ctx)) = self.poly_types.get(name) {
|
} else if let Some((t, ctx)) = self.poly_types.get(name) {
|
||||||
Some((t, ctx))
|
Some((t, ctx))
|
||||||
} else if let Some(outer) = &self.outer {
|
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
outer.rec_get_type(name)
|
outer.rec_get_type(name)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -19,7 +19,6 @@ use std::option::Option; // conflicting to Type::Option
|
||||||
|
|
||||||
use erg_common::astr::AtomicStr;
|
use erg_common::astr::AtomicStr;
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::Location;
|
|
||||||
use erg_common::impl_display_from_debug;
|
use erg_common::impl_display_from_debug;
|
||||||
use erg_common::traits::{Locational, Stream};
|
use erg_common::traits::{Locational, Stream};
|
||||||
use erg_common::vis::Visibility;
|
use erg_common::vis::Visibility;
|
||||||
|
@ -554,6 +553,23 @@ impl Context {
|
||||||
AtomicStr::arc(&self.name[..])
|
AtomicStr::arc(&self.name[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_outer(&self) -> Option<&Context> {
|
||||||
|
self.outer.as_ref().map(|x| x.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns None if self is `<builtins>`.
|
||||||
|
/// This avoids infinite loops.
|
||||||
|
pub(crate) fn get_builtins(&self) -> Option<&Context> {
|
||||||
|
// builtins中で定義した型等はmod_cacheがNoneになっている
|
||||||
|
if &self.name[..] != "<builtins>" {
|
||||||
|
self.mod_cache
|
||||||
|
.as_ref()
|
||||||
|
.map(|cache| cache.ref_ctx("<builtins>").unwrap())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn grow(
|
pub(crate) fn grow(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -567,7 +583,7 @@ impl Context {
|
||||||
};
|
};
|
||||||
log!(info "{}: current namespace: {name}", fn_name!());
|
log!(info "{}: current namespace: {name}", fn_name!());
|
||||||
self.outer = Some(Box::new(mem::take(self)));
|
self.outer = Some(Box::new(mem::take(self)));
|
||||||
self.mod_cache = self.outer.as_ref().unwrap().mod_cache.clone();
|
self.mod_cache = self.get_outer().unwrap().mod_cache.clone();
|
||||||
self.name = name.into();
|
self.name = name.into();
|
||||||
self.kind = kind;
|
self.kind = kind;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -584,7 +600,7 @@ impl Context {
|
||||||
&vi.t,
|
&vi.t,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if let Some(parent) = &mut self.outer {
|
if let Some(parent) = self.outer.as_mut() {
|
||||||
let parent = mem::take(parent);
|
let parent = mem::take(parent);
|
||||||
let ctx = mem::take(self);
|
let ctx = mem::take(self);
|
||||||
*self = *parent;
|
*self = *parent;
|
||||||
|
@ -595,12 +611,14 @@ impl Context {
|
||||||
Ok(ctx)
|
Ok(ctx)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(TyCheckErrors::from(TyCheckError::checker_bug(
|
// toplevel
|
||||||
0,
|
let ctx = mem::take(self);
|
||||||
Location::Unknown,
|
log!(info "{}: current namespace: {}", fn_name!(), self.name);
|
||||||
fn_name!(),
|
if !uninited_errs.is_empty() {
|
||||||
line!(),
|
Err(uninited_errs)
|
||||||
)))
|
} else {
|
||||||
|
Ok(ctx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ impl Context {
|
||||||
return Some((name, vi));
|
return Some((name, vi));
|
||||||
}
|
}
|
||||||
if is_const {
|
if is_const {
|
||||||
if let Some(outer) = &self.outer {
|
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||||
outer.registered_info(name, is_const)
|
outer.registered_info(name, is_const)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -871,7 +871,7 @@ impl Context {
|
||||||
..ErgConfig::default()
|
..ErgConfig::default()
|
||||||
};
|
};
|
||||||
let mut hir_builder = HIRBuilder::new(cfg, mod_cache.clone());
|
let mut hir_builder = HIRBuilder::new(cfg, mod_cache.clone());
|
||||||
if let Err(errs) = hir_builder.build_and_cache(var_name.clone()) {
|
if let Err(errs) = hir_builder.build_and_cache(var_name.clone(), "exec") {
|
||||||
errs.fmt_all_stderr();
|
errs.fmt_all_stderr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
||||||
|
|
||||||
use erg_common::astr::AtomicStr;
|
use erg_common::astr::AtomicStr;
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::error::{Location, MultiErrorDisplay};
|
use erg_common::error::{Location, MultiErrorDisplay};
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
use erg_common::traits::{Locational, Runnable, Stream};
|
use erg_common::traits::{Locational, Runnable, Stream};
|
||||||
|
@ -81,8 +81,12 @@ impl Runnable for ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(&mut self, src: String) -> Result<String, CompileErrors> {
|
fn eval(&mut self, src: String) -> Result<String, CompileErrors> {
|
||||||
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
let cfg = ErgConfig {
|
||||||
let ast = ast_builder.build_with_str(src)?;
|
input: Input::Str(src),
|
||||||
|
..self.cfg.copy()
|
||||||
|
};
|
||||||
|
let mut ast_builder = ASTBuilder::new(cfg);
|
||||||
|
let ast = ast_builder.build()?;
|
||||||
let (hir, ..) = self.lower(ast, "eval").map_err(|errs| self.convert(errs))?;
|
let (hir, ..) = self.lower(ast, "eval").map_err(|errs| self.convert(errs))?;
|
||||||
Ok(format!("{hir}"))
|
Ok(format!("{hir}"))
|
||||||
}
|
}
|
||||||
|
@ -92,7 +96,7 @@ impl ASTLowerer {
|
||||||
pub fn new_with_cache(cfg: ErgConfig, mod_cache: SharedModuleCache) -> Self {
|
pub fn new_with_cache(cfg: ErgConfig, mod_cache: SharedModuleCache) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cfg,
|
cfg,
|
||||||
ctx: Context::new_main_module(mod_cache),
|
ctx: Context::new_module(mod_cache),
|
||||||
errs: LowerErrors::empty(),
|
errs: LowerErrors::empty(),
|
||||||
warns: LowerWarnings::empty(),
|
warns: LowerWarnings::empty(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,9 @@ impl fmt::Display for SharedModuleCache {
|
||||||
|
|
||||||
impl SharedModuleCache {
|
impl SharedModuleCache {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(Shared::new(ModuleCache::new()))
|
let self_ = Self(Shared::new(ModuleCache::new()));
|
||||||
|
Context::init_builtins(&self_);
|
||||||
|
self_
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ctx<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<Rc<Context>>
|
pub fn get_ctx<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<Rc<Context>>
|
||||||
|
|
|
@ -3,14 +3,14 @@ use erg_compiler::mod_cache::SharedModuleCache;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_subtyping() -> Result<(), ()> {
|
fn test_subtyping() -> Result<(), ()> {
|
||||||
let context = Context::new_main_module(SharedModuleCache::new());
|
let context = Context::new_module(SharedModuleCache::new());
|
||||||
context.test_refinement_subtyping()?;
|
context.test_refinement_subtyping()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_instantiation_and_generalization() -> Result<(), ()> {
|
fn test_instantiation_and_generalization() -> Result<(), ()> {
|
||||||
let context = Context::new_main_module(SharedModuleCache::new());
|
let context = Context::new_module(SharedModuleCache::new());
|
||||||
context.test_instantiation_and_generalization()?;
|
context.test_instantiation_and_generalization()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,17 +25,7 @@ impl ASTBuilder {
|
||||||
let module = desugarer.desugar(module);
|
let module = desugarer.desugar(module);
|
||||||
let mut desugarer = Desugarer::new();
|
let mut desugarer = Desugarer::new();
|
||||||
let module = desugarer.desugar(module);
|
let module = desugarer.desugar(module);
|
||||||
let ast = AST::new(Str::ever(self.runner.cfg().module), module);
|
let ast = AST::new(Str::rc(self.runner.cfg().input.filename()), module);
|
||||||
Ok(ast)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_with_str(&mut self, src: String) -> Result<AST, ParserRunnerErrors> {
|
|
||||||
let module = self.runner.parse_with_str(src)?;
|
|
||||||
let mut desugarer = Desugarer::new();
|
|
||||||
let module = desugarer.desugar(module);
|
|
||||||
let mut desugarer = Desugarer::new();
|
|
||||||
let module = desugarer.desugar(module);
|
|
||||||
let ast = AST::new(Str::ever(self.runner.cfg().module), module);
|
|
||||||
Ok(ast)
|
Ok(ast)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,6 +337,20 @@ impl<T> FreeKind<T> {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn linked(&self) -> Option<&T> {
|
||||||
|
match self {
|
||||||
|
Self::Linked(typ) => Some(typ),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn linked_mut(&mut self) -> Option<&mut T> {
|
||||||
|
match self {
|
||||||
|
Self::Linked(typ) => Some(typ),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -1104,6 +1104,10 @@ pub enum Type {
|
||||||
Ellipsis, // これはクラスのほうで型推論用のマーカーではない
|
Ellipsis, // これはクラスのほうで型推論用のマーカーではない
|
||||||
Never, // {}
|
Never, // {}
|
||||||
Mono(Str),
|
Mono(Str),
|
||||||
|
ForeignMono {
|
||||||
|
path: Str,
|
||||||
|
name: Str,
|
||||||
|
},
|
||||||
/* Polymorphic types */
|
/* Polymorphic types */
|
||||||
Ref(Box<Type>),
|
Ref(Box<Type>),
|
||||||
RefMut {
|
RefMut {
|
||||||
|
@ -1174,6 +1178,10 @@ impl PartialEq for Type {
|
||||||
| (Self::Ellipsis, Self::Ellipsis)
|
| (Self::Ellipsis, Self::Ellipsis)
|
||||||
| (Self::Never, Self::Never) => true,
|
| (Self::Never, Self::Never) => true,
|
||||||
(Self::Mono(l), Self::Mono(r)) => l == r,
|
(Self::Mono(l), Self::Mono(r)) => l == r,
|
||||||
|
(
|
||||||
|
Self::ForeignMono { path: lp, name: ln },
|
||||||
|
Self::ForeignMono { path: rp, name: rn },
|
||||||
|
) => lp == rp && ln == rn,
|
||||||
(Self::MonoQVar(l), Self::MonoQVar(r)) => l == r,
|
(Self::MonoQVar(l), Self::MonoQVar(r)) => l == r,
|
||||||
(Self::Ref(l), Self::Ref(r)) => l == r,
|
(Self::Ref(l), Self::Ref(r)) => l == r,
|
||||||
(
|
(
|
||||||
|
@ -1269,6 +1277,7 @@ impl LimitedDisplay for Type {
|
||||||
}
|
}
|
||||||
match self {
|
match self {
|
||||||
Self::Mono(name) => write!(f, "{name}"),
|
Self::Mono(name) => write!(f, "{name}"),
|
||||||
|
Self::ForeignMono { path, name } => write!(f, "{name}(of {path})"),
|
||||||
Self::Ref(t) => {
|
Self::Ref(t) => {
|
||||||
write!(f, "{}(", self.name())?;
|
write!(f, "{}(", self.name())?;
|
||||||
t.limited_fmt(f, limit - 1)?;
|
t.limited_fmt(f, limit - 1)?;
|
||||||
|
@ -1758,7 +1767,9 @@ impl Type {
|
||||||
Self::Error => Str::ever("Error"),
|
Self::Error => Str::ever("Error"),
|
||||||
Self::Inf => Str::ever("Inf"),
|
Self::Inf => Str::ever("Inf"),
|
||||||
Self::NegInf => Str::ever("NegInf"),
|
Self::NegInf => Str::ever("NegInf"),
|
||||||
Self::Mono(name) | Self::MonoQVar(name) => name.clone(),
|
Self::Mono(name) | Self::MonoQVar(name) | Self::ForeignMono { name, .. } => {
|
||||||
|
name.clone()
|
||||||
|
}
|
||||||
Self::And(_, _) => Str::ever("And"),
|
Self::And(_, _) => Str::ever("And"),
|
||||||
Self::Not(_, _) => Str::ever("Not"),
|
Self::Not(_, _) => Str::ever("Not"),
|
||||||
Self::Or(_, _) => Str::ever("Or"),
|
Self::Or(_, _) => Str::ever("Or"),
|
||||||
|
@ -1991,16 +2002,22 @@ impl Type {
|
||||||
|
|
||||||
pub fn self_t(&self) -> Option<&Type> {
|
pub fn self_t(&self) -> Option<&Type> {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(fv) if fv.is_linked() => todo!("linked: {fv}"),
|
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||||
|
.unwrap()
|
||||||
|
.linked()
|
||||||
|
.and_then(|t| t.self_t()),
|
||||||
Self::Refinement(refine) => refine.t.self_t(),
|
Self::Refinement(refine) => refine.t.self_t(),
|
||||||
Self::Subr(subr) => subr.self_t(),
|
Self::Subr(subr) => subr.self_t(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn non_default_params(&self) -> Option<&Vec<ParamTy>> {
|
pub fn non_default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(_) => panic!("fv"),
|
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||||
|
.unwrap()
|
||||||
|
.linked()
|
||||||
|
.and_then(|t| t.non_default_params()),
|
||||||
Self::Refinement(refine) => refine.t.non_default_params(),
|
Self::Refinement(refine) => refine.t.non_default_params(),
|
||||||
Self::Subr(SubrType {
|
Self::Subr(SubrType {
|
||||||
non_default_params, ..
|
non_default_params, ..
|
||||||
|
@ -2012,7 +2029,10 @@ impl Type {
|
||||||
|
|
||||||
pub fn var_args(&self) -> Option<&ParamTy> {
|
pub fn var_args(&self) -> Option<&ParamTy> {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(_) => panic!("fv"),
|
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||||
|
.unwrap()
|
||||||
|
.linked()
|
||||||
|
.and_then(|t| t.var_args()),
|
||||||
Self::Refinement(refine) => refine.t.var_args(),
|
Self::Refinement(refine) => refine.t.var_args(),
|
||||||
Self::Subr(SubrType {
|
Self::Subr(SubrType {
|
||||||
var_params: var_args,
|
var_params: var_args,
|
||||||
|
@ -2023,18 +2043,24 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn default_params(&self) -> Option<&Vec<ParamTy>> {
|
pub fn default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(_) => panic!("fv"),
|
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||||
|
.unwrap()
|
||||||
|
.linked()
|
||||||
|
.and_then(|t| t.default_params()),
|
||||||
Self::Refinement(refine) => refine.t.default_params(),
|
Self::Refinement(refine) => refine.t.default_params(),
|
||||||
Self::Subr(SubrType { default_params, .. }) => Some(default_params),
|
Self::Subr(SubrType { default_params, .. }) => Some(default_params),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn return_t(&self) -> Option<&Type> {
|
pub fn return_t(&self) -> Option<&Type> {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(_) => panic!("fv"),
|
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||||
|
.unwrap()
|
||||||
|
.linked()
|
||||||
|
.and_then(|t| t.return_t()),
|
||||||
Self::Refinement(refine) => refine.t.return_t(),
|
Self::Refinement(refine) => refine.t.return_t(),
|
||||||
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
||||||
Some(return_t)
|
Some(return_t)
|
||||||
|
@ -2045,7 +2071,10 @@ impl Type {
|
||||||
|
|
||||||
pub fn mut_return_t(&mut self) -> Option<&mut Type> {
|
pub fn mut_return_t(&mut self) -> Option<&mut Type> {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(_) => panic!("fv"),
|
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_mut() }
|
||||||
|
.unwrap()
|
||||||
|
.linked_mut()
|
||||||
|
.and_then(|t| t.mut_return_t()),
|
||||||
Self::Refinement(refine) => refine.t.mut_return_t(),
|
Self::Refinement(refine) => refine.t.mut_return_t(),
|
||||||
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
||||||
Some(return_t)
|
Some(return_t)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue