Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translate the Japanese documents into English and some text corrections #87

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "erg"
version = "0.3.0"
version = "0.3.1"
description = "The Erg programming language"
authors = ["Shunsuke Shibayama <sbym1346@gmail.com>"]
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -47,8 +47,8 @@ traditional_chinese = [

[dependencies]
erg_common = { version = "0.3.0", path = "./compiler/erg_common" }
erg_parser = { version = "0.3.0", path = "./compiler/erg_parser" }
erg_compiler = { version = "0.3.0", path = "./compiler/erg_compiler" }
erg_parser = { version = "0.3.1", path = "./compiler/erg_parser" }
erg_compiler = { version = "0.3.1", path = "./compiler/erg_compiler" }
erg_type = { version = "0.3.0", path = "./compiler/erg_type" }

# [workspace]
Expand Down
2 changes: 1 addition & 1 deletion FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These are supported funding model platforms

github: mtshiba # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
github: erg-lang # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
Expand Down
4 changes: 2 additions & 2 deletions compiler/erg_compiler/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "erg_compiler"
version = "0.3.0"
version = "0.3.1"
description = "Centimetre: the Erg compiler"
authors = ["Shunsuke Shibayama <sbym1346@gmail.com>"]
license = "MIT OR Apache-2.0"
Expand All @@ -18,7 +18,7 @@ traditional_chinese = [ "erg_common/traditional_chinese", "erg_parser/traditiona

[dependencies]
erg_common = { version = "0.3.0", path = "../erg_common" }
erg_parser = { version = "0.3.0", path = "../erg_parser" }
erg_parser = { version = "0.3.1", path = "../erg_parser" }
erg_type = { version = "0.3.0", path = "../erg_type" }

[lib]
Expand Down
2 changes: 2 additions & 0 deletions compiler/erg_compiler/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,8 @@ impl CodeGenerator {
// no else block
let idx_end = self.cur_block().lasti;
self.edit_code(idx_pop_jump_if_false + 1, idx_end / 2);
self.emit_load_const(ValueObj::None);
self.stack_dec();
self.stack_dec();
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion compiler/erg_parser/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "erg_parser"
version = "0.3.0"
version = "0.3.1"
description = "The Erg parser"
authors = ["mtshiba <sbym1346@gmail.com>"]
license = "MIT OR Apache-2.0"
Expand Down
9 changes: 9 additions & 0 deletions compiler/erg_parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2269,6 +2269,15 @@ impl LambdaSignature {
bounds,
}
}

pub fn do_sig(do_symbol: &Token) -> Self {
let parens = Some((do_symbol.clone(), do_symbol.clone()));
Self::new(
Params::new(vec![], vec![], parens),
None,
TypeBoundSpecs::empty(),
)
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
Expand Down
43 changes: 43 additions & 0 deletions compiler/erg_parser/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ enum PosOrKwArg {
pub enum Side {
LhsAssign,
LhsLambda,
Do,
Rhs,
}

Expand Down Expand Up @@ -156,6 +157,15 @@ impl Parser {
/// `(Rhs) , (LhsLambda) ->`
/// `(Rhs) (LhsLambda) -> (Rhs);`
fn cur_side(&self) -> Side {
match self.peek() {
Some(t) => {
let name = &t.inspect()[..];
if name == "do" || name == "do!" {
return Side::Do;
}
}
_ => {}
}
// 以降に=, ->などがないならすべて右辺値
let opt_equal_pos = self.tokens.iter().skip(1).position(|t| t.is(Equal));
let opt_arrow_pos = self
Expand Down Expand Up @@ -1531,6 +1541,11 @@ impl Parser {
debug_call_info!(self);
match self.peek() {
Some(t) if t.is(Symbol) => {
if &t.inspect()[..] == "do" || &t.inspect()[..] == "do!" {
let lambda = self.try_reduce_do_block().map_err(|_| self.stack_dec())?;
self.level -= 1;
return Ok(PosOrKwArg::Pos(PosArg::new(Expr::Lambda(lambda))));
}
if self.nth_is(1, Colon) {
let acc = self.try_reduce_acc().map_err(|_| self.stack_dec())?;
debug_power_assert!(self.cur_is(Colon));
Expand Down Expand Up @@ -1651,6 +1666,29 @@ impl Parser {
Ok(Lambda::new(sig, op, body, self.counter))
}

fn try_reduce_do_block(&mut self) -> ParseResult<Lambda> {
debug_call_info!(self);
let do_symbol = self.lpop();
let sig = LambdaSignature::do_sig(&do_symbol);
let op = match &do_symbol.inspect()[..] {
"do" => Token::from_str(FuncArrow, "->"),
"do!" => Token::from_str(ProcArrow, "=>"),
_ => todo!(),
};
if self.cur_is(Colon) {
self.lpop();
let body = self.try_reduce_block().map_err(|_| self.stack_dec())?;
self.counter.inc();
self.level -= 1;
Ok(Lambda::new(sig, op, body, self.counter))
} else {
let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?;
let block = Block::new(vec![expr]);
self.level -= 1;
Ok(Lambda::new(sig, op, block, self.counter))
}
}

fn try_reduce_expr(&mut self) -> ParseResult<Expr> {
debug_call_info!(self);
let mut stack = Vec::<ExprOrOp>::new();
Expand All @@ -1665,6 +1703,11 @@ impl Parser {
self.level -= 1;
Ok(Expr::Lambda(lambda))
}
Side::Do => {
let lambda = self.try_reduce_do_block().map_err(|_| self.stack_dec())?;
self.level -= 1;
Ok(Expr::Lambda(lambda))
}
Side::Rhs => {
stack.push(ExprOrOp::Expr(
self.try_reduce_bin_lhs().map_err(|_| self.stack_dec())?,
Expand Down
2 changes: 1 addition & 1 deletion doc/EN/syntax/10_array.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ print! Typeof l[1..2] # [Int; 4]
```

<p align='center'>
<a href='./09_builtin_procs.md'>Previous</a> | <a href='./11_dict.md'>Next</a>
<a href='./09_builtin_procs.md'>Previous</a> | <a href='./11_tuple.md'>Next</a>
</p>
2 changes: 1 addition & 1 deletion doc/EN/syntax/17_mutability.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ In C, types and functions cannot be assigned to variables; int and main are iden
However, in Erg, "everything is an object". Not only functions and types, but even operators can be assigned to variables.

<p align='center'>
<a href='./16_iterator.md'>Previous</a> | <a href='./18_memory_management.md'>Next</a>
<a href='./16_iterator.md'>Previous</a> | <a href='./18_ownership.md'>Next</a>
</p>
2 changes: 1 addition & 1 deletion doc/EN/syntax/19_visibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,5 @@ _ = foo.record.a.z # OK
```

<p align='center'>
<a href='./18_memory_management.md'>Previous</a> | <a href='./20_naming_rule.md'>Next</a>
<a href='./18_ownership.md'>Previous</a> | <a href='./20_naming_rule.md'>Next</a>
</p>
2 changes: 1 addition & 1 deletion doc/EN/syntax/22_subroutine.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ and(x, y, z) = x and y and z
```

<p align='center'>
<a href='./21_lambda.md'>Previous</a> | <a href='./23_scope.md'>Next</a>
<a href='./21_lambda.md'>Previous</a> | <a href='./23_closure.md'>Next</a>
</p>
File renamed without changes.
42 changes: 42 additions & 0 deletions doc/EN/syntax/type/06_nst_vs_sst.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Nominal Subtyping vs. Structural Subtyping

```erg
# NST
MonthsClass = Class Months
MonthsClass.
name self =
match self:
1 -> "january"
2 -> "february"
3 -> "march"
...

# SST
Months = 0..12
MonthsImpl = Patch Months
MonthsImpl.
name self =
match self:
1 -> "January"
2 -> "February"
3 -> "March"
...

assert 12 in Months
assert 2.name() == "February"
assert not 12 in MonthsClass
assert MonthsClass.new(12) in MonthsClass
# It can use structural types, even though wrapped in a class.
assert MonthsClass.new(12) in Months
# If both exist, class methods take priority.
assert MonthsClass.new(2).name() == "february"
```

## In The End, Which Should I Use, NST or SST?

If you cannot decide which one to use, our recommendation is NST.
SST requires abstraction skills to write code that does not break down in any use case. Good abstraction can lead to high productivity, but wrong abstraction (commonality by appearances) can lead to counterproductive results. (NSTs can reduce this risk by deliberately keeping abstraction to a minimum. If you are not a library implementor, it is not a bad idea to code only with NSTs.

<p align='center'>
<a href='./04_class.md'>Previous</a> | <a href='./06_inheritance.md'>Next</a>
</p>
9 changes: 9 additions & 0 deletions doc/EN/syntax/type/09_attributive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Attributive Type

Attribute types are types that contain Record and Dataclass, Patch, Module, etc.
Types belonging to attribute types are not value types.

## Record Type Composite

It is possible to flatten Record types composited.
For example, `{... {.name = Str; .age = Nat}; ... {.name = Str; .id = Nat}}` becomes `{.name = Str; .age = Nat; .id = Nat}`.
36 changes: 36 additions & 0 deletions doc/EN/syntax/type/10_interval.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Interval Type

The most basic use of `Range` objects is as iterator.

```erg
for! 0..9, i =>
print! i
```

Note that unlike Python, it includes a end number.

However, this is not only use for the `Range` objects. It can also be used the type. Such a type is called the Interval type.

```erg
i: 0..10 = 2
```

The `Nat` type is equivalent to `0..<Inf` and, `Int` and `Ratio` are equivalent to `-Inf<..<Inf`,
`0..<Inf` can also be written `0.._`. `_` means any instance of `Int` type.

Since it is can also be used as iterator, it can be specified in reverse order, such as `10..0`, however `<..`, `..<` and `<..<` cannot be reversed.

```erg
a = 0..10 # OK
b = 0..<10 # OK
c = 10..0 # OK
d = 10<..0 # Syntax error
e = 10..<0 # Syntax error
f = 10<..<0 # Syntax error
```

A Range operator can be used for non-numeric types, as long as they are `Ord` immutable types.

```erg
Alphabet = "A".."z"
```
85 changes: 85 additions & 0 deletions doc/EN/syntax/type/11_enum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Enumerative Type

Enum types generated by Set.
Enum types can be used as-is with type specifications, but further methods can be defined by classifying them into classes or defining patches.

A partially typed system with an enumerated type is called an enumerated partially typed.

```erg
Bool = {True, False}
Status = {"ok", "error"}
```

Since `1..7` can be rewritten as `{1, 2, 3, 4, 5, 6, 7}`, so when element is finite, the Enum types essentially equivalent the Range types.

```erg
Binary! = Class {0, 1}!.
invert! ref! self =
if! self == 0:
do!
self.set! 1
do!
self.set! 0

b = Binary!.new !0
b.invert!()
```

Incidentally, Erg's Enum types are a concept that encompasses enumerative types common in other languages.

```rust
// Rust
enum Status { Ok, Error }
```

```erg
# Erg
Status = {"Ok", "Error"}
```

The difference with Rust is that it uses a structural subtype(SST).

```rust
// There is no relationship between Status and ExtraStatus.
enum Status { Ok, Error }
enum ExtraStatus { Ok, Error, Unknown }

// Methods can be implemented
impl Status {
// ...
}
impl ExtraStatus {
// ...
}
```

```erg
# Status > ExtraStatus, and elements of Status can use methods of ExtraStatus.
Status = Trait {"Ok", "Error"}
# ...
ExtraStatus = Trait {"Ok", "Error", "Unknown"}
# ...
```

Methods can also be added by patching.

Use the `or` operator to explicitly indicate inclusion or to add a choice to an existing Enum type.

```erg
ExtraStatus = Status or {"Unknown"}
```

An enumerated type in which all classes to which an element belongs are identical is called a homogenous enumerated type.

By default, a class whose requirement type is an homogeneous enumerated type can be treated as a subclass of the class to which the element belongs.

If you do not wish to do so, you can make it a wrapper class.

```erg
Abc = Class {"A", "B", "C"}
Abc.new("A").is_uppercase()

OpaqueAbc = Class {inner = {"A", "B", "C"}}.
new inner: {"A", "B", "C"} = Self.new {inner;}
OpaqueAbc.new("A").is_uppercase() # TypeError
```
Loading