mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-01 17:33:29 +00:00
make debug log easier to see
This commit is contained in:
parent
c4b61bb14d
commit
95c70f4aed
13 changed files with 146 additions and 82 deletions
|
@ -270,17 +270,86 @@ macro_rules! debug_enum_assert {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! debug_info {
|
||||||
|
($output:ident) => {{
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use $crate::color::{CYAN, RESET};
|
||||||
|
write!($output, "[{}DEBUG{}] {}:{:04}: ", CYAN, RESET, file!(), line!()).unwrap();
|
||||||
|
}};
|
||||||
|
() => {{
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use $crate::color::{CYAN, RESET};
|
||||||
|
print!("[{}DEBUG{}] {}:{:04}: ", CYAN, RESET, file!(), line!());
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Debug log utility.
|
||||||
|
/// directives:
|
||||||
|
/// c: colored output
|
||||||
|
/// f: file specified
|
||||||
|
/// f+c: file specified and colored (e.g. colored output to stderr)
|
||||||
|
/// info: info logging, (comprehensive shorthand for "c GREEN")
|
||||||
|
/// info_f: file version of info
|
||||||
|
/// err: error logging, (comprehensive shorthand for "c RED")
|
||||||
|
/// err_f: file version of err
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! log {
|
macro_rules! log {
|
||||||
(f $output: ident, $($arg: tt)*) => {
|
(info $($arg: tt)*) => {{
|
||||||
if cfg!(feature = "debug") { write!($output, "{}:{:04}: ", file!(), line!()).unwrap();
|
$crate::log!(c GREEN, $($arg)*);
|
||||||
|
}};
|
||||||
|
|
||||||
|
(err $($arg: tt)*) => {{
|
||||||
|
$crate::log!(c RED, $($arg)*);
|
||||||
|
}};
|
||||||
|
|
||||||
|
(info_f $output:ident, $($arg: tt)*) => {{
|
||||||
|
$crate::log!(f+c $output, GREEN, $($arg)*);
|
||||||
|
}};
|
||||||
|
|
||||||
|
(err_f $output:ident, $($arg: tt)*) => {{
|
||||||
|
$crate::log!(f+c $output, RED, $($arg)*);
|
||||||
|
}};
|
||||||
|
|
||||||
|
(f $output: ident, $($arg: tt)*) => {{
|
||||||
|
if cfg!(feature = "debug") {
|
||||||
|
use $crate::color::RESET;
|
||||||
|
$crate::debug_info!($output);
|
||||||
write!($output, $($arg)*).unwrap();
|
write!($output, $($arg)*).unwrap();
|
||||||
|
write!($output, "{}", RESET).unwrap(); // color color anyway
|
||||||
$output.flush().unwrap();
|
$output.flush().unwrap();
|
||||||
}
|
}
|
||||||
};
|
}};
|
||||||
($($arg: tt)*) => {
|
|
||||||
if cfg!(feature = "debug") { print!("{}:{:04}: ", file!(), line!()); println!($($arg)*); }
|
(c $color:ident, $($arg: tt)*) => {{
|
||||||
};
|
if cfg!(feature = "debug") {
|
||||||
|
use $crate::color::*;
|
||||||
|
$crate::debug_info!();
|
||||||
|
print!("{}", $color);
|
||||||
|
println!($($arg)*);
|
||||||
|
print!("{}", RESET); // reset color anyway
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
(f+c $output:ident, $color:ident, $($arg: tt)*) => {{
|
||||||
|
if cfg!(feature = "debug") {
|
||||||
|
use $crate::color::*;
|
||||||
|
$crate::debug_info!($output);
|
||||||
|
write!($output, "{}", $color).unwrap();
|
||||||
|
write!($output, $($arg)*).unwrap();
|
||||||
|
write!($output, "{}", RESET).unwrap(); // reset color anyway
|
||||||
|
$output.flush().unwrap();
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
($($arg: tt)*) => {{
|
||||||
|
if cfg!(feature = "debug") {
|
||||||
|
use $crate::color::*;
|
||||||
|
$crate::debug_info!();
|
||||||
|
println!($($arg)*);
|
||||||
|
print!("{}", RESET); // reset color anyway
|
||||||
|
}
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
|
@ -8,7 +8,6 @@ use std::process;
|
||||||
use std::slice::{Iter, IterMut};
|
use std::slice::{Iter, IterMut};
|
||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
|
|
||||||
use crate::color::{GREEN, RESET};
|
|
||||||
use crate::config::{ErgConfig, Input, BUILD_DATE, GIT_HASH_SHORT, SEMVER};
|
use crate::config::{ErgConfig, Input, BUILD_DATE, GIT_HASH_SHORT, SEMVER};
|
||||||
use crate::error::{ErrorDisplay, ErrorKind, Location, MultiErrorDisplay};
|
use crate::error::{ErrorDisplay, ErrorKind, Location, MultiErrorDisplay};
|
||||||
use crate::Str;
|
use crate::Str;
|
||||||
|
@ -343,7 +342,7 @@ pub trait Runnable: Sized {
|
||||||
Input::REPL => {
|
Input::REPL => {
|
||||||
let output = stdout();
|
let output = stdout();
|
||||||
let mut output = BufWriter::new(output.lock());
|
let mut output = BufWriter::new(output.lock());
|
||||||
log!(f output, "{GREEN}[DEBUG] The REPL has started.{RESET}\n");
|
log!(info_f output, "The REPL has started.\n");
|
||||||
output
|
output
|
||||||
.write_all(instance.start_message().as_bytes())
|
.write_all(instance.start_message().as_bytes())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -354,7 +353,7 @@ pub trait Runnable: Sized {
|
||||||
let line = chomp(&instance.input().read());
|
let line = chomp(&instance.input().read());
|
||||||
if &line[..] == ":quit" || &line[..] == ":exit" {
|
if &line[..] == ":quit" || &line[..] == ":exit" {
|
||||||
instance.finish();
|
instance.finish();
|
||||||
log!(f output, "{GREEN}[DEBUG] The REPL has finished successfully.{RESET}\n");
|
log!(info_f output, "The REPL has finished successfully.\n");
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
lines.push_str(&line);
|
lines.push_str(&line);
|
||||||
|
@ -376,7 +375,7 @@ pub trait Runnable: Sized {
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
instance.finish();
|
instance.finish();
|
||||||
log!(f output, "{GREEN}[DEBUG] The REPL has finished successfully.{RESET}\n");
|
log!(info_f output, "The REPL has finished successfully.\n");
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
errs.fmt_all_stderr();
|
errs.fmt_all_stderr();
|
||||||
|
|
|
@ -5,7 +5,6 @@ use std::fmt;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
|
||||||
use erg_common::cache::CacheSet;
|
use erg_common::cache::CacheSet;
|
||||||
use erg_common::color::{GREEN, RESET};
|
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::error::{Location, MultiErrorDisplay};
|
use erg_common::error::{Location, MultiErrorDisplay};
|
||||||
use erg_common::opcode::Opcode;
|
use erg_common::opcode::Opcode;
|
||||||
|
@ -378,13 +377,13 @@ impl CodeGenerator {
|
||||||
fn write_instr(&mut self, code: Opcode) {
|
fn write_instr(&mut self, code: Opcode) {
|
||||||
self.mut_cur_block_codeobj().code.push(code as u8);
|
self.mut_cur_block_codeobj().code.push(code as u8);
|
||||||
self.mut_cur_block().lasti += 1;
|
self.mut_cur_block().lasti += 1;
|
||||||
// log!("wrote: {}", code);
|
// log!(info "wrote: {}", code);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_arg(&mut self, code: u8) {
|
fn write_arg(&mut self, code: u8) {
|
||||||
self.mut_cur_block_codeobj().code.push(code);
|
self.mut_cur_block_codeobj().code.push(code);
|
||||||
self.mut_cur_block().lasti += 1;
|
self.mut_cur_block().lasti += 1;
|
||||||
// log!("wrote: {}", code);
|
// log!(info "wrote: {}", code);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stack_inc(&mut self) {
|
fn stack_inc(&mut self) {
|
||||||
|
@ -1414,7 +1413,7 @@ impl CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen(&mut self, hir: HIR) -> CodeObj {
|
pub fn codegen(&mut self, hir: HIR) -> CodeObj {
|
||||||
log!("{GREEN}[DEBUG] the code-generating process has started.{RESET}");
|
log!(info "the code-generating process has started.{RESET}");
|
||||||
self.unit_size += 1;
|
self.unit_size += 1;
|
||||||
self.units.push(CodeGenUnit::new(
|
self.units.push(CodeGenUnit::new(
|
||||||
self.unit_size,
|
self.unit_size,
|
||||||
|
@ -1482,7 +1481,7 @@ impl CodeGenerator {
|
||||||
self.mut_cur_block().prev_lineno += ld;
|
self.mut_cur_block().prev_lineno += ld;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log!("{GREEN}[DEBUG] the code-generating process has completed.{RESET}");
|
log!(info "the code-generating process has completed.{RESET}");
|
||||||
unit.codeobj
|
unit.codeobj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
//! コンパイラーを定義する
|
//! コンパイラーを定義する
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use erg_common::color::{GREEN, RESET};
|
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::error::MultiErrorDisplay;
|
use erg_common::error::MultiErrorDisplay;
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
|
@ -159,7 +158,7 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(&mut self, src: Str, mode: &str) -> Result<CodeObj, CompileErrors> {
|
pub fn compile(&mut self, src: Str, mode: &str) -> Result<CodeObj, CompileErrors> {
|
||||||
log!("{GREEN}[DEBUG] the compiling process has started.{RESET}");
|
log!(info "the compiling process has started");
|
||||||
let mut cfg = self.cfg.copy();
|
let mut cfg = self.cfg.copy();
|
||||||
cfg.input = Input::Str(src);
|
cfg.input = Input::Str(src);
|
||||||
let mut parser = ParserRunner::new(cfg);
|
let mut parser = ParserRunner::new(cfg);
|
||||||
|
@ -181,9 +180,10 @@ impl Compiler {
|
||||||
.check(hir)
|
.check(hir)
|
||||||
.map_err(|errs| self.convert(errs))?;
|
.map_err(|errs| self.convert(errs))?;
|
||||||
let codeobj = self.code_generator.codegen(hir);
|
let codeobj = self.code_generator.codegen(hir);
|
||||||
log!("{GREEN}code object:\n{}", codeobj.code_info());
|
log!(info "code object:\n{}", codeobj.code_info());
|
||||||
log!(
|
log!(
|
||||||
"[DEBUG] the compiling process has completed, found errors: {}{RESET}",
|
c GREEN,
|
||||||
|
"the compiling process has completed, found errors: {}",
|
||||||
self.code_generator.errs.len()
|
self.code_generator.errs.len()
|
||||||
);
|
);
|
||||||
if self.code_generator.errs.is_empty() {
|
if self.code_generator.errs.is_empty() {
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl Context {
|
||||||
if sub.is_cachable() && sup.is_cachable() {
|
if sub.is_cachable() && sup.is_cachable() {
|
||||||
let res = GLOBAL_TYPE_CACHE.get(&SubtypePair::new(sub.clone(), sup.clone()));
|
let res = GLOBAL_TYPE_CACHE.get(&SubtypePair::new(sub.clone(), sup.clone()));
|
||||||
if res.is_some() {
|
if res.is_some() {
|
||||||
log!("cache hit");
|
log!(info "cache hit");
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
} else {
|
} else {
|
||||||
|
@ -242,7 +242,7 @@ impl Context {
|
||||||
/// make judgments that include supertypes in the same namespace & take into account glue patches
|
/// make judgments that include supertypes in the same namespace & take into account glue patches
|
||||||
/// 同一名前空間にある上位型を含めた判定&接着パッチを考慮した判定を行う
|
/// 同一名前空間にある上位型を含めた判定&接着パッチを考慮した判定を行う
|
||||||
fn nominal_supertype_of(&self, lhs: &Type, rhs: &Type) -> bool {
|
fn nominal_supertype_of(&self, lhs: &Type, rhs: &Type) -> bool {
|
||||||
log!("nominal_supertype_of:\nlhs: {lhs}\nrhs: {rhs}");
|
log!(info "nominal_supertype_of:\nlhs: {lhs}\nrhs: {rhs}");
|
||||||
if let Some(res) = self.inquire_cache(rhs, lhs) {
|
if let Some(res) = self.inquire_cache(rhs, lhs) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -345,12 +345,12 @@ impl Context {
|
||||||
/// assert!(sup_conforms(?E(<: Eq(?R)), {Nat, Eq(T)}))
|
/// assert!(sup_conforms(?E(<: Eq(?R)), {Nat, Eq(T)}))
|
||||||
fn _sub_conforms(&self, free: &FreeTyVar, inst_pair: &TraitInstance) -> bool {
|
fn _sub_conforms(&self, free: &FreeTyVar, inst_pair: &TraitInstance) -> bool {
|
||||||
let (_sub, sup) = free.crack_bound_types().unwrap();
|
let (_sub, sup) = free.crack_bound_types().unwrap();
|
||||||
log!("{free}");
|
log!(info "{free}");
|
||||||
free.forced_undoable_link(&inst_pair.sub_type);
|
free.forced_undoable_link(&inst_pair.sub_type);
|
||||||
log!("{free}");
|
log!(info "{free}");
|
||||||
let judge = self.subtype_of(&sup, &inst_pair.sup_trait);
|
let judge = self.subtype_of(&sup, &inst_pair.sup_trait);
|
||||||
free.undo();
|
free.undo();
|
||||||
log!("{free}");
|
log!(info "{free}");
|
||||||
judge
|
judge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ impl Context {
|
||||||
/// 単一化、評価等はここでは行わない、スーパータイプになる可能性があるかだけ判定する
|
/// 単一化、評価等はここでは行わない、スーパータイプになる可能性があるかだけ判定する
|
||||||
/// ので、lhsが(未連携)型変数の場合は単一化せずにtrueを返す
|
/// ので、lhsが(未連携)型変数の場合は単一化せずにtrueを返す
|
||||||
pub(crate) fn structural_supertype_of(&self, lhs: &Type, rhs: &Type) -> bool {
|
pub(crate) fn structural_supertype_of(&self, lhs: &Type, rhs: &Type) -> bool {
|
||||||
log!("structural_supertype_of:\nlhs: {lhs}\nrhs: {rhs}");
|
log!(info "structural_supertype_of:\nlhs: {lhs}\nrhs: {rhs}");
|
||||||
match (lhs, rhs) {
|
match (lhs, rhs) {
|
||||||
(Subr(ls), Subr(rs)) if ls.kind.same_kind_as(&rs.kind) => {
|
(Subr(ls), Subr(rs)) if ls.kind.same_kind_as(&rs.kind) => {
|
||||||
if ls.kind.self_t().is_some() {
|
if ls.kind.self_t().is_some() {
|
||||||
|
@ -632,7 +632,7 @@ impl Context {
|
||||||
self.subtype_of(l, r)
|
self.subtype_of(l, r)
|
||||||
}
|
}
|
||||||
(TyParam::Type(l), TyParam::Type(r), Variance::Covariant) => {
|
(TyParam::Type(l), TyParam::Type(r), Variance::Covariant) => {
|
||||||
// if matches!(r.as_ref(), &Type::Refinement(_)) { log!("{l}, {r}, {}", self.structural_supertype_of(l, r, bounds, Some(lhs_variance))); }
|
// if matches!(r.as_ref(), &Type::Refinement(_)) { log!(info "{l}, {r}, {}", self.structural_supertype_of(l, r, bounds, Some(lhs_variance))); }
|
||||||
self.supertype_of(l, r)
|
self.supertype_of(l, r)
|
||||||
}
|
}
|
||||||
// Invariant
|
// Invariant
|
||||||
|
@ -788,7 +788,7 @@ impl Context {
|
||||||
lhs.preds.clone().concat(rhs_preds),
|
lhs.preds.clone().concat(rhs_preds),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
log!("{lhs}\n{rhs}");
|
log!(info "{lhs}\n{rhs}");
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// (type) getters & validators
|
// (type) getters & validators
|
||||||
use std::option::Option; // conflicting to Type::Option
|
use std::option::Option; // conflicting to Type::Option
|
||||||
|
|
||||||
use erg_common::color::{GREEN, RED};
|
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::ErrorCore;
|
use erg_common::error::ErrorCore;
|
||||||
use erg_common::levenshtein::levenshtein;
|
use erg_common::levenshtein::levenshtein;
|
||||||
|
@ -365,7 +364,7 @@ impl Context {
|
||||||
..
|
..
|
||||||
}) = t
|
}) = t
|
||||||
{
|
{
|
||||||
log!("{}, {}", callee.ref_t(), after);
|
log!(info "{}, {}", callee.ref_t(), after);
|
||||||
self.reunify(callee.ref_t(), after, Some(callee.loc()), None)?;
|
self.reunify(callee.ref_t(), after, Some(callee.loc()), None)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -531,8 +530,8 @@ impl Context {
|
||||||
param_ty.name.as_ref(),
|
param_ty.name.as_ref(),
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
log!("{RED}semi-unification failed with {callee}\n{arg_t} !<: {param_t}");
|
log!(err "semi-unification failed with {callee}\n{arg_t} !<: {param_t}");
|
||||||
log!("errno: {}{GREEN}", e.core.errno);
|
log!(err "errno: {}", e.core.errno);
|
||||||
// REVIEW:
|
// REVIEW:
|
||||||
let name = callee.var_full_name().unwrap_or_else(|| "".to_string());
|
let name = callee.var_full_name().unwrap_or_else(|| "".to_string());
|
||||||
let name = name
|
let name = name
|
||||||
|
@ -625,13 +624,13 @@ impl Context {
|
||||||
fmt_slice(kw_args)
|
fmt_slice(kw_args)
|
||||||
);
|
);
|
||||||
self.substitute_call(obj, method_name, &instance, pos_args, kw_args)?;
|
self.substitute_call(obj, method_name, &instance, pos_args, kw_args)?;
|
||||||
log!("Substituted:\ninstance: {instance}");
|
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!("Params evaluated:\nres: {res}\n");
|
log!(info "Params evaluated:\nres: {res}\n");
|
||||||
self.propagate(&res, obj)?;
|
self.propagate(&res, obj)?;
|
||||||
log!("Propagated:\nres: {res}\n");
|
log!(info "Propagated:\nres: {res}\n");
|
||||||
let res = self.resolve_trait(res)?;
|
let res = self.resolve_trait(res)?;
|
||||||
log!("Trait resolved:\nres: {res}\n");
|
log!(info "Trait resolved:\nres: {res}\n");
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -524,7 +524,7 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
format!("{parent}::{name}", parent = self.name)
|
format!("{parent}::{name}", parent = self.name)
|
||||||
};
|
};
|
||||||
log!("{}: 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.name = name.into();
|
self.name = name.into();
|
||||||
self.kind = kind;
|
self.kind = kind;
|
||||||
|
@ -544,7 +544,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
if let Some(parent) = &mut self.outer {
|
if let Some(parent) = &mut self.outer {
|
||||||
*self = mem::take(parent);
|
*self = mem::take(parent);
|
||||||
log!("{}: current namespace: {}", fn_name!(), self.name);
|
log!(info "{}: current namespace: {}", fn_name!(), self.name);
|
||||||
if !uninited_errs.is_empty() {
|
if !uninited_errs.is_empty() {
|
||||||
Err(uninited_errs)
|
Err(uninited_errs)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -303,7 +303,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
// TODO: visibility
|
// TODO: visibility
|
||||||
let vi = VarInfo::new(found_t, muty, Private, VarKind::Defined(id));
|
let vi = VarInfo::new(found_t, muty, Private, VarKind::Defined(id));
|
||||||
log!("Registered {}::{name}: {}", self.name, &vi.t);
|
log!(info "Registered {}::{name}: {}", self.name, &vi.t);
|
||||||
self.params.push((Some(name.clone()), vi));
|
self.params.push((Some(name.clone()), vi));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -975,7 +975,7 @@ impl Context {
|
||||||
sup_loc: Option<Location>,
|
sup_loc: Option<Location>,
|
||||||
param_name: Option<&Str>,
|
param_name: Option<&Str>,
|
||||||
) -> TyCheckResult<()> {
|
) -> TyCheckResult<()> {
|
||||||
erg_common::log!("trying sub_unify:\nmaybe_sub: {maybe_sub}\nmaybe_sup: {maybe_sup}");
|
erg_common::log!(info "trying sub_unify:\nmaybe_sub: {maybe_sub}\nmaybe_sup: {maybe_sup}");
|
||||||
// In this case, there is no new information to be gained
|
// In this case, there is no new information to be gained
|
||||||
// この場合、特に新しく得られる情報はない
|
// この場合、特に新しく得られる情報はない
|
||||||
if maybe_sub == &Type::Never || maybe_sup == &Type::Obj {
|
if maybe_sub == &Type::Never || maybe_sup == &Type::Obj {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
//! SideEffectCheckerを実装
|
//! SideEffectCheckerを実装
|
||||||
//! 関数や不変型に副作用がないかチェックする
|
//! 関数や不変型に副作用がないかチェックする
|
||||||
|
|
||||||
use erg_common::color::{GREEN, RESET};
|
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
use erg_common::traits::Stream;
|
use erg_common::traits::Stream;
|
||||||
use erg_common::vis::Visibility;
|
use erg_common::vis::Visibility;
|
||||||
|
@ -78,7 +77,7 @@ impl SideEffectChecker {
|
||||||
pub fn check(mut self, hir: HIR) -> EffectResult<HIR> {
|
pub fn check(mut self, hir: HIR) -> EffectResult<HIR> {
|
||||||
self.path_stack.push((hir.name.clone(), Private));
|
self.path_stack.push((hir.name.clone(), Private));
|
||||||
self.block_stack.push(Module);
|
self.block_stack.push(Module);
|
||||||
log!("{GREEN}[DEBUG] the side-effects checking process has started.{RESET}");
|
log!(info "the side-effects checking process has started.{RESET}");
|
||||||
// トップレベルでは副作用があっても問題なく、純粋性違反がないかのみチェックする
|
// トップレベルでは副作用があっても問題なく、純粋性違反がないかのみチェックする
|
||||||
for expr in hir.module.iter() {
|
for expr in hir.module.iter() {
|
||||||
match expr {
|
match expr {
|
||||||
|
@ -104,7 +103,7 @@ impl SideEffectChecker {
|
||||||
other => todo!("{other}"),
|
other => todo!("{other}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log!("{GREEN}[DEBUG] the side-effects checking process has completed, found errors: {}{RESET}", self.errs.len());
|
log!(info "the side-effects checking process has completed, found errors: {}{RESET}", self.errs.len());
|
||||||
if self.errs.is_empty() {
|
if self.errs.is_empty() {
|
||||||
Ok(hir)
|
Ok(hir)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! implements `ASTLowerer`.
|
//! implements `ASTLowerer`.
|
||||||
//!
|
//!
|
||||||
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
||||||
use erg_common::color::{GREEN, RED, RESET};
|
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
use erg_common::traits::{Locational, Stream};
|
use erg_common::traits::{Locational, Stream};
|
||||||
use erg_common::vis::Visibility;
|
use erg_common::vis::Visibility;
|
||||||
|
@ -95,7 +94,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_array(&mut self, array: ast::Array) -> LowerResult<hir::Array> {
|
fn lower_array(&mut self, array: ast::Array) -> LowerResult<hir::Array> {
|
||||||
log!("[DEBUG] entered {}({array})", fn_name!());
|
log!(info "entered {}({array})", fn_name!());
|
||||||
match array {
|
match array {
|
||||||
ast::Array::Normal(arr) => Ok(hir::Array::Normal(self.lower_normal_array(arr)?)),
|
ast::Array::Normal(arr) => Ok(hir::Array::Normal(self.lower_normal_array(arr)?)),
|
||||||
ast::Array::WithLength(arr) => {
|
ast::Array::WithLength(arr) => {
|
||||||
|
@ -106,7 +105,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_normal_array(&mut self, array: ast::NormalArray) -> LowerResult<hir::NormalArray> {
|
fn lower_normal_array(&mut self, array: ast::NormalArray) -> LowerResult<hir::NormalArray> {
|
||||||
log!("[DEBUG] entered {}({array})", fn_name!());
|
log!(info "entered {}({array})", fn_name!());
|
||||||
let mut new_array = vec![];
|
let mut new_array = vec![];
|
||||||
let (elems, _) = array.elems.into_iters();
|
let (elems, _) = array.elems.into_iters();
|
||||||
let mut union = Type::Never;
|
let mut union = Type::Never;
|
||||||
|
@ -154,7 +153,7 @@ impl ASTLowerer {
|
||||||
&mut self,
|
&mut self,
|
||||||
array: ast::ArrayWithLength,
|
array: ast::ArrayWithLength,
|
||||||
) -> LowerResult<hir::ArrayWithLength> {
|
) -> LowerResult<hir::ArrayWithLength> {
|
||||||
log!("[DEBUG] entered {}({array})", fn_name!());
|
log!(info "entered {}({array})", fn_name!());
|
||||||
let elem = self.lower_expr(array.elem.expr)?;
|
let elem = self.lower_expr(array.elem.expr)?;
|
||||||
let array_t = self.gen_array_with_length_type(&elem, &array.len);
|
let array_t = self.gen_array_with_length_type(&elem, &array.len);
|
||||||
let len = self.lower_expr(*array.len)?;
|
let len = self.lower_expr(*array.len)?;
|
||||||
|
@ -201,14 +200,14 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_tuple(&mut self, tuple: ast::Tuple) -> LowerResult<hir::Tuple> {
|
fn lower_tuple(&mut self, tuple: ast::Tuple) -> LowerResult<hir::Tuple> {
|
||||||
log!("[DEBUG] entered {}({tuple})", fn_name!());
|
log!(info "entered {}({tuple})", fn_name!());
|
||||||
match tuple {
|
match tuple {
|
||||||
ast::Tuple::Normal(tup) => Ok(hir::Tuple::Normal(self.lower_normal_tuple(tup)?)),
|
ast::Tuple::Normal(tup) => Ok(hir::Tuple::Normal(self.lower_normal_tuple(tup)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_normal_tuple(&mut self, tuple: ast::NormalTuple) -> LowerResult<hir::NormalTuple> {
|
fn lower_normal_tuple(&mut self, tuple: ast::NormalTuple) -> LowerResult<hir::NormalTuple> {
|
||||||
log!("[DEBUG] entered {}({tuple})", fn_name!());
|
log!(info "entered {}({tuple})", fn_name!());
|
||||||
let mut new_tuple = vec![];
|
let mut new_tuple = vec![];
|
||||||
let (elems, _) = tuple.elems.into_iters();
|
let (elems, _) = tuple.elems.into_iters();
|
||||||
for elem in elems {
|
for elem in elems {
|
||||||
|
@ -219,7 +218,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_record(&mut self, record: ast::Record) -> LowerResult<hir::Record> {
|
fn lower_record(&mut self, record: ast::Record) -> LowerResult<hir::Record> {
|
||||||
log!("[DEBUG] entered {}({record})", fn_name!());
|
log!(info "entered {}({record})", fn_name!());
|
||||||
let mut hir_record =
|
let mut hir_record =
|
||||||
hir::Record::new(record.l_brace, record.r_brace, hir::RecordAttrs::new());
|
hir::Record::new(record.l_brace, record.r_brace, hir::RecordAttrs::new());
|
||||||
self.ctx.grow("<record>", ContextKind::Dummy, Private)?;
|
self.ctx.grow("<record>", ContextKind::Dummy, Private)?;
|
||||||
|
@ -232,7 +231,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_acc(&mut self, acc: ast::Accessor) -> LowerResult<hir::Accessor> {
|
fn lower_acc(&mut self, acc: ast::Accessor) -> LowerResult<hir::Accessor> {
|
||||||
log!("[DEBUG] entered {}({acc})", fn_name!());
|
log!(info "entered {}({acc})", fn_name!());
|
||||||
match acc {
|
match acc {
|
||||||
ast::Accessor::Local(local) => {
|
ast::Accessor::Local(local) => {
|
||||||
// `match` is an untypable special form
|
// `match` is an untypable special form
|
||||||
|
@ -293,7 +292,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_bin(&mut self, bin: ast::BinOp) -> LowerResult<hir::BinOp> {
|
fn lower_bin(&mut self, bin: ast::BinOp) -> LowerResult<hir::BinOp> {
|
||||||
log!("[DEBUG] entered {}({bin})", fn_name!());
|
log!(info "entered {}({bin})", fn_name!());
|
||||||
let mut args = bin.args.into_iter();
|
let mut args = bin.args.into_iter();
|
||||||
let lhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
|
let lhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
|
||||||
let rhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
|
let rhs = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
|
||||||
|
@ -306,7 +305,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_unary(&mut self, unary: ast::UnaryOp) -> LowerResult<hir::UnaryOp> {
|
fn lower_unary(&mut self, unary: ast::UnaryOp) -> LowerResult<hir::UnaryOp> {
|
||||||
log!("[DEBUG] entered {}({unary})", fn_name!());
|
log!(info "entered {}({unary})", fn_name!());
|
||||||
let mut args = unary.args.into_iter();
|
let mut args = unary.args.into_iter();
|
||||||
let arg = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
|
let arg = hir::PosArg::new(self.lower_expr(*args.next().unwrap())?);
|
||||||
let args = [arg];
|
let args = [arg];
|
||||||
|
@ -317,7 +316,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_call(&mut self, call: ast::Call) -> LowerResult<hir::Call> {
|
fn lower_call(&mut self, call: ast::Call) -> LowerResult<hir::Call> {
|
||||||
log!("[DEBUG] entered {}({}(...))", fn_name!(), call.obj);
|
log!(info "entered {}({}(...))", fn_name!(), call.obj);
|
||||||
let (pos_args, kw_args, paren) = call.args.deconstruct();
|
let (pos_args, kw_args, paren) = call.args.deconstruct();
|
||||||
let mut hir_args = hir::Args::new(
|
let mut hir_args = hir::Args::new(
|
||||||
Vec::with_capacity(pos_args.len()),
|
Vec::with_capacity(pos_args.len()),
|
||||||
|
@ -342,7 +341,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_lambda(&mut self, lambda: ast::Lambda) -> LowerResult<hir::Lambda> {
|
fn lower_lambda(&mut self, lambda: ast::Lambda) -> LowerResult<hir::Lambda> {
|
||||||
log!("[DEBUG] entered {}({lambda})", fn_name!());
|
log!(info "entered {}({lambda})", fn_name!());
|
||||||
let is_procedural = lambda.is_procedural();
|
let is_procedural = lambda.is_procedural();
|
||||||
let id = get_hash(&lambda.sig);
|
let id = get_hash(&lambda.sig);
|
||||||
let name = format!("<lambda_{id}>");
|
let name = format!("<lambda_{id}>");
|
||||||
|
@ -407,7 +406,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_def(&mut self, def: ast::Def) -> LowerResult<hir::Def> {
|
fn lower_def(&mut self, def: ast::Def) -> LowerResult<hir::Def> {
|
||||||
log!("[DEBUG] entered {}({})", fn_name!(), def.sig);
|
log!(info "entered {}({})", fn_name!(), def.sig);
|
||||||
if let Some(name) = def.sig.name_as_str() {
|
if let Some(name) = def.sig.name_as_str() {
|
||||||
self.ctx.grow(name, ContextKind::Instant, Private)?;
|
self.ctx.grow(name, ContextKind::Instant, Private)?;
|
||||||
let res = match def.sig {
|
let res = match def.sig {
|
||||||
|
@ -430,7 +429,7 @@ impl ASTLowerer {
|
||||||
sig: ast::VarSignature,
|
sig: ast::VarSignature,
|
||||||
body: ast::DefBody,
|
body: ast::DefBody,
|
||||||
) -> LowerResult<hir::Def> {
|
) -> LowerResult<hir::Def> {
|
||||||
log!("[DEBUG] entered {}({sig})", fn_name!());
|
log!(info "entered {}({sig})", fn_name!());
|
||||||
self.ctx.preregister(body.block.ref_payload())?;
|
self.ctx.preregister(body.block.ref_payload())?;
|
||||||
let block = self.lower_block(body.block)?;
|
let block = self.lower_block(body.block)?;
|
||||||
let found_body_t = block.ref_t();
|
let found_body_t = block.ref_t();
|
||||||
|
@ -482,7 +481,7 @@ impl ASTLowerer {
|
||||||
sig: ast::SubrSignature,
|
sig: ast::SubrSignature,
|
||||||
body: ast::DefBody,
|
body: ast::DefBody,
|
||||||
) -> LowerResult<hir::Def> {
|
) -> LowerResult<hir::Def> {
|
||||||
log!("[DEBUG] entered {}({sig})", fn_name!());
|
log!(info "entered {}({sig})", fn_name!());
|
||||||
let t = self
|
let t = self
|
||||||
.ctx
|
.ctx
|
||||||
.outer
|
.outer
|
||||||
|
@ -490,8 +489,8 @@ impl ASTLowerer {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get_current_scope_var(sig.ident.inspect())
|
.get_current_scope_var(sig.ident.inspect())
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
log!("{}\n", sig.ident.inspect());
|
log!(info "{}\n", sig.ident.inspect());
|
||||||
log!("{}\n", self.ctx.outer.as_ref().unwrap());
|
log!(info "{}\n", self.ctx.outer.as_ref().unwrap());
|
||||||
panic!()
|
panic!()
|
||||||
}) // FIXME: or instantiate
|
}) // FIXME: or instantiate
|
||||||
.t
|
.t
|
||||||
|
@ -520,7 +519,7 @@ impl ASTLowerer {
|
||||||
// Call.obj == Accessor cannot be type inferred by itself (it can only be inferred with arguments)
|
// Call.obj == Accessor cannot be type inferred by itself (it can only be inferred with arguments)
|
||||||
// so turn off type checking (check=false)
|
// so turn off type checking (check=false)
|
||||||
fn lower_expr(&mut self, expr: ast::Expr) -> LowerResult<hir::Expr> {
|
fn lower_expr(&mut self, expr: ast::Expr) -> LowerResult<hir::Expr> {
|
||||||
log!("[DEBUG] entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
match expr {
|
match expr {
|
||||||
ast::Expr::Lit(lit) => Ok(hir::Expr::Lit(hir::Literal::from(lit.token))),
|
ast::Expr::Lit(lit) => Ok(hir::Expr::Lit(hir::Literal::from(lit.token))),
|
||||||
ast::Expr::Array(arr) => Ok(hir::Expr::Array(self.lower_array(arr)?)),
|
ast::Expr::Array(arr) => Ok(hir::Expr::Array(self.lower_array(arr)?)),
|
||||||
|
@ -537,7 +536,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_block(&mut self, ast_block: ast::Block) -> LowerResult<hir::Block> {
|
fn lower_block(&mut self, ast_block: ast::Block) -> LowerResult<hir::Block> {
|
||||||
log!("[DEBUG] entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let mut hir_block = Vec::with_capacity(ast_block.len());
|
let mut hir_block = Vec::with_capacity(ast_block.len());
|
||||||
for expr in ast_block.into_iter() {
|
for expr in ast_block.into_iter() {
|
||||||
let expr = self.lower_expr(expr)?;
|
let expr = self.lower_expr(expr)?;
|
||||||
|
@ -547,8 +546,8 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower(&mut self, ast: AST, mode: &str) -> Result<(HIR, LowerWarnings), LowerErrors> {
|
pub fn lower(&mut self, ast: AST, mode: &str) -> Result<(HIR, LowerWarnings), LowerErrors> {
|
||||||
log!("{GREEN}[DEBUG] the AST lowering process has started.");
|
log!(info "the AST lowering process has started.");
|
||||||
log!("{GREEN}[DEBUG] the type-checking process has started.");
|
log!(info "the type-checking process has started.");
|
||||||
let mut module = hir::Module::with_capacity(ast.module.len());
|
let mut module = hir::Module::with_capacity(ast.module.len());
|
||||||
self.ctx.preregister(ast.module.ref_payload())?;
|
self.ctx.preregister(ast.module.ref_payload())?;
|
||||||
for expr in ast.module.into_iter() {
|
for expr in ast.module.into_iter() {
|
||||||
|
@ -562,18 +561,19 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let hir = HIR::new(ast.name, module);
|
let hir = HIR::new(ast.name, module);
|
||||||
log!("HIR (not derefed):\n{hir}");
|
log!(info "HIR (not derefed):\n{hir}");
|
||||||
log!(
|
log!(
|
||||||
"[DEBUG] the type-checking process has completed, found errors: {}",
|
c GREEN,
|
||||||
|
"the type-checking process has completed, found errors: {}",
|
||||||
self.errs.len()
|
self.errs.len()
|
||||||
);
|
);
|
||||||
let hir = self.ctx.deref_toplevel(hir)?;
|
let hir = self.ctx.deref_toplevel(hir)?;
|
||||||
if self.errs.is_empty() {
|
if self.errs.is_empty() {
|
||||||
log!("HIR:\n{hir}");
|
log!(info "HIR:\n{hir}");
|
||||||
log!("[DEBUG] the AST lowering process has completed.{RESET}");
|
log!(info "the AST lowering process has completed.");
|
||||||
Ok((hir, LowerWarnings::from(self.warns.take_all())))
|
Ok((hir, LowerWarnings::from(self.warns.take_all())))
|
||||||
} else {
|
} else {
|
||||||
log!("{RED}[DEBUG] the AST lowering process has failed.{RESET}");
|
log!(err "the AST lowering process has failed.");
|
||||||
Err(LowerErrors::from(self.errs.take_all()))
|
Err(LowerErrors::from(self.errs.take_all()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use erg_common::color::{GREEN, RESET};
|
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
|
@ -57,7 +56,7 @@ impl OwnershipChecker {
|
||||||
// moveされた後の変数が使用されていないかチェックする
|
// moveされた後の変数が使用されていないかチェックする
|
||||||
// ProceduralでないメソッドでRefMutが使われているかはSideEffectCheckerでチェックする
|
// ProceduralでないメソッドでRefMutが使われているかはSideEffectCheckerでチェックする
|
||||||
pub fn check(mut self, hir: HIR) -> OwnershipResult<HIR> {
|
pub fn check(mut self, hir: HIR) -> OwnershipResult<HIR> {
|
||||||
log!("{GREEN}[DEBUG] the ownership checking process has started.{RESET}");
|
log!(info "the ownership checking process has started.{RESET}");
|
||||||
self.path_stack.push((hir.name.clone(), Private));
|
self.path_stack.push((hir.name.clone(), Private));
|
||||||
self.dict
|
self.dict
|
||||||
.insert(Str::from(self.full_path()), LocalVars::default());
|
.insert(Str::from(self.full_path()), LocalVars::default());
|
||||||
|
@ -84,7 +83,7 @@ impl OwnershipChecker {
|
||||||
fn check_expr(&mut self, expr: &Expr, ownership: Ownership) {
|
fn check_expr(&mut self, expr: &Expr, ownership: Ownership) {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Def(def) => {
|
Expr::Def(def) => {
|
||||||
log!("define: {}", def.sig);
|
log!(info "define: {}", def.sig);
|
||||||
self.define(def);
|
self.define(def);
|
||||||
let name = match &def.sig {
|
let name = match &def.sig {
|
||||||
Signature::Var(var) => var.inspect().clone(),
|
Signature::Var(var) => var.inspect().clone(),
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use erg_common::color::{GREEN, RED, RESET};
|
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
use erg_common::config::Input;
|
use erg_common::config::Input;
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
|
@ -31,7 +30,8 @@ macro_rules! debug_call_info {
|
||||||
($self: ident) => {
|
($self: ident) => {
|
||||||
$self.level += 1;
|
$self.level += 1;
|
||||||
log!(
|
log!(
|
||||||
"[DEBUG]\n{} ({}) entered {}, cur: {}",
|
c GREEN,
|
||||||
|
"\n{} ({}) entered {}, cur: {}",
|
||||||
" ".repeat($self.level),
|
" ".repeat($self.level),
|
||||||
$self.level,
|
$self.level,
|
||||||
fn_name!(),
|
fn_name!(),
|
||||||
|
@ -286,7 +286,7 @@ impl Parser {
|
||||||
|
|
||||||
fn skip_and_throw_syntax_err(&mut self, caused_by: &str) -> ParseError {
|
fn skip_and_throw_syntax_err(&mut self, caused_by: &str) -> ParseError {
|
||||||
let loc = self.peek().unwrap().loc();
|
let loc = self.peek().unwrap().loc();
|
||||||
log!("{RED}[DEBUG] error caused by: {caused_by}{GREEN}");
|
log!(err "error caused by: {caused_by}");
|
||||||
self.next_expr();
|
self.next_expr();
|
||||||
ParseError::simple_syntax_error(0, loc)
|
ParseError::simple_syntax_error(0, loc)
|
||||||
}
|
}
|
||||||
|
@ -366,8 +366,8 @@ impl Parser {
|
||||||
if self.tokens.is_empty() {
|
if self.tokens.is_empty() {
|
||||||
return Ok(AST::new(mod_name, Module::empty()));
|
return Ok(AST::new(mod_name, Module::empty()));
|
||||||
}
|
}
|
||||||
log!("{GREEN}[DEBUG] the parsing process has started.");
|
log!(info "the parsing process has started.");
|
||||||
log!("token stream: {}", self.tokens);
|
log!(info "token stream: {}", self.tokens);
|
||||||
let module = match self.try_reduce_module() {
|
let module = match self.try_reduce_module() {
|
||||||
Ok(module) => module,
|
Ok(module) => module,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -380,13 +380,13 @@ impl Parser {
|
||||||
.push(ParseError::compiler_bug(0, loc, fn_name!(), line!()));
|
.push(ParseError::compiler_bug(0, loc, fn_name!(), line!()));
|
||||||
return Err(mem::take(&mut self.errs));
|
return Err(mem::take(&mut self.errs));
|
||||||
}
|
}
|
||||||
log!("[DEBUG] the parsing process has completed.");
|
log!(info "the parsing process has completed.");
|
||||||
log!("AST:\n{module}");
|
log!(info "AST:\n{module}");
|
||||||
log!("[DEBUG] the desugaring process has started.");
|
log!(info "the desugaring process has started.");
|
||||||
let mut desugarer = Desugarer::new();
|
let mut desugarer = Desugarer::new();
|
||||||
let module = desugarer.desugar(module);
|
let module = desugarer.desugar(module);
|
||||||
log!("AST (desugared):\n{module}");
|
log!(info "AST (desugared):\n{module}");
|
||||||
log!("[DEBUG] the desugaring process has completed.{RESET}");
|
log!(info "the desugaring process has completed.{RESET}");
|
||||||
if self.errs.is_empty() {
|
if self.errs.is_empty() {
|
||||||
Ok(AST::new(mod_name, module))
|
Ok(AST::new(mod_name, module))
|
||||||
} else {
|
} else {
|
||||||
|
@ -976,7 +976,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(t) if t.category_is(TC::BinOp) || t.category_is(TC::UnaryOp) => {
|
Some(t) if t.category_is(TC::BinOp) || t.category_is(TC::UnaryOp) => {
|
||||||
log!("[DEBUG] error caused by: {}", fn_name!());
|
log!(info "error caused by: {}", fn_name!());
|
||||||
let err = ParseError::syntax_error(
|
let err = ParseError::syntax_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
t.loc(),
|
t.loc(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue