mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
WIP
This commit is contained in:
commit
befe2cf835
15 changed files with 148 additions and 59 deletions
58
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
58
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
name: 🐛 Bug report
|
||||
description: Create a report to help us improve
|
||||
labels:
|
||||
- bug
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Reproducible code
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected result
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Actual result
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Erg version
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Python version
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: os
|
||||
options:
|
||||
- Windows 10
|
||||
- Windows 11
|
||||
- MacOS 12 (Monterey)
|
||||
- MacOS 11 (Big Sur)
|
||||
- Ubuntu
|
||||
- Linux(other distro)
|
||||
- Other (write in `Additional context`)
|
|
@ -1,13 +1,13 @@
|
|||
[package]
|
||||
name = "erg_common"
|
||||
version = "0.5.8"
|
||||
description = "A common components library of Erg"
|
||||
authors = ["erg-lang team <moderation.erglang@gmail.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/erg-lang/erg/tree/main/src/erg_common"
|
||||
documentation = "https://docs.rs/erg_common"
|
||||
homepage = "https://erg-lang.github.io/"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
documentation.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
|
@ -12,10 +12,18 @@ homepage.workspace = true
|
|||
|
||||
[features]
|
||||
# when "debug" feature is turned on, that of parser will also be turned on.
|
||||
debug = [ "erg_common/debug", "erg_parser/debug", "erg_type/debug" ]
|
||||
japanese = [ "erg_common/japanese", "erg_parser/japanese", "erg_type/japanese" ]
|
||||
simplified_chinese = [ "erg_common/simplified_chinese", "erg_parser/simplified_chinese", "erg_type/simplified_chinese" ]
|
||||
traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditional_chinese", "erg_type/traditional_chinese" ]
|
||||
debug = ["erg_common/debug", "erg_parser/debug", "erg_type/debug"]
|
||||
japanese = ["erg_common/japanese", "erg_parser/japanese", "erg_type/japanese"]
|
||||
simplified_chinese = [
|
||||
"erg_common/simplified_chinese",
|
||||
"erg_parser/simplified_chinese",
|
||||
"erg_type/simplified_chinese",
|
||||
]
|
||||
traditional_chinese = [
|
||||
"erg_common/traditional_chinese",
|
||||
"erg_parser/traditional_chinese",
|
||||
"erg_type/traditional_chinese",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
erg_common = { version = "0.5.8", path = "../erg_common" }
|
||||
|
|
|
@ -2040,7 +2040,7 @@ impl CodeGenerator {
|
|||
self.stack_dec();
|
||||
self.emit_pop_top();
|
||||
self.emit_global_import_items(
|
||||
Identifier::public("prelude"),
|
||||
Identifier::public("_erg_std_prelude"),
|
||||
vec![(
|
||||
Identifier::public("in_operator"),
|
||||
Some(Identifier::private("#in_operator")),
|
||||
|
|
|
@ -850,6 +850,9 @@ impl Context {
|
|||
|
||||
/// returns union of two types (A or B)
|
||||
pub(crate) fn union(&self, lhs: &Type, rhs: &Type) -> Type {
|
||||
if lhs == rhs {
|
||||
return lhs.clone();
|
||||
}
|
||||
// `?T or ?U` will not be unified
|
||||
// `Set!(?T, 3) or Set(?T, 3)` wii be unified to Set(?T, 3)
|
||||
if !lhs.is_unbound_var() && !rhs.is_unbound_var() {
|
||||
|
@ -889,6 +892,9 @@ impl Context {
|
|||
|
||||
/// returns intersection of two types (A and B)
|
||||
pub(crate) fn intersection(&self, lhs: &Type, rhs: &Type) -> Type {
|
||||
if lhs == rhs {
|
||||
return lhs.clone();
|
||||
}
|
||||
// ?T and ?U will not be unified
|
||||
if !lhs.is_unbound_var() && !rhs.is_unbound_var() {
|
||||
match (self.supertype_of(lhs, rhs), self.subtype_of(lhs, rhs)) {
|
||||
|
|
|
@ -1373,6 +1373,10 @@ impl Context {
|
|||
let mut record_type = Self::builtin_mono_class("RecordType", 2);
|
||||
record_type.register_superclass(builtin_mono("Record"), &record);
|
||||
record_type.register_superclass(builtin_mono("Type"), &type_);
|
||||
/* Or (true or type) */
|
||||
let or_t = builtin_poly("Or", vec![ty_tp(mono_q("L")), ty_tp(mono_q("R"))]);
|
||||
let mut or = Self::builtin_poly_class("Or", vec![PS::t_nd("L"), PS::t_nd("R")], 2);
|
||||
or.register_superclass(Obj, &obj);
|
||||
/* Float_mut */
|
||||
let mut float_mut = Self::builtin_mono_class("Float!", 2);
|
||||
float_mut.register_superclass(Float, &float);
|
||||
|
@ -1744,6 +1748,7 @@ impl Context {
|
|||
);
|
||||
self.register_builtin_type(builtin_mono("Record"), record, Const);
|
||||
self.register_builtin_type(builtin_mono("RecordType"), record_type, Const);
|
||||
self.register_builtin_type(or_t, or, Const);
|
||||
self.register_builtin_type(builtin_mono("Int!"), int_mut, Const);
|
||||
self.register_builtin_type(builtin_mono("Nat!"), nat_mut, Const);
|
||||
self.register_builtin_type(builtin_mono("Float!"), float_mut, Const);
|
||||
|
|
|
@ -17,7 +17,7 @@ use erg_parser::ast::{self, Identifier};
|
|||
use erg_parser::token::Token;
|
||||
|
||||
use erg_type::constructors::{
|
||||
anon, builtin_mono, free_var, func, module, mono_proj, subr_t, v_enum,
|
||||
anon, builtin_mono, builtin_poly, free_var, func, module, mono_proj, subr_t, v_enum,
|
||||
};
|
||||
use erg_type::free::Constraint;
|
||||
use erg_type::typaram::TyParam;
|
||||
|
@ -1454,7 +1454,7 @@ impl Context {
|
|||
}
|
||||
Type::Poly { path, name, .. } => {
|
||||
if self.path() == path {
|
||||
if let Some((_, ctx)) = self.rec_get_mono_type(name) {
|
||||
if let Some((_, ctx)) = self.rec_get_poly_type(name) {
|
||||
return Some(ctx);
|
||||
}
|
||||
}
|
||||
|
@ -1469,7 +1469,7 @@ impl Context {
|
|||
.and_then(|cache| cache.ref_ctx(path.as_path()))
|
||||
})
|
||||
{
|
||||
if let Some((_, ctx)) = ctx.rec_get_mono_type(name) {
|
||||
if let Some((_, ctx)) = ctx.rec_get_poly_type(name) {
|
||||
return Some(ctx);
|
||||
}
|
||||
}
|
||||
|
@ -1516,16 +1516,10 @@ impl Context {
|
|||
return Some(res);
|
||||
}
|
||||
}
|
||||
Type::Or(l, r) => {
|
||||
let lctx = self.get_nominal_type_ctx(l)?;
|
||||
let rctx = self.get_nominal_type_ctx(r)?;
|
||||
// use smaller context
|
||||
return match (self.supertype_of(l, r), self.supertype_of(r, l)) {
|
||||
(true, true) => Some(lctx),
|
||||
(true, false) => Some(rctx),
|
||||
(false, true) => Some(lctx),
|
||||
(false, false) => None,
|
||||
};
|
||||
Type::Or(_l, _r) => {
|
||||
if let Some(ctx) = self.get_nominal_type_ctx(&builtin_poly("Or", vec![])) {
|
||||
return Some(ctx);
|
||||
}
|
||||
}
|
||||
// FIXME: `F()`などの場合、実際は引数が省略されていてもmonomorphicになる
|
||||
other if other.is_monomorphic() => {
|
||||
|
|
|
@ -2,7 +2,8 @@ discard _x = None
|
|||
|
||||
discard 1
|
||||
|
||||
cond c, then, else =
|
||||
# if: |T, U|(Bool, T, U) -> T or U
|
||||
cond|T: Type|(c: Bool, then: T, else: T): T =
|
||||
if c:
|
||||
do then
|
||||
do else
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
[package]
|
||||
name = "erg_parser"
|
||||
version = "0.5.8"
|
||||
description = "The Erg parser"
|
||||
authors = ["erg-lang team <moderation.erglang@gmail.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/erg-lang/erg/tree/main/src/erg_compiler/erg_parser"
|
||||
documentation = "https://docs.rs/erg_parser"
|
||||
homepage = "https://erg-lang.github.io/"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
documentation.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
[features]
|
||||
debug = [ "erg_common/debug" ]
|
||||
japanese = [ "erg_common/japanese" ]
|
||||
simplified_chinese = [ "erg_common/simplified_chinese" ]
|
||||
traditional_chinese = [ "erg_common/traditional_chinese" ]
|
||||
debug = ["erg_common/debug"]
|
||||
japanese = ["erg_common/japanese"]
|
||||
simplified_chinese = ["erg_common/simplified_chinese"]
|
||||
traditional_chinese = ["erg_common/traditional_chinese"]
|
||||
|
||||
[dependencies]
|
||||
erg_common = { version = "0.5.8", path = "../erg_common" }
|
||||
|
|
|
@ -469,7 +469,8 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
}
|
||||
Some(t) if t.is(LSqBr) => {
|
||||
// x[...] (`x [...]` will interpreted as `x([...])`)
|
||||
Some(t) if t.is(LSqBr) && acc.col_end().unwrap() == t.col_begin().unwrap() => {
|
||||
self.skip();
|
||||
let index = self
|
||||
.try_reduce_expr(false, false)
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
[package]
|
||||
name = "erg_type"
|
||||
version = "0.5.8"
|
||||
description = "APIs for Erg types"
|
||||
authors = ["erg-lang team <moderation.erglang@gmail.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/erg-lang/erg/tree/main/compiler/erg_type"
|
||||
documentation = "https://docs.rs/erg_type"
|
||||
homepage = "https://erg-lang.github.io/"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
documentation.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[features]
|
||||
debug = [ "erg_common/debug" ]
|
||||
japanese = [ "erg_common/japanese" ]
|
||||
simplified_chinese = [ "erg_common/simplified_chinese" ]
|
||||
traditional_chinese = [ "erg_common/traditional_chinese" ]
|
||||
debug = ["erg_common/debug"]
|
||||
japanese = ["erg_common/japanese"]
|
||||
simplified_chinese = ["erg_common/simplified_chinese"]
|
||||
traditional_chinese = ["erg_common/traditional_chinese"]
|
||||
|
||||
[dependencies]
|
||||
erg_common = { version = "0.5.8", path = "../erg_common" }
|
||||
|
|
|
@ -1922,11 +1922,6 @@ impl Type {
|
|||
matches!(self, Self::FreeVar(_))
|
||||
}
|
||||
|
||||
/// FIXME: `Int or Str` should be monomorphic
|
||||
pub fn is_monomorphic(&self) -> bool {
|
||||
matches!(self.typarams_len(), Some(0) | None)
|
||||
}
|
||||
|
||||
pub const fn is_callable(&self) -> bool {
|
||||
matches!(self, Self::Subr { .. } | Self::Callable { .. })
|
||||
}
|
||||
|
@ -1935,6 +1930,18 @@ impl Type {
|
|||
matches!(self, Self::FreeVar(fv) if fv.is_unbound() || fv.crack().is_unbound_var())
|
||||
}
|
||||
|
||||
/// See also: `is_monomorphized`
|
||||
pub fn is_monomorphic(&self) -> bool {
|
||||
matches!(self.typarams_len(), Some(0) | None)
|
||||
}
|
||||
|
||||
/// `Set(Int, 3)` is not monomorphic but monomorphized
|
||||
pub fn is_monomorphized(&self) -> bool {
|
||||
matches!(self.typarams_len(), Some(0) | None)
|
||||
|| (self.has_no_qvar() && self.has_no_unbound_var())
|
||||
}
|
||||
|
||||
/// if the type is polymorphic
|
||||
pub fn has_qvar(&self) -> bool {
|
||||
match self {
|
||||
Self::MonoQVar(_) | Self::PolyQVar { .. } => true,
|
||||
|
@ -1972,6 +1979,10 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn has_no_qvar(&self) -> bool {
|
||||
!self.has_qvar()
|
||||
}
|
||||
|
||||
pub fn is_cachable(&self) -> bool {
|
||||
match self {
|
||||
Self::FreeVar(_) => false,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
for! 1..<100, i =>
|
||||
match (i % 3, i % 5):
|
||||
(0, 0) => print! "FizzBuzz"
|
||||
(0, _) => print! "Fizz"
|
||||
(_, 0) => print! "Buzz"
|
||||
(_, _) => print! i
|
||||
match [i % 3, i % 5]:
|
||||
[0, 0] => print! "FizzBuzz"
|
||||
[0, _] => print! "Fizz"
|
||||
[_, 0] => print! "Buzz"
|
||||
[_, _] => print! i
|
||||
|
|
|
@ -56,6 +56,11 @@ fn exec_move_check() -> Result<(), ()> {
|
|||
expect_failure("examples/move_check.er")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_prelude() -> Result<(), ()> {
|
||||
expect_success("compiler/erg_compiler/std/prelude.er")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_quantified() -> Result<(), ()> {
|
||||
expect_success("examples/quantified.er")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue