mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 04:09:05 +00:00
chore: add FreshNameGenerator
This commit is contained in:
parent
46cf002a71
commit
d6f30924f1
12 changed files with 84 additions and 62 deletions
|
@ -1,15 +1,33 @@
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
|
||||||
static VAR_ID: AtomicUsize = AtomicUsize::new(0);
|
use crate::Str;
|
||||||
|
|
||||||
pub fn fresh_varname() -> String {
|
#[derive(Debug, Default)]
|
||||||
VAR_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
pub struct FreshNameGenerator {
|
||||||
let i = VAR_ID.load(std::sync::atomic::Ordering::SeqCst);
|
id: AtomicUsize,
|
||||||
format!("%v{i}")
|
/// To avoid conflicts with variable names generated in another phase
|
||||||
|
prefix: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fresh_param_name() -> String {
|
impl FreshNameGenerator {
|
||||||
VAR_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
pub const fn new(prefix: &'static str) -> Self {
|
||||||
let i = VAR_ID.load(std::sync::atomic::Ordering::SeqCst);
|
Self {
|
||||||
format!("%p{i}")
|
id: AtomicUsize::new(0),
|
||||||
|
prefix,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fresh_varname(&self) -> Str {
|
||||||
|
self.id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
let i = self.id.load(std::sync::atomic::Ordering::SeqCst);
|
||||||
|
Str::from(format!("%v_{}_{i}", self.prefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fresh_param_name(&self) -> Str {
|
||||||
|
self.id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
let i = self.id.load(std::sync::atomic::Ordering::SeqCst);
|
||||||
|
Str::from(format!("%p_{}_{i}", self.prefix))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static FRESH_GEN: FreshNameGenerator = FreshNameGenerator::new("global");
|
||||||
|
|
|
@ -10,6 +10,7 @@ use erg_common::cache::CacheSet;
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
use erg_common::env::erg_std_path;
|
use erg_common::env::erg_std_path;
|
||||||
use erg_common::error::{ErrorDisplay, Location};
|
use erg_common::error::{ErrorDisplay, Location};
|
||||||
|
use erg_common::fresh::FreshNameGenerator;
|
||||||
use erg_common::io::Input;
|
use erg_common::io::Input;
|
||||||
use erg_common::opcode::{CommonOpcode, CompareOp};
|
use erg_common::opcode::{CommonOpcode, CompareOp};
|
||||||
use erg_common::opcode308::Opcode308;
|
use erg_common::opcode308::Opcode308;
|
||||||
|
@ -39,7 +40,6 @@ use crate::hir::{
|
||||||
use crate::ty::value::ValueObj;
|
use crate::ty::value::ValueObj;
|
||||||
use crate::ty::{HasType, Type, TypeCode, TypePair, VisibilityModifier};
|
use crate::ty::{HasType, Type, TypeCode, TypePair, VisibilityModifier};
|
||||||
use crate::varinfo::VarInfo;
|
use crate::varinfo::VarInfo;
|
||||||
use erg_common::fresh::fresh_varname;
|
|
||||||
use AccessKind::*;
|
use AccessKind::*;
|
||||||
use Type::*;
|
use Type::*;
|
||||||
|
|
||||||
|
@ -172,6 +172,7 @@ pub struct PyCodeGenerator {
|
||||||
abc_loaded: bool,
|
abc_loaded: bool,
|
||||||
unit_size: usize,
|
unit_size: usize,
|
||||||
units: PyCodeGenStack,
|
units: PyCodeGenStack,
|
||||||
|
fresh_gen: FreshNameGenerator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PyCodeGenerator {
|
impl PyCodeGenerator {
|
||||||
|
@ -190,6 +191,7 @@ impl PyCodeGenerator {
|
||||||
abc_loaded: false,
|
abc_loaded: false,
|
||||||
unit_size: 0,
|
unit_size: 0,
|
||||||
units: PyCodeGenStack::empty(),
|
units: PyCodeGenStack::empty(),
|
||||||
|
fresh_gen: FreshNameGenerator::new("codegen"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1997,7 +1999,7 @@ impl PyCodeGenerator {
|
||||||
self.stack_inc_n(2);
|
self.stack_inc_n(2);
|
||||||
let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
|
let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
|
||||||
self.emit_with_block(lambda.body, params);
|
self.emit_with_block(lambda.body, params);
|
||||||
let stash = Identifier::private_with_line(Str::from(fresh_varname()), lambda_line);
|
let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
|
||||||
self.emit_store_instr(stash.clone(), Name);
|
self.emit_store_instr(stash.clone(), Name);
|
||||||
self.emit_load_const(ValueObj::None);
|
self.emit_load_const(ValueObj::None);
|
||||||
self.emit_load_const(ValueObj::None);
|
self.emit_load_const(ValueObj::None);
|
||||||
|
@ -2046,7 +2048,7 @@ impl PyCodeGenerator {
|
||||||
self.stack_inc_n(2);
|
self.stack_inc_n(2);
|
||||||
let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
|
let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
|
||||||
self.emit_with_block(lambda.body, params);
|
self.emit_with_block(lambda.body, params);
|
||||||
let stash = Identifier::private_with_line(Str::from(fresh_varname()), lambda_line);
|
let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
|
||||||
self.emit_store_instr(stash.clone(), Name);
|
self.emit_store_instr(stash.clone(), Name);
|
||||||
self.write_instr(POP_BLOCK);
|
self.write_instr(POP_BLOCK);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
|
@ -2099,7 +2101,7 @@ impl PyCodeGenerator {
|
||||||
// self.stack_inc_n(2);
|
// self.stack_inc_n(2);
|
||||||
let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
|
let lambda_line = lambda.body.last().unwrap().ln_begin().unwrap_or(0);
|
||||||
self.emit_with_block(lambda.body, params);
|
self.emit_with_block(lambda.body, params);
|
||||||
let stash = Identifier::private_with_line(Str::from(fresh_varname()), lambda_line);
|
let stash = Identifier::private_with_line(self.fresh_gen.fresh_varname(), lambda_line);
|
||||||
self.emit_store_instr(stash.clone(), Name);
|
self.emit_store_instr(stash.clone(), Name);
|
||||||
self.write_instr(POP_BLOCK);
|
self.write_instr(POP_BLOCK);
|
||||||
self.write_arg(0);
|
self.write_arg(0);
|
||||||
|
@ -2849,9 +2851,9 @@ impl PyCodeGenerator {
|
||||||
let (param_name, params) = if let Some(new_first_param) = new_first_param {
|
let (param_name, params) = if let Some(new_first_param) = new_first_param {
|
||||||
let param_name = new_first_param
|
let param_name = new_first_param
|
||||||
.name()
|
.name()
|
||||||
.map(|s| s.to_string())
|
.cloned()
|
||||||
.unwrap_or_else(fresh_varname);
|
.unwrap_or_else(|| self.fresh_gen.fresh_varname());
|
||||||
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line);
|
let param = VarName::from_str_and_line(param_name.clone(), line);
|
||||||
let raw =
|
let raw =
|
||||||
erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
|
erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None);
|
||||||
let vi = VarInfo::nd_parameter(
|
let vi = VarInfo::nd_parameter(
|
||||||
|
@ -2932,9 +2934,9 @@ impl PyCodeGenerator {
|
||||||
if let Some(new_first_param) = ident.vi.t.non_default_params().unwrap().first() {
|
if let Some(new_first_param) = ident.vi.t.non_default_params().unwrap().first() {
|
||||||
let param_name = new_first_param
|
let param_name = new_first_param
|
||||||
.name()
|
.name()
|
||||||
.map(|s| s.to_string())
|
.cloned()
|
||||||
.unwrap_or_else(fresh_varname);
|
.unwrap_or_else(|| self.fresh_gen.fresh_varname());
|
||||||
let param = VarName::from_str_and_line(Str::from(param_name.clone()), line);
|
let param = VarName::from_str_and_line(param_name.clone(), line);
|
||||||
let vi = VarInfo::nd_parameter(
|
let vi = VarInfo::nd_parameter(
|
||||||
new_first_param.typ().clone(),
|
new_first_param.typ().clone(),
|
||||||
ident.vi.def_loc.clone(),
|
ident.vi.def_loc.clone(),
|
||||||
|
@ -2947,8 +2949,7 @@ impl PyCodeGenerator {
|
||||||
let bounds = TypeBoundSpecs::empty();
|
let bounds = TypeBoundSpecs::empty();
|
||||||
let sig = SubrSignature::new(ident, bounds, params, sig.t_spec_with_op().cloned());
|
let sig = SubrSignature::new(ident, bounds, params, sig.t_spec_with_op().cloned());
|
||||||
let arg = PosArg::new(Expr::Accessor(Accessor::private_with_line(
|
let arg = PosArg::new(Expr::Accessor(Accessor::private_with_line(
|
||||||
Str::from(param_name),
|
param_name, line,
|
||||||
line,
|
|
||||||
)));
|
)));
|
||||||
let call = class_new.call_expr(Args::single(arg));
|
let call = class_new.call_expr(Args::single(arg));
|
||||||
let block = Block::new(vec![call]);
|
let block = Block::new(vec![call]);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use erg_common::consts::{ERG_MODE, PYTHON_MODE};
|
use erg_common::consts::{ERG_MODE, PYTHON_MODE};
|
||||||
|
use erg_common::fresh::FRESH_GEN;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
use erg_common::Str as StrStruct;
|
|
||||||
|
|
||||||
use crate::ty::constructors::*;
|
use crate::ty::constructors::*;
|
||||||
use crate::ty::typaram::TyParam;
|
use crate::ty::typaram::TyParam;
|
||||||
|
@ -1233,7 +1233,7 @@ impl Context {
|
||||||
mut_type,
|
mut_type,
|
||||||
);
|
);
|
||||||
array_.register_trait(arr_t.clone(), array_mutizable);
|
array_.register_trait(arr_t.clone(), array_mutizable);
|
||||||
let var = StrStruct::from(fresh_varname());
|
let var = FRESH_GEN.fresh_varname();
|
||||||
let input = refinement(
|
let input = refinement(
|
||||||
var.clone(),
|
var.clone(),
|
||||||
Nat,
|
Nat,
|
||||||
|
|
|
@ -16,7 +16,6 @@ use erg_common::config::ErgConfig;
|
||||||
use erg_common::consts::{DEBUG_MODE, ERG_MODE, PYTHON_MODE};
|
use erg_common::consts::{DEBUG_MODE, ERG_MODE, PYTHON_MODE};
|
||||||
use erg_common::dict;
|
use erg_common::dict;
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
use erg_common::fresh::fresh_varname;
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::option::Option;
|
use std::option::Option;
|
||||||
|
|
||||||
use erg_common::fresh::fresh_varname;
|
use erg_common::fresh::FRESH_GEN;
|
||||||
use erg_common::traits::Locational;
|
use erg_common::traits::Locational;
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
@ -576,7 +576,7 @@ impl Context {
|
||||||
match target {
|
match target {
|
||||||
TyParam::FreeVar(fv) => {
|
TyParam::FreeVar(fv) => {
|
||||||
if let Ok(evaled) = self.eval_tp(value.clone()) {
|
if let Ok(evaled) = self.eval_tp(value.clone()) {
|
||||||
let pred = Predicate::ge(fresh_varname().into(), evaled);
|
let pred = Predicate::ge(FRESH_GEN.fresh_varname(), evaled);
|
||||||
let new_type = self.type_from_pred(pred);
|
let new_type = self.type_from_pred(pred);
|
||||||
let new_constr = Constraint::new_type_of(Type::from(new_type));
|
let new_constr = Constraint::new_type_of(Type::from(new_type));
|
||||||
fv.update_constraint(new_constr, false);
|
fv.update_constraint(new_constr, false);
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::mem;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use erg_common::config::ErgConfig;
|
use erg_common::config::ErgConfig;
|
||||||
|
use erg_common::fresh::FreshNameGenerator;
|
||||||
use erg_common::pathutil::squash;
|
use erg_common::pathutil::squash;
|
||||||
use erg_common::traits::Locational;
|
use erg_common::traits::Locational;
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
|
@ -13,7 +14,6 @@ use erg_parser::token::{Token, TokenKind, DOT, EQUAL};
|
||||||
use crate::ty::typaram::TyParam;
|
use crate::ty::typaram::TyParam;
|
||||||
use crate::ty::value::ValueObj;
|
use crate::ty::value::ValueObj;
|
||||||
use crate::ty::HasType;
|
use crate::ty::HasType;
|
||||||
use erg_common::fresh::fresh_varname;
|
|
||||||
|
|
||||||
use crate::hir::*;
|
use crate::hir::*;
|
||||||
use crate::module::SharedModuleCache;
|
use crate::module::SharedModuleCache;
|
||||||
|
@ -23,11 +23,16 @@ use crate::module::SharedModuleCache;
|
||||||
pub struct HIRLinker<'a> {
|
pub struct HIRLinker<'a> {
|
||||||
cfg: &'a ErgConfig,
|
cfg: &'a ErgConfig,
|
||||||
mod_cache: &'a SharedModuleCache,
|
mod_cache: &'a SharedModuleCache,
|
||||||
|
fresh_gen: FreshNameGenerator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HIRLinker<'a> {
|
impl<'a> HIRLinker<'a> {
|
||||||
pub fn new(cfg: &'a ErgConfig, mod_cache: &'a SharedModuleCache) -> Self {
|
pub fn new(cfg: &'a ErgConfig, mod_cache: &'a SharedModuleCache) -> Self {
|
||||||
Self { cfg, mod_cache }
|
Self {
|
||||||
|
cfg,
|
||||||
|
mod_cache,
|
||||||
|
fresh_gen: FreshNameGenerator::new("hir_linker"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link(&self, mut main: HIR) -> HIR {
|
pub fn link(&self, mut main: HIR) -> HIR {
|
||||||
|
@ -351,7 +356,7 @@ impl<'a> HIRLinker<'a> {
|
||||||
Expr::Accessor(Accessor::private_with_line(Str::ever("#ModuleType"), line));
|
Expr::Accessor(Accessor::private_with_line(Str::ever("#ModuleType"), line));
|
||||||
let args = Args::single(PosArg::new(mod_name.clone()));
|
let args = Args::single(PosArg::new(mod_name.clone()));
|
||||||
let block = Block::new(vec![module_type.call_expr(args)]);
|
let block = Block::new(vec![module_type.call_expr(args)]);
|
||||||
let tmp = Identifier::private_with_line(Str::from(fresh_varname()), line);
|
let tmp = Identifier::private_with_line(self.fresh_gen.fresh_varname(), line);
|
||||||
let mod_def = Expr::Def(Def::new(
|
let mod_def = Expr::Def(Def::new(
|
||||||
Signature::Var(VarSignature::new(tmp.clone(), None)),
|
Signature::Var(VarSignature::new(tmp.clone(), None)),
|
||||||
DefBody::new(EQUAL, block, DefId(0)),
|
DefBody::new(EQUAL, block, DefId(0)),
|
||||||
|
|
|
@ -8,7 +8,7 @@ use erg_common::consts::{ERG_MODE, PYTHON_MODE};
|
||||||
use erg_common::dict;
|
use erg_common::dict;
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::{Location, MultiErrorDisplay};
|
use erg_common::error::{Location, MultiErrorDisplay};
|
||||||
use erg_common::fresh::fresh_varname;
|
use erg_common::fresh::FreshNameGenerator;
|
||||||
use erg_common::set;
|
use erg_common::set;
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
use erg_common::traits::{ExitStatus, Locational, NoTypeDisplay, Runnable, Stream};
|
use erg_common::traits::{ExitStatus, Locational, NoTypeDisplay, Runnable, Stream};
|
||||||
|
@ -75,6 +75,7 @@ pub struct ASTLowerer {
|
||||||
pub(crate) module: ModuleContext,
|
pub(crate) module: ModuleContext,
|
||||||
pub(crate) errs: LowerErrors,
|
pub(crate) errs: LowerErrors,
|
||||||
pub(crate) warns: LowerWarnings,
|
pub(crate) warns: LowerWarnings,
|
||||||
|
fresh_gen: FreshNameGenerator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ASTLowerer {
|
impl Default for ASTLowerer {
|
||||||
|
@ -177,6 +178,7 @@ impl ASTLowerer {
|
||||||
cfg,
|
cfg,
|
||||||
errs: LowerErrors::empty(),
|
errs: LowerErrors::empty(),
|
||||||
warns: LowerWarnings::empty(),
|
warns: LowerWarnings::empty(),
|
||||||
|
fresh_gen: FreshNameGenerator::new("lower"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +188,7 @@ impl ASTLowerer {
|
||||||
module,
|
module,
|
||||||
errs: LowerErrors::empty(),
|
errs: LowerErrors::empty(),
|
||||||
warns: LowerWarnings::empty(),
|
warns: LowerWarnings::empty(),
|
||||||
|
fresh_gen: FreshNameGenerator::new("lower"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,7 +757,7 @@ impl ASTLowerer {
|
||||||
TokenKind::Gre => {
|
TokenKind::Gre => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
let t = value.class();
|
let t = value.class();
|
||||||
let varname = Str::from(fresh_varname());
|
let varname = self.fresh_gen.fresh_varname();
|
||||||
let pred = Predicate::gt(varname.clone(), TyParam::value(value));
|
let pred = Predicate::gt(varname.clone(), TyParam::value(value));
|
||||||
let refine = refinement(varname, t, pred);
|
let refine = refinement(varname, t, pred);
|
||||||
Some(guard(var, refine))
|
Some(guard(var, refine))
|
||||||
|
@ -762,7 +765,7 @@ impl ASTLowerer {
|
||||||
TokenKind::GreEq => {
|
TokenKind::GreEq => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
let t = value.class();
|
let t = value.class();
|
||||||
let varname = Str::from(fresh_varname());
|
let varname = self.fresh_gen.fresh_varname();
|
||||||
let pred = Predicate::ge(varname.clone(), TyParam::value(value));
|
let pred = Predicate::ge(varname.clone(), TyParam::value(value));
|
||||||
let refine = refinement(varname, t, pred);
|
let refine = refinement(varname, t, pred);
|
||||||
Some(guard(var, refine))
|
Some(guard(var, refine))
|
||||||
|
@ -770,7 +773,7 @@ impl ASTLowerer {
|
||||||
TokenKind::Less => {
|
TokenKind::Less => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
let t = value.class();
|
let t = value.class();
|
||||||
let varname = Str::from(fresh_varname());
|
let varname = self.fresh_gen.fresh_varname();
|
||||||
let pred = Predicate::lt(varname.clone(), TyParam::value(value));
|
let pred = Predicate::lt(varname.clone(), TyParam::value(value));
|
||||||
let refine = refinement(varname, t, pred);
|
let refine = refinement(varname, t, pred);
|
||||||
Some(guard(var, refine))
|
Some(guard(var, refine))
|
||||||
|
@ -778,7 +781,7 @@ impl ASTLowerer {
|
||||||
TokenKind::LessEq => {
|
TokenKind::LessEq => {
|
||||||
let value = self.module.context.expr_to_value(rhs.clone())?;
|
let value = self.module.context.expr_to_value(rhs.clone())?;
|
||||||
let t = value.class();
|
let t = value.class();
|
||||||
let varname = Str::from(fresh_varname());
|
let varname = self.fresh_gen.fresh_varname();
|
||||||
let pred = Predicate::le(varname.clone(), TyParam::value(value));
|
let pred = Predicate::le(varname.clone(), TyParam::value(value));
|
||||||
let refine = refinement(varname, t, pred);
|
let refine = refinement(varname, t, pred);
|
||||||
Some(guard(var, refine))
|
Some(guard(var, refine))
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use erg_common::fresh::FRESH_GEN;
|
||||||
|
|
||||||
use crate::ty::*;
|
use crate::ty::*;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -92,7 +94,7 @@ pub fn v_enum(s: Set<ValueObj>) -> Type {
|
||||||
if !is_homogeneous(&s) {
|
if !is_homogeneous(&s) {
|
||||||
panic!("{s} is not homogeneous");
|
panic!("{s} is not homogeneous");
|
||||||
}
|
}
|
||||||
let name = Str::from(fresh_varname());
|
let name = FRESH_GEN.fresh_varname();
|
||||||
let t = inner_class(&s);
|
let t = inner_class(&s);
|
||||||
let preds = s
|
let preds = s
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -103,7 +105,7 @@ pub fn v_enum(s: Set<ValueObj>) -> Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tp_enum(ty: Type, s: Set<TyParam>) -> Type {
|
pub fn tp_enum(ty: Type, s: Set<TyParam>) -> Type {
|
||||||
let name = Str::from(fresh_varname());
|
let name = FRESH_GEN.fresh_varname();
|
||||||
let preds = s
|
let preds = s
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|tp| Predicate::eq(name.clone(), tp))
|
.map(|tp| Predicate::eq(name.clone(), tp))
|
||||||
|
@ -113,7 +115,7 @@ pub fn tp_enum(ty: Type, s: Set<TyParam>) -> Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn singleton(ty: Type, tp: TyParam) -> Type {
|
pub fn singleton(ty: Type, tp: TyParam) -> Type {
|
||||||
let name = Str::from(fresh_varname());
|
let name = FRESH_GEN.fresh_varname();
|
||||||
let preds = Predicate::eq(name.clone(), tp);
|
let preds = Predicate::eq(name.clone(), tp);
|
||||||
let refine = RefinementType::new(name, ty, preds);
|
let refine = RefinementType::new(name, ty, preds);
|
||||||
Type::Refinement(refine)
|
Type::Refinement(refine)
|
||||||
|
@ -129,7 +131,7 @@ where
|
||||||
{
|
{
|
||||||
let l = l.try_into().unwrap_or_else(|l| todo!("{l:?}"));
|
let l = l.try_into().unwrap_or_else(|l| todo!("{l:?}"));
|
||||||
let r = r.try_into().unwrap_or_else(|r| todo!("{r:?}"));
|
let r = r.try_into().unwrap_or_else(|r| todo!("{r:?}"));
|
||||||
let name = Str::from(fresh_varname());
|
let name = FRESH_GEN.fresh_varname();
|
||||||
let pred = match op {
|
let pred = match op {
|
||||||
IntervalOp::LeftOpen if l == TyParam::value(NegInf) => Predicate::le(name.clone(), r),
|
IntervalOp::LeftOpen if l == TyParam::value(NegInf) => Predicate::le(name.clone(), r),
|
||||||
// l<..r => {I: classof(l) | I >= l+ε and I <= r}
|
// l<..r => {I: classof(l) | I >= l+ε and I <= r}
|
||||||
|
|
|
@ -20,7 +20,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
use erg_common::fresh::fresh_varname;
|
use erg_common::fresh::FRESH_GEN;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
|
@ -2296,7 +2296,7 @@ impl Type {
|
||||||
match self {
|
match self {
|
||||||
Type::FreeVar(fv) if fv.is_linked() => fv.crack().clone().into_refinement(),
|
Type::FreeVar(fv) if fv.is_linked() => fv.crack().clone().into_refinement(),
|
||||||
Type::Nat => {
|
Type::Nat => {
|
||||||
let var = Str::from(fresh_varname());
|
let var = FRESH_GEN.fresh_varname();
|
||||||
RefinementType::new(
|
RefinementType::new(
|
||||||
var.clone(),
|
var.clone(),
|
||||||
Type::Int,
|
Type::Int,
|
||||||
|
@ -2304,7 +2304,7 @@ impl Type {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Type::Bool => {
|
Type::Bool => {
|
||||||
let var = Str::from(fresh_varname());
|
let var = FRESH_GEN.fresh_varname();
|
||||||
RefinementType::new(
|
RefinementType::new(
|
||||||
var.clone(),
|
var.clone(),
|
||||||
Type::Int,
|
Type::Int,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
use erg_common::error::{ErrorCore, ErrorKind, Location};
|
||||||
use erg_common::fresh::fresh_varname;
|
use erg_common::fresh::FRESH_GEN;
|
||||||
use erg_common::io::Input;
|
use erg_common::io::Input;
|
||||||
use erg_common::python_util::PythonVersion;
|
use erg_common::python_util::PythonVersion;
|
||||||
use erg_common::serialize::*;
|
use erg_common::serialize::*;
|
||||||
|
@ -714,7 +714,7 @@ impl HasType for ValueObj {
|
||||||
/// その要素だけの集合型を返す、クラスが欲しい場合は.classで
|
/// その要素だけの集合型を返す、クラスが欲しい場合は.classで
|
||||||
#[inline]
|
#[inline]
|
||||||
fn t(&self) -> Type {
|
fn t(&self) -> Type {
|
||||||
let name = Str::from(fresh_varname());
|
let name = FRESH_GEN.fresh_varname();
|
||||||
let pred = Predicate::eq(name.clone(), TyParam::Value(self.clone()));
|
let pred = Predicate::eq(name.clone(), TyParam::Value(self.clone()));
|
||||||
refinement(name, self.class(), pred)
|
refinement(name, self.class(), pred)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
//! Syntax sugarをdesugarする
|
//! Syntax sugarをdesugarする
|
||||||
//! e.g. Literal parameters, Multi assignment
|
//! e.g. Literal parameters, Multi assignment
|
||||||
//! 型チェックなどによる検証は行わない
|
//! 型チェックなどによる検証は行わない
|
||||||
use std::sync::atomic::AtomicUsize;
|
|
||||||
|
|
||||||
|
use erg_common::fresh::FreshNameGenerator;
|
||||||
use erg_common::traits::{Locational, Stream};
|
use erg_common::traits::{Locational, Stream};
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
use erg_common::{enum_unwrap, get_hash, log, set};
|
use erg_common::{enum_unwrap, get_hash, log, set};
|
||||||
|
@ -32,24 +32,17 @@ enum BufIndex<'i> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Desugarer {
|
pub struct Desugarer {
|
||||||
// _desugared: Set<Str>,
|
// _desugared: Set<Str>,
|
||||||
var_id: AtomicUsize,
|
var_gen: FreshNameGenerator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Desugarer {
|
impl Desugarer {
|
||||||
pub fn new() -> Desugarer {
|
pub fn new() -> Desugarer {
|
||||||
Self {
|
Self {
|
||||||
// _desugared: Set::default(),
|
// _desugared: Set::default(),
|
||||||
var_id: AtomicUsize::new(0),
|
var_gen: FreshNameGenerator::new("desugar"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fresh_varname(&self) -> String {
|
|
||||||
let i = self.var_id.load(std::sync::atomic::Ordering::SeqCst);
|
|
||||||
self.var_id
|
|
||||||
.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
|
||||||
format!("%v{i}")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn desugar(&mut self, module: Module) -> Module {
|
pub fn desugar(&mut self, module: Module) -> Module {
|
||||||
log!(info "the desugaring process has started.");
|
log!(info "the desugaring process has started.");
|
||||||
let module = self.desugar_multiple_pattern_def(module);
|
let module = self.desugar_multiple_pattern_def(module);
|
||||||
|
@ -517,10 +510,10 @@ impl Desugarer {
|
||||||
let sig = LambdaSignature::new(params, return_t_spec.clone(), sig.bounds);
|
let sig = LambdaSignature::new(params, return_t_spec.clone(), sig.bounds);
|
||||||
let second_branch = Lambda::new(sig, op, def.body.block, def.body.id);
|
let second_branch = Lambda::new(sig, op, def.body.block, def.body.id);
|
||||||
let first_arg = if params_len == 1 {
|
let first_arg = if params_len == 1 {
|
||||||
Expr::dummy_local(&self.fresh_varname())
|
Expr::dummy_local(&self.var_gen.fresh_varname())
|
||||||
} else {
|
} else {
|
||||||
let args =
|
let args = (0..params_len)
|
||||||
(0..params_len).map(|_| PosArg::new(Expr::dummy_local(&self.fresh_varname())));
|
.map(|_| PosArg::new(Expr::dummy_local(&self.var_gen.fresh_varname())));
|
||||||
Expr::Tuple(Tuple::Normal(NormalTuple::new(Args::pos_only(
|
Expr::Tuple(Tuple::Normal(NormalTuple::new(Args::pos_only(
|
||||||
args.collect(),
|
args.collect(),
|
||||||
None,
|
None,
|
||||||
|
@ -547,8 +540,8 @@ impl Desugarer {
|
||||||
&mut self,
|
&mut self,
|
||||||
line: u32,
|
line: u32,
|
||||||
t_spec: Option<TypeSpecWithOp>,
|
t_spec: Option<TypeSpecWithOp>,
|
||||||
) -> (String, Signature) {
|
) -> (Str, Signature) {
|
||||||
let buf_name = self.fresh_varname();
|
let buf_name = self.var_gen.fresh_varname();
|
||||||
let buf_sig = Signature::Var(VarSignature::new(
|
let buf_sig = Signature::Var(VarSignature::new(
|
||||||
VarPattern::Ident(Identifier::private_with_line(Str::rc(&buf_name), line)),
|
VarPattern::Ident(Identifier::private_with_line(Str::rc(&buf_name), line)),
|
||||||
t_spec,
|
t_spec,
|
||||||
|
@ -556,8 +549,8 @@ impl Desugarer {
|
||||||
(buf_name, buf_sig)
|
(buf_name, buf_sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_buf_nd_param(&mut self, line: u32) -> (String, ParamPattern) {
|
fn gen_buf_nd_param(&mut self, line: u32) -> (Str, ParamPattern) {
|
||||||
let buf_name = self.fresh_varname();
|
let buf_name = self.var_gen.fresh_varname();
|
||||||
let pat = ParamPattern::VarName(VarName::from_str_and_line(Str::rc(&buf_name), line));
|
let pat = ParamPattern::VarName(VarName::from_str_and_line(Str::rc(&buf_name), line));
|
||||||
(buf_name, pat)
|
(buf_name, pat)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Implements `Parser` for Erg. `Parser` parses the source code to generate `AST`,
|
//! Implements `Parser` for Erg. `Parser` parses the source code to generate `AST`.
|
||||||
//! and performs type checking and other optimizations if necessary.
|
//! The generated `AST`s are guaranteed to be identical if the source code is identical.
|
||||||
|
//! However, identical `AST`s may be generated even if the source code is (a bit) different.
|
||||||
#![allow(clippy::large_enum_variant)]
|
#![allow(clippy::large_enum_variant)]
|
||||||
extern crate erg_common;
|
extern crate erg_common;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue