mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 04:09:05 +00:00
Merge remote-tracking branch 'upstream/main' into add-sync_to_translation_status.er
This commit is contained in:
commit
c3d27fb059
47 changed files with 462 additions and 237 deletions
|
@ -56,3 +56,6 @@ bd_re = "build --features debug --release"
|
||||||
bd_ja_re = "build --features debug --features japanese --release"
|
bd_ja_re = "build --features debug --features japanese --release"
|
||||||
bd_zh_cn_re = "build --features debug --features simplified_chinese --release"
|
bd_zh_cn_re = "build --features debug --features simplified_chinese --release"
|
||||||
bd_zh_tw_re = "build --features debug --features traditional_chinese --release"
|
bd_zh_tw_re = "build --features debug --features traditional_chinese --release"
|
||||||
|
|
||||||
|
inst = "install --path . --features els"
|
||||||
|
dinst = "install --path . --features debug --features els"
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,6 +17,7 @@
|
||||||
/*/.DS_Store
|
/*/.DS_Store
|
||||||
/.idea/
|
/.idea/
|
||||||
/timeit.dat
|
/timeit.dat
|
||||||
|
**/__pycache__/
|
||||||
|
|
||||||
# Nix
|
# Nix
|
||||||
.direnv
|
.direnv
|
||||||
|
|
|
@ -6,7 +6,7 @@ Beginners should read the instructions [here](https://github.com/erg-lang/erg/is
|
||||||
|
|
||||||
## Documents
|
## Documents
|
||||||
|
|
||||||
If you are thinking of contributing to Erg, you should read documents under `doc/*/dev_guide`. In particular, please pre-install what is written in `env.md`.
|
If you are thinking of contributing to Erg, you should read documents under `doc/*/dev_guide`. In particular, please pre-install what is written in [`env.md`](doc/EN/dev_guide/env.md).
|
||||||
|
|
||||||
Or you are interested in the internal structure of Erg, `doc/*/compiler` may provide useful information.
|
Or you are interested in the internal structure of Erg, `doc/*/compiler` may provide useful information.
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
even for and while expressions are just one of the subroutines, so this is possible.
|
even for and while expressions are just one of the subroutines, so this is possible.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
loop! block = while! do(True), block
|
loop! block! = while! do! True, block!
|
||||||
|
|
||||||
# equals to `while! do(True), do! print! "hello"`
|
# equals to `while! do(True), do! print! "hello"`
|
||||||
loop! do!:
|
loop! do!:
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
Ergでは特別扱いされる構文要素がとても少なく、例えば予約語が一つもありません。以下のような芸当も可能です。
|
Ergでは特別扱いされる構文要素がとても少なく、例えば予約語が一つもありません。以下のような芸当も可能です。
|
||||||
|
|
||||||
```python
|
```python
|
||||||
loop! block = while! do(True), block
|
loop! block! = while! do! True, block!
|
||||||
|
|
||||||
# `while! do(True), do! print! "hello"`と同じです
|
# `while! do(True), do! print! "hello"`と同じです
|
||||||
loop! do!:
|
loop! do!:
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
在Erg中,很少有东西被认为是特殊的,没有关键字,因此for和while表达式也只是子程序之一
|
在Erg中,很少有东西被认为是特殊的,没有关键字,因此for和while表达式也只是子程序之一
|
||||||
|
|
||||||
```python
|
```python
|
||||||
loop! block = while! do(True), block
|
loop! block! = while! do! True, block!
|
||||||
|
|
||||||
# equals to `while! do(True), do! print! "hello"`
|
# equals to `while! do(True), do! print! "hello"`
|
||||||
loop! do!:
|
loop! do!:
|
||||||
|
|
|
@ -76,9 +76,9 @@
|
||||||
在Erg中,很少有東西被認為是特殊的,沒有關鍵字,因此for和while表達式也只是子程序之一
|
在Erg中,很少有東西被認為是特殊的,沒有關鍵字,因此for和while表達式也只是子程序之一
|
||||||
|
|
||||||
```python
|
```python
|
||||||
loop! block = while! do(True), block
|
loop! block! = while! do! True, block!
|
||||||
|
|
||||||
# equals to `while! do(True), do! print! "hello"`
|
# equals to `while! do! True, do! print! "hello"`
|
||||||
loop! do!:
|
loop! do!:
|
||||||
print! "hello"
|
print! "hello"
|
||||||
```
|
```
|
||||||
|
|
|
@ -356,11 +356,11 @@ macro_rules! debug_enum_assert {
|
||||||
macro_rules! debug_info {
|
macro_rules! debug_info {
|
||||||
($output:ident) => {{
|
($output:ident) => {{
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use $crate::style::{CYAN, RESET};
|
use $crate::style::{colors::DEBUG, RESET};
|
||||||
write!(
|
write!(
|
||||||
$output,
|
$output,
|
||||||
"[{}DEBUG{}] {}:{:04}: ",
|
"[{}DEBUG{}] {}:{:04}: ",
|
||||||
CYAN,
|
DEBUG,
|
||||||
RESET,
|
RESET,
|
||||||
file!(),
|
file!(),
|
||||||
line!()
|
line!()
|
||||||
|
@ -369,8 +369,8 @@ macro_rules! debug_info {
|
||||||
}};
|
}};
|
||||||
() => {{
|
() => {{
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use $crate::style::{CYAN, RESET};
|
use $crate::style::{colors::DEBUG, RESET};
|
||||||
print!("[{}DEBUG{}] {}:{:04}: ", CYAN, RESET, file!(), line!());
|
print!("[{}DEBUG{}] {}:{:04}: ", DEBUG, RESET, file!(), line!());
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,25 +386,25 @@ macro_rules! debug_info {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! log {
|
macro_rules! log {
|
||||||
(info $($arg: tt)*) => {{
|
(info $($arg: tt)*) => {{
|
||||||
$crate::log!(c GREEN, $($arg)*);
|
$crate::log!(c DEBUG_MAIN, $($arg)*);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
(err $($arg: tt)*) => {{
|
(err $($arg: tt)*) => {{
|
||||||
$crate::log!(c RED, $($arg)*);
|
$crate::log!(c DEBUG_ERROR, $($arg)*);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
(info_f $output:ident, $($arg: tt)*) => {{
|
(info_f $output:ident, $($arg: tt)*) => {{
|
||||||
$crate::log!(f+c $output, GREEN, $($arg)*);
|
$crate::log!(f+c $output, DEBUG_MAIN, $($arg)*);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
(err_f $output:ident, $($arg: tt)*) => {{
|
(err_f $output:ident, $($arg: tt)*) => {{
|
||||||
$crate::log!(f+c $output, RED, $($arg)*);
|
$crate::log!(f+c $output, DEBUG_ERROR, $($arg)*);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
(f $output: ident, $($arg: tt)*) => {{
|
(f $output: ident, $($arg: tt)*) => {{
|
||||||
if cfg!(feature = "debug") {
|
if cfg!(feature = "debug") {
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use $crate::color::{RESET, GREEN, RED};
|
use $crate::color::{RESET, colors::DEBUG_MAIN, colors::DEBUG_ERROR};
|
||||||
$crate::debug_info!($output);
|
$crate::debug_info!($output);
|
||||||
write!($output, $($arg)*).unwrap();
|
write!($output, $($arg)*).unwrap();
|
||||||
write!($output, "{}", RESET).unwrap(); // color color anyway
|
write!($output, "{}", RESET).unwrap(); // color color anyway
|
||||||
|
@ -415,7 +415,7 @@ macro_rules! log {
|
||||||
(c $color:ident, $($arg: tt)*) => {{
|
(c $color:ident, $($arg: tt)*) => {{
|
||||||
if cfg!(feature = "debug") {
|
if cfg!(feature = "debug") {
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use $crate::style::{RESET, GREEN, RED};
|
use $crate::style::{RESET, colors::DEBUG_MAIN, colors::DEBUG_ERROR};
|
||||||
$crate::debug_info!();
|
$crate::debug_info!();
|
||||||
print!("{}", $color);
|
print!("{}", $color);
|
||||||
println!($($arg)*);
|
println!($($arg)*);
|
||||||
|
@ -426,7 +426,7 @@ macro_rules! log {
|
||||||
(f+c $output:ident, $color:ident, $($arg: tt)*) => {{
|
(f+c $output:ident, $color:ident, $($arg: tt)*) => {{
|
||||||
if cfg!(feature = "debug") {
|
if cfg!(feature = "debug") {
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use $crate::style::{RESET, GREEN};
|
use $crate::style::{RESET, colors::DEBUG_MAIN};
|
||||||
$crate::debug_info!($output);
|
$crate::debug_info!($output);
|
||||||
write!($output, "{}{}{}", $color, $($arg)*, RESET).unwrap();
|
write!($output, "{}{}{}", $color, $($arg)*, RESET).unwrap();
|
||||||
write!($output, $($arg)*).unwrap();
|
write!($output, $($arg)*).unwrap();
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
|
use self::colors::*;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
pub const ATTR_RESET: &str = "\x1b[0m";
|
pub const ATTR_RESET: &str = "\x1b[0m";
|
||||||
pub const BOLD: &str = "\x1b[1m";
|
pub const BOLD: &str = "\x1b[1m";
|
||||||
pub const UNDERLINE: &str = "\x1b[4m";
|
pub const UNDERLINE: &str = "\x1b[4m";
|
||||||
pub const REVERSED: &str = "\x1b[7m";
|
pub const REVERSED: &str = "\x1b[7m";
|
||||||
|
pub const RESET: &str = "\x1b[m";
|
||||||
|
|
||||||
// Escape sequences change the color of the terminal
|
// Escape sequences change the color of the terminal
|
||||||
pub const RESET: &str = "\x1b[m";
|
#[cfg(not(feature = "pretty"))]
|
||||||
|
pub mod colors {
|
||||||
pub const BLACK: &str = "\x1b[30m";
|
pub const BLACK: &str = "\x1b[30m";
|
||||||
pub const BLUE: &str = "\x1b[94m";
|
pub const BLUE: &str = "\x1b[94m";
|
||||||
pub const CYAN: &str = "\x1b[96m";
|
pub const CYAN: &str = "\x1b[96m";
|
||||||
|
@ -16,14 +19,26 @@ pub const MAGENTA: &str = "\x1b[95m";
|
||||||
pub const RED: &str = "\x1b[91m";
|
pub const RED: &str = "\x1b[91m";
|
||||||
pub const WHITE: &str = "\x1b[97m";
|
pub const WHITE: &str = "\x1b[97m";
|
||||||
pub const YELLOW: &str = "\x1b[93m";
|
pub const YELLOW: &str = "\x1b[93m";
|
||||||
|
pub const DEBUG_MAIN: &str = GREEN;
|
||||||
|
pub const DEBUG: &str = CYAN;
|
||||||
|
pub const DEBUG_ERROR: &str = RED;
|
||||||
|
}
|
||||||
// custom colors when use `pretty`
|
// custom colors when use `pretty`
|
||||||
pub const CUSTOM_RED: &str = "\x1b[38;2;255;76;76m";
|
#[cfg(feature = "pretty")]
|
||||||
pub const CUSTOM_BLUE: &str = "\x1b[38;2;76;76;255m";
|
pub mod colors {
|
||||||
pub const CUSTOM_GRAY: &str = "\x1b[38;2;231;231;235m";
|
pub const BLACK: &str = "\x1b[30m";
|
||||||
pub const CUSTOM_CYAN: &str = "\x1b[38;2;76;255;255m";
|
pub const BLUE: &str = "\x1b[38;2;76;76;255m";
|
||||||
pub const CUSTOM_MAGENTA: &str = "\x1b[38;2;165;76;255m";
|
pub const CYAN: &str = "\x1b[38;2;76;255;255m";
|
||||||
pub const CUSTOM_GREEN: &str = "\x1b[38;2;76;255;76m";
|
pub const GRAY: &str = "\x1b[38;2;231;231;235m";
|
||||||
pub const CUSTOM_YELLOW: &str = "\x1b[38;2;255;255;76m";
|
pub const GREEN: &str = "\x1b[38;2;76;255;76m";
|
||||||
|
pub const MAGENTA: &str = "\x1b[38;2;165;76;255m";
|
||||||
|
pub const RED: &str = "\x1b[38;2;255;76;76m";
|
||||||
|
pub const WHITE: &str = "\x1b[97m";
|
||||||
|
pub const YELLOW: &str = "\x1b[38;2;255;255;76m";
|
||||||
|
pub const DEBUG_MAIN: &str = BLUE;
|
||||||
|
pub const DEBUG: &str = MAGENTA;
|
||||||
|
pub const DEBUG_ERROR: &str = CYAN;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remove_style(s: &str) -> String {
|
pub fn remove_style(s: &str) -> String {
|
||||||
s.replace(RED, "")
|
s.replace(RED, "")
|
||||||
|
@ -53,13 +68,6 @@ pub enum Color {
|
||||||
Red,
|
Red,
|
||||||
White,
|
White,
|
||||||
Yellow,
|
Yellow,
|
||||||
CustomRed,
|
|
||||||
CustomBlue,
|
|
||||||
CustomGray,
|
|
||||||
CustomCyan,
|
|
||||||
CustomMagenta,
|
|
||||||
CustomGreen,
|
|
||||||
CustomYellow,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
|
@ -75,13 +83,6 @@ impl Color {
|
||||||
Color::Red => RED,
|
Color::Red => RED,
|
||||||
Color::Yellow => YELLOW,
|
Color::Yellow => YELLOW,
|
||||||
Color::White => WHITE,
|
Color::White => WHITE,
|
||||||
Color::CustomRed => CUSTOM_RED,
|
|
||||||
Color::CustomBlue => CUSTOM_BLUE,
|
|
||||||
Color::CustomGray => CUSTOM_GRAY,
|
|
||||||
Color::CustomCyan => CUSTOM_CYAN,
|
|
||||||
Color::CustomMagenta => CUSTOM_MAGENTA,
|
|
||||||
Color::CustomGreen => CUSTOM_GREEN,
|
|
||||||
Color::CustomYellow => CUSTOM_YELLOW,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +116,6 @@ pub struct ThemeColors {
|
||||||
pub accent: Color,
|
pub accent: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "pretty"))]
|
|
||||||
pub const COLORS: ThemeColors = ThemeColors {
|
pub const COLORS: ThemeColors = ThemeColors {
|
||||||
error: Color::Red,
|
error: Color::Red,
|
||||||
warning: Color::Yellow,
|
warning: Color::Yellow,
|
||||||
|
@ -125,16 +125,6 @@ pub const COLORS: ThemeColors = ThemeColors {
|
||||||
accent: Color::White,
|
accent: Color::White,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "pretty")]
|
|
||||||
pub const COLORS: ThemeColors = ThemeColors {
|
|
||||||
error: Color::CustomRed,
|
|
||||||
warning: Color::CustomYellow,
|
|
||||||
exception: Color::CustomMagenta,
|
|
||||||
gutter: Color::CustomCyan,
|
|
||||||
hint: Color::CustomGreen,
|
|
||||||
accent: Color::CustomGray,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Characters {
|
pub struct Characters {
|
||||||
hat: char, // error
|
hat: char, // error
|
||||||
|
@ -524,9 +514,6 @@ mod tests {
|
||||||
println!("{BLUE}Hello{RESET}, {GREEN}World{RESET}");
|
println!("{BLUE}Hello{RESET}, {GREEN}World{RESET}");
|
||||||
println!("{MAGENTA}Hello{RESET}, {BLACK}World{RESET}");
|
println!("{MAGENTA}Hello{RESET}, {BLACK}World{RESET}");
|
||||||
println!("{GRAY}Hello{RESET}, {WHITE}World{RESET}");
|
println!("{GRAY}Hello{RESET}, {WHITE}World{RESET}");
|
||||||
println!("{CUSTOM_BLUE}Hello{RESET}, {CUSTOM_CYAN}World{RESET}");
|
|
||||||
println!("{CUSTOM_GRAY}Hello{RESET}, {CUSTOM_GREEN}World{RESET}");
|
|
||||||
println!("{CUSTOM_MAGENTA}Hello{RESET}, {CUSTOM_RED}World{RESET}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -46,6 +46,18 @@ use crate::ty::{HasType, Type, TypeCode, TypePair};
|
||||||
use erg_common::fresh::fresh_varname;
|
use erg_common::fresh::fresh_varname;
|
||||||
use AccessKind::*;
|
use AccessKind::*;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ControlKind {
|
||||||
|
If,
|
||||||
|
While,
|
||||||
|
For,
|
||||||
|
Match,
|
||||||
|
With,
|
||||||
|
Discard,
|
||||||
|
Assert,
|
||||||
|
}
|
||||||
|
|
||||||
/// patch method -> function
|
/// patch method -> function
|
||||||
/// patch attr -> variable
|
/// patch attr -> variable
|
||||||
fn debind(ident: &Identifier) -> Option<Str> {
|
fn debind(ident: &Identifier) -> Option<Str> {
|
||||||
|
@ -1604,6 +1616,21 @@ impl PyCodeGenerator {
|
||||||
self.emit_load_const(ValueObj::None);
|
self.emit_load_const(ValueObj::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deopt_instr(&mut self, kind: ControlKind, args: Args) {
|
||||||
|
if !self.control_loaded {
|
||||||
|
self.load_control();
|
||||||
|
}
|
||||||
|
let local = match kind {
|
||||||
|
ControlKind::If => Identifier::public("if__"),
|
||||||
|
ControlKind::For => Identifier::public("for__"),
|
||||||
|
ControlKind::While => Identifier::public("while__"),
|
||||||
|
ControlKind::With => Identifier::public("with__"),
|
||||||
|
ControlKind::Discard => Identifier::public("discard__"),
|
||||||
|
kind => todo!("{kind:?}"),
|
||||||
|
};
|
||||||
|
self.emit_call_local(local, args);
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_if_instr(&mut self, mut args: Args) {
|
fn emit_if_instr(&mut self, mut args: Args) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let init_stack_len = self.stack_len();
|
let init_stack_len = self.stack_len();
|
||||||
|
@ -1670,6 +1697,9 @@ impl PyCodeGenerator {
|
||||||
|
|
||||||
fn emit_for_instr(&mut self, mut args: Args) {
|
fn emit_for_instr(&mut self, mut args: Args) {
|
||||||
log!(info "entered {} ({})", fn_name!(), args);
|
log!(info "entered {} ({})", fn_name!(), args);
|
||||||
|
if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
|
||||||
|
return self.deopt_instr(ControlKind::For, args);
|
||||||
|
}
|
||||||
let _init_stack_len = self.stack_len();
|
let _init_stack_len = self.stack_len();
|
||||||
let iterable = args.remove(0);
|
let iterable = args.remove(0);
|
||||||
self.emit_expr(iterable);
|
self.emit_expr(iterable);
|
||||||
|
@ -1716,6 +1746,9 @@ impl PyCodeGenerator {
|
||||||
|
|
||||||
fn emit_while_instr(&mut self, mut args: Args) {
|
fn emit_while_instr(&mut self, mut args: Args) {
|
||||||
log!(info "entered {} ({})", fn_name!(), args);
|
log!(info "entered {} ({})", fn_name!(), args);
|
||||||
|
if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
|
||||||
|
return self.deopt_instr(ControlKind::While, args);
|
||||||
|
}
|
||||||
let _init_stack_len = self.stack_len();
|
let _init_stack_len = self.stack_len();
|
||||||
// e.g. is_foo!: () => Bool, do!(is_bar)
|
// e.g. is_foo!: () => Bool, do!(is_bar)
|
||||||
let cond_block = args.remove(0);
|
let cond_block = args.remove(0);
|
||||||
|
@ -2008,9 +2041,11 @@ impl PyCodeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_with_instr_311(&mut self, args: Args) {
|
fn emit_with_instr_311(&mut self, mut args: Args) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let mut args = args;
|
if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
|
||||||
|
return self.deopt_instr(ControlKind::With, args);
|
||||||
|
}
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
let lambda = enum_unwrap!(args.remove(0), Expr::Lambda);
|
let lambda = enum_unwrap!(args.remove(0), Expr::Lambda);
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
|
@ -2054,9 +2089,11 @@ impl PyCodeGenerator {
|
||||||
self.emit_load_name_instr(stash);
|
self.emit_load_name_instr(stash);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_with_instr_310(&mut self, args: Args) {
|
fn emit_with_instr_310(&mut self, mut args: Args) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let mut args = args;
|
if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
|
||||||
|
return self.deopt_instr(ControlKind::With, args);
|
||||||
|
}
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
let lambda = enum_unwrap!(args.remove(0), Expr::Lambda);
|
let lambda = enum_unwrap!(args.remove(0), Expr::Lambda);
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
|
@ -2105,9 +2142,11 @@ impl PyCodeGenerator {
|
||||||
self.emit_load_name_instr(stash);
|
self.emit_load_name_instr(stash);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_with_instr_308(&mut self, args: Args) {
|
fn emit_with_instr_308(&mut self, mut args: Args) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let mut args = args;
|
if !matches!(args.get(1).unwrap(), Expr::Lambda(_)) {
|
||||||
|
return self.deopt_instr(ControlKind::With, args);
|
||||||
|
}
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
let lambda = enum_unwrap!(args.remove(0), Expr::Lambda);
|
let lambda = enum_unwrap!(args.remove(0), Expr::Lambda);
|
||||||
let params = self.gen_param_names(&lambda.params);
|
let params = self.gen_param_names(&lambda.params);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
use std::option::Option; // conflicting to Type::Option
|
use std::option::Option; // conflicting to Type::Option
|
||||||
|
|
||||||
use erg_common::error::{Location, MultiErrorDisplay};
|
use erg_common::error::{Location, MultiErrorDisplay};
|
||||||
|
use erg_common::style::colors::DEBUG_ERROR;
|
||||||
|
|
||||||
use crate::ty::constructors::{and, not, or, poly};
|
use crate::ty::constructors::{and, not, or, poly};
|
||||||
use crate::ty::free::{Constraint, FreeKind};
|
use crate::ty::free::{Constraint, FreeKind};
|
||||||
|
@ -131,7 +132,7 @@ impl Context {
|
||||||
|| self.nominal_supertype_of(lhs, rhs)
|
|| self.nominal_supertype_of(lhs, rhs)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
log!("answer: {lhs} {RED}:>{RESET} {rhs} == {res}");
|
log!("answer: {lhs} {DEBUG_ERROR}:>{RESET} {rhs} == {res}");
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl Context {
|
||||||
None,
|
None,
|
||||||
Bool,
|
Bool,
|
||||||
);
|
);
|
||||||
let I = mono_q(KW_I, subtypeof(poly(KW_ITERABLE, vec![ty_tp(T.clone())])));
|
let I = mono_q(TY_I, subtypeof(poly(ITERABLE, vec![ty_tp(T.clone())])));
|
||||||
let t_iter = nd_func(vec![kw(KW_OBJECT, I.clone())], None, proj(I, ITERATOR)).quantify();
|
let t_iter = nd_func(vec![kw(KW_OBJECT, I.clone())], None, proj(I, ITERATOR)).quantify();
|
||||||
let t_len = nd_func(
|
let t_len = nd_func(
|
||||||
vec![kw(KW_S, poly(SEQ, vec![TyParam::erased(Type)]))],
|
vec![kw(KW_S, poly(SEQ, vec![TyParam::erased(Type)]))],
|
||||||
|
|
31
crates/erg_compiler/lib/pystd/ntpath.d.er
Normal file
31
crates/erg_compiler/lib/pystd/ntpath.d.er
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
.abspath: (path: PathLike) -> Str
|
||||||
|
.basename: (path: PathLike) -> Str
|
||||||
|
.commonpath: (paths: Iterable PathLike) -> Str
|
||||||
|
.commonprefix: (list: [PathLike; _]) -> Str
|
||||||
|
.dirname: (path: PathLike) -> Str
|
||||||
|
.exists!: (path: PathLike) => Bool
|
||||||
|
.lexists!: (path: PathLike) => Bool
|
||||||
|
.expanduser!: (path: PathLike) => Str
|
||||||
|
.expandvars!: (path: PathLike) => Str
|
||||||
|
.getatime!: (path: PathLike) => Float
|
||||||
|
.getmtime!: (path: PathLike) => Float
|
||||||
|
.getctime!: (path: PathLike) => Float
|
||||||
|
.getsize!: (path: PathLike) => Int
|
||||||
|
.isabs: (path: PathLike) -> Bool
|
||||||
|
.isfile!: (path: PathLike) => Bool
|
||||||
|
.isdir!: (path: PathLike) => Bool
|
||||||
|
.islink!: (path: PathLike) => Bool
|
||||||
|
.ismount!: (path: PathLike) => Bool
|
||||||
|
.join: (path: PathLike, *paths: PathLike) -> Str
|
||||||
|
.normcase: (path: PathLike) -> Str
|
||||||
|
.normpath: (path: PathLike) -> Str
|
||||||
|
.realpath!: (path: PathLike, strict := Bool) => Str
|
||||||
|
.relpath: (path: PathLike, start := PathLike) -> Str
|
||||||
|
.samefile!: (path1: PathLike, path2: PathLike) => Bool
|
||||||
|
.sameopenfile!: (fp1: File! or PathLike, fp2: File! or PathLike) => Bool
|
||||||
|
|
||||||
|
.split: (path: PathLike) -> (Str, Str)
|
||||||
|
.splitdrive: (path: PathLike) -> (Str, Str)
|
||||||
|
.splitext: (path: PathLike) -> (Str, Str)
|
||||||
|
|
||||||
|
.supports_unicode_filenames: Bool
|
31
crates/erg_compiler/lib/pystd/posixpath.d.er
Normal file
31
crates/erg_compiler/lib/pystd/posixpath.d.er
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
.abspath: (path: PathLike) -> Str
|
||||||
|
.basename: (p: PathLike) -> Str
|
||||||
|
.commonpath: (paths: Iterable PathLike) -> Str
|
||||||
|
.commonprefix: (list: [PathLike; _]) -> Str
|
||||||
|
.dirname: (p: PathLike) -> Str
|
||||||
|
.exists!: (path: PathLike) => Bool
|
||||||
|
.lexists!: (path: PathLike) => Bool
|
||||||
|
.expanduser!: (path: PathLike) => Str
|
||||||
|
.expandvars!: (path: PathLike) => Str
|
||||||
|
.getatime!: (path: PathLike) => Float
|
||||||
|
.getmtime!: (path: PathLike) => Float
|
||||||
|
.getctime!: (path: PathLike) => Float
|
||||||
|
.getsize!: (path: PathLike) => Int
|
||||||
|
.isabs: (s: PathLike) -> Bool
|
||||||
|
.isfile!: (path: PathLike) => Bool
|
||||||
|
.isdir!: (path: PathLike) => Bool
|
||||||
|
.islink!: (path: PathLike) => Bool
|
||||||
|
.ismount!: (path: PathLike) => Bool
|
||||||
|
.join: (a: PathLike, *p: PathLike) -> Str
|
||||||
|
.normcase: (path: PathLike) -> Str
|
||||||
|
.normpath: (s: PathLike) -> Str
|
||||||
|
.realpath!: (path: PathLike, strict := Bool) => Str
|
||||||
|
.relpath: (path: PathLike, start := PathLike or NoneType) -> Str
|
||||||
|
.samefile!: (path1: PathLike, path2: PathLike) => Bool
|
||||||
|
.sameopenfile!: (fp1: File! or PathLike, fp2: File! or PathLike) => Bool
|
||||||
|
|
||||||
|
.split: (p: PathLike) -> (Str, Str)
|
||||||
|
.splitdrive: (p: PathLike) -> (Str, Str)
|
||||||
|
.splitext: (p: PathLike) -> (Str, Str)
|
||||||
|
|
||||||
|
.supports_unicode_filenames: Bool
|
|
@ -4,6 +4,7 @@ use erg_common::config::ErgConfig;
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
use erg_common::error::Location;
|
use erg_common::error::Location;
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
|
use erg_common::style::colors::DEBUG_MAIN;
|
||||||
use erg_common::traits::{Locational, Stream};
|
use erg_common::traits::{Locational, Stream};
|
||||||
use erg_common::vis::Visibility;
|
use erg_common::vis::Visibility;
|
||||||
use erg_common::Str;
|
use erg_common::Str;
|
||||||
|
@ -78,7 +79,7 @@ impl OwnershipChecker {
|
||||||
self.check_expr(chunk, Ownership::Owned, true);
|
self.check_expr(chunk, Ownership::Owned, true);
|
||||||
}
|
}
|
||||||
log!(
|
log!(
|
||||||
"{GREEN}[DEBUG] the ownership checking process has completed, found errors: {}{RESET}",
|
"{DEBUG_MAIN}[DEBUG] the ownership checking process has completed, found errors: {}{RESET}",
|
||||||
self.errs.len()
|
self.errs.len()
|
||||||
);
|
);
|
||||||
if self.errs.is_empty() {
|
if self.errs.is_empty() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ macro_rules! debug_call_info {
|
||||||
($self: ident) => {
|
($self: ident) => {
|
||||||
$self.level += 1;
|
$self.level += 1;
|
||||||
log!(
|
log!(
|
||||||
c GREEN,
|
c DEBUG_MAIN,
|
||||||
"\n{} ({}) entered {}, cur: {}",
|
"\n{} ({}) entered {}, cur: {}",
|
||||||
"・".repeat(($self.level as f32 / 4.0).floor() as usize),
|
"・".repeat(($self.level as f32 / 4.0).floor() as usize),
|
||||||
$self.level,
|
$self.level,
|
||||||
|
@ -48,7 +48,7 @@ macro_rules! debug_exit_info {
|
||||||
($self: ident) => {
|
($self: ident) => {
|
||||||
$self.level -= 1;
|
$self.level -= 1;
|
||||||
log!(
|
log!(
|
||||||
c GREEN,
|
c DEBUG_MAIN,
|
||||||
"\n{} ({}) exit {}, cur: {}",
|
"\n{} ({}) exit {}, cur: {}",
|
||||||
"・".repeat(($self.level as f32 / 4.0).floor() as usize),
|
"・".repeat(($self.level as f32 / 4.0).floor() as usize),
|
||||||
$self.level,
|
$self.level,
|
||||||
|
@ -228,7 +228,7 @@ impl Parser {
|
||||||
pub(crate) fn stack_dec(&mut self, fn_name: &str) {
|
pub(crate) fn stack_dec(&mut self, fn_name: &str) {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
log!(
|
log!(
|
||||||
c GREEN,
|
c DEBUG_MAIN,
|
||||||
"\n{} ({}) exit {}, cur: {}",
|
"\n{} ({}) exit {}, cur: {}",
|
||||||
"・".repeat((self.level as f32 / 4.0).floor() as usize),
|
"・".repeat((self.level as f32 / 4.0).floor() as usize),
|
||||||
self.level,
|
self.level,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
## ドキュメント
|
## ドキュメント
|
||||||
|
|
||||||
Erg への貢献を考えている場合は、`doc/*/dev_guide` にあるドキュメントを読む必要があります。特に`env.md`に書かれているものを事前にインストールしてください。
|
Erg への貢献を考えている場合は、`doc/*/dev_guide` にあるドキュメントを読む必要があります。特に[`env.md`](../JA/dev_guide/env.md)に書かれているものを事前にインストールしてください。
|
||||||
|
|
||||||
Erg の内部構造に興味がある場合は、`doc/*/compiler` が役に立つかもしれません。
|
Erg の内部構造に興味がある場合は、`doc/*/compiler` が役に立つかもしれません。
|
||||||
|
|
||||||
|
@ -22,11 +22,11 @@ Ergのバグだと思われる動作を見つけた場合は、[報告](https://
|
||||||
|
|
||||||
私たちは常に、ドキュメントをさまざまな言語バージョンに翻訳してくれる人を探しています。
|
私たちは常に、ドキュメントをさまざまな言語バージョンに翻訳してくれる人を探しています。
|
||||||
|
|
||||||
ドキュメントが他の言語に比べて古くなっていることに気づき、内容を更新したいという方も歓迎します ([こちら](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362) を参照)。これを行う方法について)。
|
ドキュメントが他の言語に比べて古くなっていることに気づき、内容を更新したいという方も歓迎します (これを行う方法については[こちら](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362) を参照)。
|
||||||
|
|
||||||
## 質問する
|
## 質問する
|
||||||
|
|
||||||
ご不明な点がございましたら、[Discord チャンネル](https://discord.gg/zfAAUbgGr4)までお気軽にお問い合わせください。
|
ご不明な点がございましたら、[Discord チャンネル](https://discord.gg/zfAAUbgGr4)でお気軽にお問い合わせください。
|
||||||
|
|
||||||
## 開発・実装に関して
|
## 開発・実装に関して
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Architecture of `ergc`
|
# Architecture of `ergc`
|
||||||
|
|
||||||
## 1. Scan an Erg script (.er) and generate a `TokenStream` (parser/lex.rs)
|
## 1. Scan an Erg script (.er) and generate a `TokenStream`
|
||||||
|
|
||||||
|
src: [erg_parser\lex.rs](../../../crates/erg_parser/lex.rs)
|
||||||
|
|
||||||
* parser/lexer/Lexer generates `TokenStream` (this is an iterator of `Token`, `TokenStream` can be generated by `Lexer::collect()`)
|
* parser/lexer/Lexer generates `TokenStream` (this is an iterator of `Token`, `TokenStream` can be generated by `Lexer::collect()`)
|
||||||
* `Lexer` is constructed from `Lexer::new` or `Lexer::from_str`, where `Lexer::new` reads the code from a file or command option.
|
* `Lexer` is constructed from `Lexer::new` or `Lexer::from_str`, where `Lexer::new` reads the code from a file or command option.
|
||||||
|
@ -9,21 +11,42 @@
|
||||||
* `LexerRunner` can also be used if you want to use `Lexer` as standalone; `Lexer` is just an iterator and does not implement the `Runnable` trait.
|
* `LexerRunner` can also be used if you want to use `Lexer` as standalone; `Lexer` is just an iterator and does not implement the `Runnable` trait.
|
||||||
* `Runnable` is implemented by `LexerRunner`, `ParserRunner`, `Compiler`, and `DummyVM`.
|
* `Runnable` is implemented by `LexerRunner`, `ParserRunner`, `Compiler`, and `DummyVM`.
|
||||||
|
|
||||||
## 2. Convert `TokenStream` -> `AST` (parser/parse.rs)
|
## 2. Convert `TokenStream` -> `AST`
|
||||||
|
|
||||||
|
src: [erg_parser\parse.rs](../../../crates/erg_parser/parse.rs)
|
||||||
|
|
||||||
* `Parser`, like `Lexer`, has two constructors, `Parser::new` and `Parser::from_str`, and `Parser::parse` will give the `AST`.
|
* `Parser`, like `Lexer`, has two constructors, `Parser::new` and `Parser::from_str`, and `Parser::parse` will give the `AST`.
|
||||||
* `AST` is the wrapper type of `Vec<Expr>`. It is for "Abstract Syntax Tree".
|
* `AST` is the wrapper type of `Vec<Expr>`. It is for "Abstract Syntax Tree".
|
||||||
|
|
||||||
### 2.1 Desugaring `AST`
|
### 2.1 Desugaring `AST`
|
||||||
|
|
||||||
|
src: [erg_parser/desugar.rs](../../../crates/erg_parser/desugar.rs)
|
||||||
|
|
||||||
* expand nested vars (`Desugarer::desugar_nest_vars_pattern`)
|
* expand nested vars (`Desugarer::desugar_nest_vars_pattern`)
|
||||||
* desugar multiple pattern definition syntax (`Desugarer::desugar_multiple_pattern_def`)
|
* desugar multiple pattern definition syntax (`Desugarer::desugar_multiple_pattern_def`)
|
||||||
|
|
||||||
### 2.2 Reordering & Linking `AST`
|
### 2.2 Reordering & Linking `AST`
|
||||||
|
|
||||||
* Sort variables according to dependencies and link class methods to class definitions (`Linker::link`)
|
src: [erg_compiler/reorder.rs](../../../crates/erg_compiler/reorder.rs)
|
||||||
|
|
||||||
## 3. Type checking & inference, Convert `AST` -> `HIR` (compiler/lower.rs)
|
* link class methods to class definitions
|
||||||
|
* method definitions are allowed outside of the class definition file
|
||||||
|
* current implementation is incomplete, only in the same file
|
||||||
|
|
||||||
|
## 3. Convert `AST` -> `HIR`
|
||||||
|
|
||||||
|
(main) src: [erg_compiler/lower.rs](../../../crates/erg_compiler/lower.rs)
|
||||||
|
|
||||||
|
## 3.1 Name Resolution
|
||||||
|
|
||||||
|
In the current implementation it is done during type checking.
|
||||||
|
|
||||||
|
* All ASTs (including imported modules) are scanned for name resolution before type inference.
|
||||||
|
* In addition to performing constant cycle checking and reordering, a context is created for type inference (however, most of the information on variables registered in this context is not yet finalized).
|
||||||
|
|
||||||
|
### 3.2 Type checking & inference
|
||||||
|
|
||||||
|
src: [erg_compiler/lower.rs](../../../crates/erg_compiler/lower.rs)
|
||||||
|
|
||||||
* `HIR` has every variable's type information. It is for "High-level Intermediate Representation".
|
* `HIR` has every variable's type information. It is for "High-level Intermediate Representation".
|
||||||
* `ASTLowerer` can be constructed in the same way as `Parser` and `Lexer`.
|
* `ASTLowerer` can be constructed in the same way as `Parser` and `Lexer`.
|
||||||
|
@ -31,19 +54,28 @@
|
||||||
* `ASTLowerer` is owned by `Compiler`. Unlike conventional structures, `ASTLowerer` handles code contexts and is not a one-time disposable.
|
* `ASTLowerer` is owned by `Compiler`. Unlike conventional structures, `ASTLowerer` handles code contexts and is not a one-time disposable.
|
||||||
* If the result of type inference is incomplete (if there is an unknown type variable), an error will occur during name resolution.
|
* If the result of type inference is incomplete (if there is an unknown type variable), an error will occur during name resolution.
|
||||||
|
|
||||||
## 4. Check side-effects (compiler/effectcheck.rs)
|
## 4. Check side-effects
|
||||||
|
|
||||||
## 4. Check ownerships (compiler/memcheck.rs)
|
src: [erg_compiler/effectcheck.rs](../../../crates/erg_compiler/effectcheck.rs)
|
||||||
|
|
||||||
## 5. Desugar `HIR` (compiler/desugar_hir.rs)
|
## 5. Check ownerships
|
||||||
|
|
||||||
|
src: [erg_compiler/ownercheck.rs](../../../crates/erg_compiler/ownercheck.rs)
|
||||||
|
|
||||||
|
## 6. Desugar `HIR`
|
||||||
|
|
||||||
|
src: [erg_compiler/desugar_hir.rs](../../../crates/erg_compiler/desugar_hir.rs)
|
||||||
|
|
||||||
Convert parts that are not consistent with Python syntax
|
Convert parts that are not consistent with Python syntax
|
||||||
|
|
||||||
* Convert class member variables to functions
|
* Convert class member variables to functions
|
||||||
|
|
||||||
## 6. Generate Bytecode (`CodeObj`) from `HIR` (compiler/codegen.rs)
|
## 7. Link
|
||||||
|
|
||||||
## (7. (Future plans) Convert Bytecode -> LLVM IR)
|
src: [erg_compiler/link.rs](../../../crates/erg_compiler/link.rs)
|
||||||
|
|
||||||
* Bytecode is stack-based, whereas LLVM IR is register-based.
|
* Load all modules, resolve dependencies, and combine into a single HIR
|
||||||
There will be several more layers of intermediate processes for this conversion process.
|
|
||||||
|
## 8. Generate Bytecode (`CodeObj`) from `HIR`
|
||||||
|
|
||||||
|
src: [erg_compiler/codegen.rs](../../../crates/erg_compiler/codegen.rs)
|
||||||
|
|
|
@ -36,3 +36,7 @@ Increase the thread stack size. Used for Windows execution and test execution.
|
||||||
|
|
||||||
`--language-server` option becomes available.
|
`--language-server` option becomes available.
|
||||||
`erg --language-server` will start the Erg language server.
|
`erg --language-server` will start the Erg language server.
|
||||||
|
|
||||||
|
## py_compatible
|
||||||
|
|
||||||
|
Enable Python-compatible mode, which makes parts of the APIs and syntax compatible with Python. Used for [pylyzer](https://github.com/mtshiba/pylyzer).
|
||||||
|
|
|
@ -7,6 +7,8 @@ Any document that does not follow the rules below is subject to correction.
|
||||||
* Always include definitions, meanings, or links to terms that appear for the first time in the document.
|
* Always include definitions, meanings, or links to terms that appear for the first time in the document.
|
||||||
* Use parentheses as a proviso only for sentences that are supplementary but necessary for understanding the main text, and use footnotes for sentences that are not essential for understanding the main text[<sup id="f1">1</ sup>](#1).
|
* Use parentheses as a proviso only for sentences that are supplementary but necessary for understanding the main text, and use footnotes for sentences that are not essential for understanding the main text[<sup id="f1">1</ sup>](#1).
|
||||||
* If the content of the document is outdated, update it according to [this method](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362).
|
* If the content of the document is outdated, update it according to [this method](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362).
|
||||||
|
* Files under `syntax` should have sequential numbers at the beginning of their file names, except for those not included in the document.
|
||||||
|
* Scripts that automatically insert and replace files exist in doc/script.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
We use pre-commit to have clippy check and test automatically.
|
We use pre-commit to have clippy check and test automatically.
|
||||||
The checks may fail on the first run even if there are no bugs, in which case you should try committing again.
|
The checks may fail on the first run even if there are no bugs, in which case you should try committing again.
|
||||||
|
|
||||||
* Python3 interpreter
|
* Python3 interpreter (3.7~3.11)
|
||||||
|
|
||||||
|
If you want to check the behavior of Erg in various versions, it is recommended to install such as [pyenv](https://github.com/pyenv/pyenv).
|
||||||
|
|
||||||
## Recommendation
|
## Recommendation
|
||||||
|
|
||||||
|
|
|
@ -112,8 +112,8 @@ C = Class {x = Int}
|
||||||
.method self = ...
|
.method self = ...
|
||||||
```
|
```
|
||||||
|
|
||||||
You can specify the language of the document by writing the language code immediately after the `'''`. The [Erg Language Server](https://github.com/erg-lang/erg/tree/main/compiler/els) will then display documents in the Markdown format for each language version (The default language is English).
|
You can specify the language of the document by writing the language code immediately after the `'''`. The [Erg Language Server](https://github.com/erg-lang/erg/tree/main/crates/els) will then display documents in the Markdown format for each language version (The default language is English).
|
||||||
See [here](https://github.com/erg-lang/erg/blob/main/doc/JA/dev_guide/i18n_messages.md) for registered language codes.
|
See [here](https://github.com/erg-lang/erg/blob/main/doc/EN/dev_guide/i18n_messages.md) for registered language codes.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -76,25 +76,25 @@ Each of these literals has its own documentation describing them separately, so
|
||||||
[], [1], [1, 2, 3], ["1", "2",], ...
|
[], [1], [1, 2, 3], ["1", "2",], ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Tuple Literal](./11_tuple.md)
|
### [Tuple Literal](./13_tuple.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
(), (1, 2, 3), (1, "hello", True), ...
|
(), (1, 2, 3), (1, "hello", True), ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Dict Literal](./12_dict.md)
|
### [Dict Literal](./11_dict.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
|
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Record Literal](./13_record.md)
|
### [Record Literal](./14_record.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
|
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Set Literal](./14_set.md)
|
### [Set Literal](./15_set.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, ...
|
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, ...
|
||||||
|
|
|
@ -98,11 +98,11 @@ The above code prints `π` when `x` is `3.141592653589793`. If `x` is changed to
|
||||||
Some objects cannot be bound as constants. Mutable objects, for example. Mutable objects are objects whose states can be changed, as described in detail later.
|
Some objects cannot be bound as constants. Mutable objects, for example. Mutable objects are objects whose states can be changed, as described in detail later.
|
||||||
This is because of the rule that only constant expressions can be assigned to constants. Constant expressions are also discussed later.
|
This is because of the rule that only constant expressions can be assigned to constants. Constant expressions are also discussed later.
|
||||||
|
|
||||||
```python,compile_fail
|
```python
|
||||||
X = 1 # OK
|
X = 1 # OK
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
X = !1 # TypeError: cannot define Int! object as a constant
|
X = !1 # TypeError: cannot define Int! object as a constant
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ C!.
|
||||||
x
|
x
|
||||||
```
|
```
|
||||||
|
|
||||||
Procedural methods can also take [ownership](./18_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition.
|
Procedural methods can also take [ownership](./19_ownership.md) of `self`. Remove `ref` or `ref!` from the method definition.
|
||||||
|
|
||||||
```python,compile_fail
|
```python,compile_fail
|
||||||
n = 1
|
n = 1
|
||||||
|
|
|
@ -18,7 +18,7 @@ The difference from JavaScript object literals is that they are not accessible a
|
||||||
This is because access to the value is determined at compile-time, and because dictionaries and records are different things. In other words, `{"name": "John"}` is a Dict and `{name = "John"}` is a record.
|
This is because access to the value is determined at compile-time, and because dictionaries and records are different things. In other words, `{"name": "John"}` is a Dict and `{name = "John"}` is a record.
|
||||||
So how should we use dictionaries and records?
|
So how should we use dictionaries and records?
|
||||||
In general, we recommend using records. Records have the advantages of being checked at compile-time for the existence of elements and of being able to specify __visibility_.
|
In general, we recommend using records. Records have the advantages of being checked at compile-time for the existence of elements and of being able to specify __visibility_.
|
||||||
Specifying visibility is equivalent to specifying public/private in Java and other languages. For details, see [visibility](./19_visibility.md) for details.
|
Specifying visibility is equivalent to specifying public/private in Java and other languages. For details, see [visibility](./20_visibility.md) for details.
|
||||||
|
|
||||||
```python,compile_fail
|
```python,compile_fail
|
||||||
a = {x = 1; .y = x + 1}
|
a = {x = 1; .y = x + 1}
|
||||||
|
@ -53,7 +53,7 @@ assert o.i == 1
|
||||||
```
|
```
|
||||||
|
|
||||||
There is a notable syntax with respect to records. When all the attribute values of a record are classes (not structural types), the record itself behaves as a type with its own attributes as required attributes.
|
There is a notable syntax with respect to records. When all the attribute values of a record are classes (not structural types), the record itself behaves as a type with its own attributes as required attributes.
|
||||||
Such a type is called a record type. See the section [Record] for more details.
|
Such a type is called a record type. See the section [Record](../API/types/classes/Record.md) for more details.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# record
|
# record
|
||||||
|
|
|
@ -8,15 +8,15 @@ Also, see [here](../terms.md) for terminology.
|
||||||
|
|
||||||
* ! → [side effect](./07_side_effect.md)
|
* ! → [side effect](./07_side_effect.md)
|
||||||
* !-type → [mutable type](./type/18_mut.md)
|
* !-type → [mutable type](./type/18_mut.md)
|
||||||
* ? → [error handling](./30_error_handling.md)
|
* ? → [error handling](./31_error_handling.md)
|
||||||
* # → [Str](./00_basic.md/#comment)
|
* # → [Str](./00_basic.md/#comments)
|
||||||
* $ → [shared](./type/advanced/shared.md)
|
* $ → [shared](./type/advanced/shared.md)
|
||||||
* %
|
* %
|
||||||
* &
|
* &
|
||||||
* &&
|
* &&
|
||||||
* [′ (single quote)](./20_naming_rule.md#literal-identifiers)
|
* [′ (single quote)](./21_naming_rule.md#literal-identifiers)
|
||||||
* [" (double quote)](./01_literal.md#str-literal)
|
* [" (double quote)](./01_literal.md#str-literal)
|
||||||
* () → [Tuple](./11_tuple.md)
|
* () → [Tuple](./13_tuple.md)
|
||||||
* *
|
* *
|
||||||
* * → [*-less multiplication](./01_literal.md/#less-multiplication)
|
* * → [*-less multiplication](./01_literal.md/#less-multiplication)
|
||||||
* + (prefix) → [operator](./06_operator.md)
|
* + (prefix) → [operator](./06_operator.md)
|
||||||
|
@ -28,19 +28,19 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* −_ → − (prefix)
|
* −_ → − (prefix)
|
||||||
* − (infix) → [operator](./06_operator.md)
|
* − (infix) → [operator](./06_operator.md)
|
||||||
* − (infix) → [Trait](./type/03_trait.md)
|
* − (infix) → [Trait](./type/03_trait.md)
|
||||||
* −> → [anonymous function](./21_lambda.md)
|
* −> → [anonymous function](./22_lambda.md)
|
||||||
* . → [Visibility](./19_visibility.md)
|
* . → [Visibility](./20_visibility.md)
|
||||||
* .. → [closed range operator](./01_literal.md/#range-object)
|
* .. → [closed range operator](./01_literal.md/#range-object)
|
||||||
* ..< → [right-open range operator](./01_literal.md/#range-object)
|
* ..< → [right-open range operator](./01_literal.md/#range-object)
|
||||||
* ...
|
* ...
|
||||||
* ... → [Extract assignment](./28_spread_syntax.md#extract-assignment)
|
* ... → [Extract assignment](./29_spread_syntax.md#extract-assignment)
|
||||||
* ... → [Variable-length arguments](./04_function.md#variable-length-arguments)
|
* ... → [Variable-length arguments](./04_function.md#variable-length-arguments)
|
||||||
* /
|
* /
|
||||||
* :
|
* :
|
||||||
* : → [Colon application style](./04_function.md)
|
* : → [Colon application style](./04_function.md)
|
||||||
* : → [Type ascription](./03_declaration.md.md)
|
* : → [Type ascription](./03_declaration.md)
|
||||||
* : → [Keyword arguments](./04_function.md)
|
* : → [Keyword arguments](./04_function.md)
|
||||||
* :: → [private variable modifier](./19_visibility.md)
|
* :: → [private variable modifier](./20_visibility.md)
|
||||||
* := → [default parameters](./04_function.md)
|
* := → [default parameters](./04_function.md)
|
||||||
* ;
|
* ;
|
||||||
* <
|
* <
|
||||||
|
@ -49,13 +49,13 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* <=
|
* <=
|
||||||
* <.. → [left-open range operator](./01_literal.md/#range-object)
|
* <.. → [left-open range operator](./01_literal.md/#range-object)
|
||||||
* <..< → [open range operator](./01_literal.md/#range-object)
|
* <..< → [open range operator](./01_literal.md/#range-object)
|
||||||
* = → [Variable](./19_visibility.md)
|
* = → [Variable](./20_visibility.md)
|
||||||
* ==
|
* ==
|
||||||
* => → [anonymous procedure operator](./08_procedure.md)
|
* => → [anonymous procedure operator](./08_procedure.md)
|
||||||
* >
|
* >
|
||||||
* >>
|
* >>
|
||||||
* >=
|
* >=
|
||||||
* @ → [decorator](./29_decorator.md)
|
* @ → [decorator](./30_decorator.md)
|
||||||
* [] → [Array](./10_array.md)
|
* [] → [Array](./10_array.md)
|
||||||
* \ → [Escaping](./00_basic.md)
|
* \ → [Escaping](./00_basic.md)
|
||||||
* ^
|
* ^
|
||||||
|
@ -63,11 +63,11 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* _ → [Type erasure](./type/advanced/erasure.md)
|
* _ → [Type erasure](./type/advanced/erasure.md)
|
||||||
* _+_ → + (infix)
|
* _+_ → + (infix)
|
||||||
* _-_ → − (infix)
|
* _-_ → − (infix)
|
||||||
* [`` (back quote)](./22_subroutine.md#operator)
|
* [`` (back quote)](./23_subroutine.md#operator)
|
||||||
* {}
|
* {}
|
||||||
* [{} type](./type/01_type_system.md)
|
* [{} type](./type/01_type_system.md)
|
||||||
* {=} → [Type System](./type/01_type_system.md#classification)
|
* {=} → [Type System](./type/01_type_system.md#classification)
|
||||||
* [{=} type](./13_record.md#empty-record)
|
* [{=} type](./14_record.md#empty-record)
|
||||||
* |
|
* |
|
||||||
* || → [Type variable list](./type/advanced/)
|
* || → [Type variable list](./type/advanced/)
|
||||||
* ~
|
* ~
|
||||||
|
@ -83,11 +83,11 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* [algebraic type](./type/13_algebraic.md)
|
* [algebraic type](./type/13_algebraic.md)
|
||||||
* [And]
|
* [And]
|
||||||
* [and]
|
* [and]
|
||||||
* [anonymous function](./21_lambda.md)
|
* [anonymous function](./22_lambda.md)
|
||||||
* anonymous type → [Type system](./type/01_type_system.md)
|
* anonymous type → [Type system](./type/01_type_system.md)
|
||||||
* [Array](./10_array.md)
|
* [Array](./10_array.md)
|
||||||
* [assert]
|
* assert
|
||||||
* [Attach](./29_decorator.md#attach)
|
* [Attach](./30_decorator.md#attach)
|
||||||
* [attribute](type/09_attributive.md)
|
* [attribute](type/09_attributive.md)
|
||||||
* [Attribute definitions](./type/02_basic.md#attribute-definitions)
|
* [Attribute definitions](./type/02_basic.md#attribute-definitions)
|
||||||
* [Attribute type](./type/09_attributive.md)
|
* [Attribute type](./type/09_attributive.md)
|
||||||
|
@ -96,7 +96,7 @@ Also, see [here](../terms.md) for terminology.
|
||||||
|
|
||||||
* [Bool, Boolean](./01_literal.md#boolean-object)
|
* [Bool, Boolean](./01_literal.md#boolean-object)
|
||||||
* [Boolean object](./01_literal.md#boolean-object)
|
* [Boolean object](./01_literal.md#boolean-object)
|
||||||
* [borrowing](./18_ownership.md#borrow)
|
* [borrowing](./19_ownership.md#borrow)
|
||||||
|
|
||||||
### C
|
### C
|
||||||
|
|
||||||
|
@ -104,43 +104,43 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* [Comments](./00_basic.md#comments)
|
* [Comments](./00_basic.md#comments)
|
||||||
* [Complex object](./01_literal.md#complex-object)
|
* [Complex object](./01_literal.md#complex-object)
|
||||||
* [Compile-time functions](./04_function.md#compile-time-functions)
|
* [Compile-time functions](./04_function.md#compile-time-functions)
|
||||||
* [circular references](./18_ownership.md#circular-references)
|
* [circular references](./19_ownership.md#circular-references)
|
||||||
* [Class](./type/04_class.md)
|
* [Class](./type/04_class.md)
|
||||||
* [Class relationship](./type/04_class.md#class-relationships)
|
* [Class relationship](./type/04_class.md#class-relationships)
|
||||||
* [Class upcasting](./type/16_subtyping.md#class-upcasting)
|
* [Class upcasting](./type/16_subtyping.md#class-upcasting)
|
||||||
* [Colon application style](./04_function.md#colon-application-style)
|
* [Colon application style](./04_function.md#colon-application-style)
|
||||||
* [Closure](./23_closure.md)
|
* [Closure](./24_closure.md)
|
||||||
* [Compound literals](./01_literal.md#compound-literals)
|
* [Compound literals](./01_literal.md#compound-literals)
|
||||||
* [Complement](./type/13_algebraic.md#complement)
|
* [Complement](./type/13_algebraic.md#complement)
|
||||||
* [Comprehension](./27_comprehension.md)
|
* [Comprehension](./28_comprehension.md)
|
||||||
* [constant](./17_mutability.md#constant)
|
* [constant](./18_mutability.md#constant)
|
||||||
* [Constants](./02_name.md#constants)
|
* [Constants](./02_name.md#constants)
|
||||||
* [Context](./30_error_handling.md#context)
|
* [Context](./31_error_handling.md#context)
|
||||||
|
|
||||||
### D
|
### D
|
||||||
|
|
||||||
* [Data type](./type/01_type_system.md#data-type)
|
* [Data type](./type/01_type_system.md#data-type)
|
||||||
* [Declaration](./03_declaration.md)
|
* [Declaration](./03_declaration.md)
|
||||||
* [decorator](./29_decorator.md)
|
* [decorator](./30_decorator.md)
|
||||||
* [Default parameters](./04_function.md#default-parameters)
|
* [Default parameters](./04_function.md#default-parameters)
|
||||||
* [Del](./02_name.md#delete-an-variable)
|
* [Del](./02_name.md#delete-an-variable)
|
||||||
* [Dependent type](./type/14_dependent.md)
|
* [Dependent type](./type/14_dependent.md)
|
||||||
* Deprecated
|
* Deprecated
|
||||||
* [Dict](./12_dict.md)
|
* [Dict](./11_dict.md)
|
||||||
* [Diff](./type/13_algebraic.md#diff)
|
* [Diff](./type/13_algebraic.md#diff)
|
||||||
* distinct
|
* distinct
|
||||||
* [Downcasting](./type/17_type_casting.md#downcasting)
|
* [Downcasting](./type/17_type_casting.md#downcasting)
|
||||||
|
|
||||||
### E
|
### E
|
||||||
|
|
||||||
* [Empty record](./13_record.md#empty-record)
|
* [Empty record](./14_record.md#empty-record)
|
||||||
* [Enum class](./type/04_class.md#enum-class)
|
* [Enum class](./type/04_class.md#enum-class)
|
||||||
* [Enum type](./type/11_enum.md)
|
* [Enum type](./type/11_enum.md)
|
||||||
* [Enumerated, Interval and Refinement types](./type/12_refinement.md#enumerated-interval-and-refinement-types)
|
* [Enumerated, Interval and Refinement types](./type/12_refinement.md#enumerated-interval-and-refinement-types)
|
||||||
* [error handling](./30_error_handling.md)
|
* [error handling](./31_error_handling.md)
|
||||||
* [Existential type](./type/advanced/existential.md)
|
* [Existential type](./type/advanced/existential.md)
|
||||||
* [Exponential literal](./01_literal.md#exponential-literal)
|
* [Exponential literal](./01_literal.md#exponential-literal)
|
||||||
* [Extract assignment](./28_spread_syntax.md#extract-assignment)
|
* [Extract assignment](./29_spread_syntax.md#extract-assignment)
|
||||||
|
|
||||||
### F
|
### F
|
||||||
|
|
||||||
|
@ -148,14 +148,14 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* [Float object](./01_literal.md#float-object)
|
* [Float object](./01_literal.md#float-object)
|
||||||
* [for](./05_builtin_funcs.md#for)
|
* [for](./05_builtin_funcs.md#for)
|
||||||
* [For-All patch](./type/07_patch.md#for-all-patch)
|
* [For-All patch](./type/07_patch.md#for-all-patch)
|
||||||
* [freeze](./18_ownership.md#freeze)
|
* [freeze](./19_ownership.md#freeze)
|
||||||
* [Function](./04_function.md)
|
* [Function](./04_function.md)
|
||||||
* [Function definition with multiple patterns](./04_function.md#function-definition-with-multiple-patterns)
|
* [Function definition with multiple patterns](./04_function.md#function-definition-with-multiple-patterns)
|
||||||
|
|
||||||
### G
|
### G
|
||||||
|
|
||||||
* [GADTs(Generalized Algebraic Data Types)](./type/advanced/GADTs.md)
|
* [GADTs(Generalized Algebraic Data Types)](./type/advanced/GADTs.md)
|
||||||
* [Generator](./34_generator.md)
|
* [Generator](./35_generator.md)
|
||||||
* [Glue Patch](./type/07_patch.md#glue-patch)
|
* [Glue Patch](./type/07_patch.md#glue-patch)
|
||||||
|
|
||||||
### H
|
### H
|
||||||
|
@ -166,19 +166,19 @@ Also, see [here](../terms.md) for terminology.
|
||||||
|
|
||||||
* [id](./09_builtin_procs.md#id)
|
* [id](./09_builtin_procs.md#id)
|
||||||
* [if](./05_builtin_funcs.md#if)
|
* [if](./05_builtin_funcs.md#if)
|
||||||
* [import](./33_package_system.md)
|
* [import](./34_package_system.md)
|
||||||
* [impl](./29_decorator.md#impl)
|
* [impl](./30_decorator.md#impl)
|
||||||
* [in]
|
* in
|
||||||
* [Indention](./00_basic.md#indentation)
|
* [Indention](./00_basic.md#indentation)
|
||||||
* [Instant block](./13_record.md#instant-block)
|
* [Instant block](./14_record.md#instant-block)
|
||||||
* [Instance/class attributes](./type/04_class.md#instance-and-class-attributes)
|
* [Instance/class attributes](./type/04_class.md#instance-and-class-attributes)
|
||||||
* [inheritable](./29_decorator.md#inheritable)
|
* [inheritable](./30_decorator.md#inheritable)
|
||||||
* [inheritance](./type/05_inheritance.md)
|
* [inheritance](./type/05_inheritance.md)
|
||||||
* [Int](./01_literal.md)
|
* [Int](./01_literal.md)
|
||||||
* [Integration with Python](./32_integration_with_Python.md)
|
* [Integration with Python](./33_integration_with_Python.md)
|
||||||
* [Interval Type](./type/10_interval.md)
|
* [Interval Type](./type/10_interval.md)
|
||||||
* [Intersection](./type/13_algebraic.md#intersection)
|
* [Intersection](./type/13_algebraic.md#intersection)
|
||||||
* [Iterator](./16_iterator.md)
|
* [Iterator](./17_iterator.md)
|
||||||
|
|
||||||
### J
|
### J
|
||||||
|
|
||||||
|
@ -189,59 +189,59 @@ Also, see [here](../terms.md) for terminology.
|
||||||
|
|
||||||
### L
|
### L
|
||||||
|
|
||||||
* lambda → [anonymous function](./21_lambda.md)
|
* lambda → [anonymous function](./22_lambda.md)
|
||||||
* let-polymorphism → [rank 1 polymorphism]
|
* let-polymorphism → [rank 1 polymorphism]
|
||||||
* [Literal Identifiers](./20_naming_rule.md#literal-identifiers)
|
* [Literal Identifiers](./21_naming_rule.md#literal-identifiers)
|
||||||
|
|
||||||
### M
|
### M
|
||||||
|
|
||||||
* [match]
|
* match
|
||||||
* [Marker trait](./type/advanced/marker_trait.md)
|
* [Marker trait](./type/advanced/marker_trait.md)
|
||||||
* [Method](./07_side_effect.md#methods)
|
* [Method](./07_side_effect.md#methods)
|
||||||
* Modifier → [decorator](./29_decorator.md)
|
* Modifier → [decorator](./30_decorator.md)
|
||||||
* [module](./24_module.md)
|
* [module](./25_module.md)
|
||||||
* [Multiple inheritance](type/05_inheritance.md#multiple-inheritance)
|
* [Multiple inheritance](type/05_inheritance.md#multiple-inheritance)
|
||||||
* [Multi-layer (multi-level) Inheritance](type/05_inheritance.md#multi-layer-multi-level-inheritance)
|
* [Multi-layer (multi-level) Inheritance](type/05_inheritance.md#multi-layer-multi-level-inheritance)
|
||||||
* [Mutable type](./type/18_mut.md)
|
* [Mutable type](./type/18_mut.md)
|
||||||
* [Mutable structure type](./type/advanced/mut_struct.md)
|
* [Mutable structure type](./type/advanced/mut_struct.md)
|
||||||
* [Mutability](./17_mutability.md)
|
* [Mutability](./18_mutability.md)
|
||||||
|
|
||||||
### N
|
### N
|
||||||
|
|
||||||
* [Nat](./01_literal.md#int-literal)
|
* [Nat](./01_literal.md#int-literal)
|
||||||
* [Never]
|
* Never
|
||||||
* [New type](./type/advanced/newtype.md)
|
* [New type](./type/advanced/newtype.md)
|
||||||
* [Heterogeneous Dict](./12_dict.md#heterogeneous-dict)
|
* [Heterogeneous Dict](./11_dict.md#heterogeneous-dict)
|
||||||
* None → [None Object]
|
* None → [None Object]
|
||||||
* [None Object]
|
* None Object
|
||||||
* Nominal Subtyping → [Class](./type/04_class.md)
|
* Nominal Subtyping → [Class](./type/04_class.md)
|
||||||
* [Not]
|
* Not
|
||||||
* [not]
|
* not
|
||||||
|
|
||||||
### O
|
### O
|
||||||
|
|
||||||
* [Object](./25_object_system.md)
|
* [Object](./26_object_system.md)
|
||||||
* [Option]
|
* [Option]
|
||||||
* [Or]
|
* [Or]
|
||||||
* [or]
|
* [or]
|
||||||
* [Ord]
|
* [Ord]
|
||||||
* [ownership system](./18_ownership.md)
|
* [ownership system](./19_ownership.md)
|
||||||
* [Overloading](./type/advanced/overloading.md)
|
* [Overloading](./type/advanced/overloading.md)
|
||||||
* [Overriding](./type/05_inheritance.md#overriding)
|
* [Overriding](./type/05_inheritance.md#overriding)
|
||||||
* [Override in trait](./type/03_trait.md#override-in-trait)
|
* [Override in trait](./type/03_trait.md#override-in-trait)
|
||||||
|
|
||||||
### P
|
### P
|
||||||
|
|
||||||
* [Panic](./30_error_handling.md#panic)
|
* [Panic](./31_error_handling.md#panic)
|
||||||
* [Patch](./type/07_patch.md)
|
* [Patch](./type/07_patch.md)
|
||||||
* [Pattern match](./26_pattern_matching.md)
|
* [Pattern match](./27_pattern_matching.md)
|
||||||
* [Phantom class](./type/advanced/phantom.md)
|
* [Phantom class](./type/advanced/phantom.md)
|
||||||
* [pipeline operator](./31_pipeline.md)
|
* [pipeline operator](./32_pipeline.md)
|
||||||
* [Predicate](./type/19_bound.md#predicate)
|
* [Predicate](./type/19_bound.md#predicate)
|
||||||
* [print!]
|
* print!
|
||||||
* [Procedures](./08_procedure.md)
|
* [Procedures](./08_procedure.md)
|
||||||
* [Projection type](./type/advanced/projection.md)
|
* [Projection type](./type/advanced/projection.md)
|
||||||
* Python → [Integration with Python](./32_integration_with_Python.md)
|
* Python → [Integration with Python](./33_integration_with_Python.md)
|
||||||
|
|
||||||
### Q
|
### Q
|
||||||
|
|
||||||
|
@ -251,15 +251,15 @@ Also, see [here](../terms.md) for terminology.
|
||||||
### R
|
### R
|
||||||
|
|
||||||
* [Range Object](./01_literal.md#range-object)
|
* [Range Object](./01_literal.md#range-object)
|
||||||
* [ref]
|
* ref
|
||||||
* [ref!]
|
* ref!
|
||||||
* [Record](./13_record.md)
|
* [Record](./14_record.md)
|
||||||
* [Recursive functions](./04_function.md#recursive-functions)
|
* [Recursive functions](./04_function.md#recursive-functions)
|
||||||
* [Refinement pattern](./type/12_refinement.md#refinement-pattern)
|
* [Refinement pattern](./type/12_refinement.md#refinement-pattern)
|
||||||
* [Refinement type](./type/12_refinement.md)
|
* [Refinement type](./type/12_refinement.md)
|
||||||
* [replication](./18_ownership.md#replication)
|
* [replication](./19_ownership.md#replication)
|
||||||
* [Replacing traits](./type/05_inheritance.md#replacing-traits-or-what-looks-like-it)
|
* [Replacing traits](./type/05_inheritance.md#replacing-traits-or-what-looks-like-it)
|
||||||
* Result → [error handling](./30_error_handling.md)
|
* Result → [error handling](./31_error_handling.md)
|
||||||
|
|
||||||
### S
|
### S
|
||||||
|
|
||||||
|
@ -269,9 +269,9 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* [Shared reference](./type/advanced/shared.md)
|
* [Shared reference](./type/advanced/shared.md)
|
||||||
* [side-effect](./07_side_effect.md)
|
* [side-effect](./07_side_effect.md)
|
||||||
* [Smart cast](./type/12_refinement.md#smart-cast)
|
* [Smart cast](./type/12_refinement.md#smart-cast)
|
||||||
* [Spread assignment](./28_spread_syntax.md)
|
* [Spread assignment](./29_spread_syntax.md)
|
||||||
* [special type variables](./type/advanced/special.md#special-type-variables)
|
* [special type variables](./type/advanced/special.md#special-type-variables)
|
||||||
* [Stack trace](30_error_handling.md#stack-trace)
|
* [Stack trace](./31_error_handling.md#stack-trace)
|
||||||
* [Structure type](./type/01_type_system.md#structure-type-anonymous-type)
|
* [Structure type](./type/01_type_system.md#structure-type-anonymous-type)
|
||||||
* [Structural patch](./type/07_patch.md#structural-patch)
|
* [Structural patch](./type/07_patch.md#structural-patch)
|
||||||
* [Structural trait](./type/03_trait.md#structural-traits)
|
* [Structural trait](./type/03_trait.md#structural-traits)
|
||||||
|
@ -282,17 +282,17 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* [Subtyping of subroutines](./type/16_subtyping.md#subtyping-of-subroutines)
|
* [Subtyping of subroutines](./type/16_subtyping.md#subtyping-of-subroutines)
|
||||||
* [Subtype specification](./type/02_basic.md#subtype-specification)
|
* [Subtype specification](./type/02_basic.md#subtype-specification)
|
||||||
* [Subtyping of polymorphic function types](./type/15_quantified.md#subtyping-of-polymorphic-function-types)
|
* [Subtyping of polymorphic function types](./type/15_quantified.md#subtyping-of-polymorphic-function-types)
|
||||||
* [Subroutine signatures](./22_subroutine.md)
|
* [Subroutine signatures](./23_subroutine.md)
|
||||||
|
|
||||||
### T
|
### T
|
||||||
|
|
||||||
* [Test](./29_decorator.md#test)
|
* [Test](./30_decorator.md#test)
|
||||||
* [Traits](./type/03_trait.md)
|
* [Traits](./type/03_trait.md)
|
||||||
* [Trait inclusion](./type/03_trait.md#trait-inclusion)
|
* [Trait inclusion](./type/03_trait.md#trait-inclusion)
|
||||||
* True → [Boolean object](./01_literal.md#boolean-object)
|
* True → [Boolean object](./01_literal.md#boolean-object)
|
||||||
* [True algebraic type](./type/13_algebraic.md#true-algebraic-type)
|
* [True algebraic type](./type/13_algebraic.md#true-algebraic-type)
|
||||||
* [Type]
|
* Type
|
||||||
* [type](./15_type.md)
|
* [type](./16_type.md)
|
||||||
* [Type arguments in method definitions](./type/15_quantified.md#type-arguments-in-method-definitions)
|
* [Type arguments in method definitions](./type/15_quantified.md#type-arguments-in-method-definitions)
|
||||||
* [Type bound](./type/19_bound.md)
|
* [Type bound](./type/19_bound.md)
|
||||||
* [Type definitions](./type/01_type_system.md#type-definitions)
|
* [Type definitions](./type/01_type_system.md#type-definitions)
|
||||||
|
@ -301,12 +301,12 @@ Also, see [here](../terms.md) for terminology.
|
||||||
* [Type specification](./type/02_basic.md#type-specification)
|
* [Type specification](./type/02_basic.md#type-specification)
|
||||||
* [Type system](./type/01_type_system.md)
|
* [Type system](./type/01_type_system.md)
|
||||||
* [Type widening](./type/advanced/widening.md)
|
* [Type widening](./type/advanced/widening.md)
|
||||||
* [Tuple](./11_tuple.md)
|
* [Tuple](./13_tuple.md)
|
||||||
|
|
||||||
### U
|
### U
|
||||||
|
|
||||||
* [union](type/13_algebraic.md#union)
|
* [union](type/13_algebraic.md#union)
|
||||||
* [Unit](./11_tuple.md#unit)
|
* [Unit](./13_tuple.md#unit)
|
||||||
* [Upcasting](type/17_type_casting.md#upcasting)
|
* [Upcasting](type/17_type_casting.md#upcasting)
|
||||||
|
|
||||||
### V
|
### V
|
||||||
|
@ -317,7 +317,7 @@ Also, see [here](../terms.md) for terminology.
|
||||||
|
|
||||||
### W
|
### W
|
||||||
|
|
||||||
* [while]
|
* while!
|
||||||
|
|
||||||
### X
|
### X
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/architecture.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
|
[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/compiler/architecture.md&commit_hash=a711efa99b325ba1012f6897e7b0e2bdb947d8a1)
|
||||||
|
|
||||||
## 1. Erg スクリプト (.er) をスキャンし、`TokenStream` (parser/lex.rs) を生成する
|
## 1. Erg スクリプト (.er) をスキャンし、`TokenStream` を生成する
|
||||||
|
|
||||||
|
src: [erg_parser/lex.rs](../../../crates/erg_parser/lex.rs)
|
||||||
|
|
||||||
* parser/lexer/Lexer が `TokenStream` を生成する (これは `Token` のイテレータである。`TokenStream` は `Lexer::collect()` によって生成できる)
|
* parser/lexer/Lexer が `TokenStream` を生成する (これは `Token` のイテレータである。`TokenStream` は `Lexer::collect()` によって生成できる)
|
||||||
* [`Lexer`](./phases/01_lex.md) は `Lexer::new` または `Lexer::from_str` から構築される。`Lexer::new` はファイルまたはコマンド オプションからコードを読み取る。
|
* [`Lexer`](./phases/01_lex.md) は `Lexer::new` または `Lexer::from_str` から構築される。`Lexer::new` はファイルまたはコマンド オプションからコードを読み取る。
|
||||||
|
@ -11,29 +13,43 @@
|
||||||
* `Lexer` を単体で使用する場合は、代わりに`LexerRunner` を使用します。`Lexer` は単なるイテレータであり、`Runnable` トレイトを実装していない。
|
* `Lexer` を単体で使用する場合は、代わりに`LexerRunner` を使用します。`Lexer` は単なるイテレータであり、`Runnable` トレイトを実装していない。
|
||||||
* `Runnable` は、 `LexerRunner` 、 `ParserRunner` 、 `Compiler` 、および `DummyVM` に実装されている。
|
* `Runnable` は、 `LexerRunner` 、 `ParserRunner` 、 `Compiler` 、および `DummyVM` に実装されている。
|
||||||
|
|
||||||
## 2. `TokenStream` -> `AST` (parser/parse.rs)
|
## 2. `TokenStream` -> `AST`
|
||||||
|
|
||||||
|
src: [erg_parser/parse.rs](../../../crates/erg_parser/parse.rs)
|
||||||
|
|
||||||
* [`Parser`](./phases/02_parse.md) は `Lexer` と同様に `Parser::new` と `Parser::from_str` の 2 つのコンストラクタを持ち、`Parser::parse` は `AST` を返す。
|
* [`Parser`](./phases/02_parse.md) は `Lexer` と同様に `Parser::new` と `Parser::from_str` の 2 つのコンストラクタを持ち、`Parser::parse` は `AST` を返す。
|
||||||
* `AST`は`Vec<Expr>`のラッパー型で、「抽象構文木」を表す。
|
* `AST`は`Vec<Expr>`のラッパー型で、「抽象構文木」を表す。
|
||||||
|
|
||||||
### 2.1 `AST`の脱糖
|
### 2.1 `AST`の脱糖
|
||||||
|
|
||||||
|
src: [erg_parser/desugar.rs](../../../crates/erg_parser/desugar.rs)
|
||||||
|
|
||||||
* [`Desugarer`](./phases/03_desugar.md)
|
* [`Desugarer`](./phases/03_desugar.md)
|
||||||
* パターンマッチを単一の変数代入列へ変換 (`Desugarer::desugar_nest_vars_pattern`)
|
* パターンマッチを単一の変数代入列へ変換 (`Desugarer::desugar_nest_vars_pattern`)
|
||||||
* 複数パターン定義構文をmatchへ変換 (`Desugarer::desugar_multiple_pattern_def`)
|
* 複数パターン定義構文をmatchへ変換 (`Desugarer::desugar_multiple_pattern_def`)
|
||||||
|
|
||||||
|
### 2.2 `AST`の並び替え・結合
|
||||||
|
|
||||||
|
src: [erg_compiler/reorder.rs](../../../crates\erg_compiler\reorder.rs)
|
||||||
|
|
||||||
|
* クラスメソッドをクラス定義に結合する
|
||||||
|
* メソッド定義は定義ファイル外でも可能となっている
|
||||||
|
* 現在の実装は不完全、同一ファイル内のみ
|
||||||
|
|
||||||
## 3. `AST` -> `HIR`
|
## 3. `AST` -> `HIR`
|
||||||
|
|
||||||
(主要な)ソースコード: [erg_compiler/lower.rs](../../../compiler/erg_compiler/lower.rs)
|
(主要な)ソースコード: [erg_compiler/lower.rs](../../../crates/erg_compiler/lower.rs)
|
||||||
|
|
||||||
## 3.1 名前解決
|
## 3.1 名前解決
|
||||||
|
|
||||||
|
現在の実装では型チェック中に行われる
|
||||||
|
|
||||||
* 型推論の前に全てのAST(importされたモジュール含む)を走査し、名前解決を行う
|
* 型推論の前に全てのAST(importされたモジュール含む)を走査し、名前解決を行う
|
||||||
* 定数の循環検査や並び替えなどが行われるほか、型推論のためのContextが作成される(ただし、このContextに登録された変数の情報ははまだ殆どが未確定)
|
* 定数の循環検査や並び替えなどが行われるほか、型推論のためのContextが作成される(ただし、このContextに登録された変数の情報ははまだ殆どが未確定)
|
||||||
|
|
||||||
### 3.2 型チェックと推論
|
### 3.2 型チェックと推論
|
||||||
|
|
||||||
ソースコード: [erg_compiler/lower.rs](../../../compiler/erg_compiler/lower.rs)
|
ソースコード: [erg_compiler/lower.rs](../../../crates/erg_compiler/lower.rs)
|
||||||
|
|
||||||
* `HIR` は、すべての変数の型情報を持っており、「高レベルの中間表現」を表す。
|
* `HIR` は、すべての変数の型情報を持っており、「高レベルの中間表現」を表す。
|
||||||
* `ASTLowerer` は Parser や Lexer と同じように構築できる。
|
* `ASTLowerer` は Parser や Lexer と同じように構築できる。
|
||||||
|
@ -43,23 +59,25 @@
|
||||||
|
|
||||||
## 4. 副作用のチェック
|
## 4. 副作用のチェック
|
||||||
|
|
||||||
ソースコード: [erg_compiler/effectcheck.rs](../../../compiler/erg_compiler/effectcheck.rs)
|
ソースコード: [erg_compiler/effectcheck.rs](../../../crates/erg_compiler/effectcheck.rs)
|
||||||
|
|
||||||
## 4. 所有権の確認
|
## 5. 所有権の確認
|
||||||
|
|
||||||
ソースコード: [erg_compiler/ownercheck.rs](../../../compiler/erg_compiler/ownercheck.rs)
|
ソースコード: [erg_compiler/ownercheck.rs](../../../crates/erg_compiler/ownercheck.rs)
|
||||||
|
|
||||||
## 5. `HIR`の脱糖
|
## 6. `HIR`の脱糖
|
||||||
|
|
||||||
ソースコード: [erg_compiler/desugar_hir.rs](../../../compiler/erg_compiler/desugar_hir.rs)
|
ソースコード: [erg_compiler/desugar_hir.rs](../../../crates/erg_compiler/desugar_hir.rs)
|
||||||
|
|
||||||
* Pythonの文法と整合しない部分を変換する
|
* Pythonの文法と整合しない部分を変換する
|
||||||
* クラスのメンバ変数を関数に変換
|
* クラスのメンバ変数を関数に変換
|
||||||
|
|
||||||
## 6. リンク
|
## 7. リンク
|
||||||
|
|
||||||
|
ソースコード: [erg_compiler/link.rs](../../../crates/erg_compiler/link.rs)
|
||||||
|
|
||||||
* 全てのモジュールを読み込み、依存関係を解決し、単一のHIRに結合する
|
* 全てのモジュールを読み込み、依存関係を解決し、単一のHIRに結合する
|
||||||
|
|
||||||
## 7. `HIR` からバイトコード (`CodeObj`) を生成
|
## 8. `HIR` からバイトコード (`CodeObj`) を生成
|
||||||
|
|
||||||
ソースコード: [erg_compiler/codegen.rs](../../../compiler/erg_compiler/codegen.rs)
|
ソースコード: [erg_compiler/codegen.rs](../../../crates/erg_compiler/codegen.rs)
|
||||||
|
|
|
@ -38,3 +38,7 @@ Erg 内部オプション、ヘルプ (ヘルプ、著作権、ライセンス
|
||||||
|
|
||||||
`--language-server`オプションが利用可能になる。
|
`--language-server`オプションが利用可能になる。
|
||||||
`erg --language-server`でLanguage Serverが起動する。
|
`erg --language-server`でLanguage Serverが起動する。
|
||||||
|
|
||||||
|
## py_compatible
|
||||||
|
|
||||||
|
Python互換モードを有効にする。APIや文法の一部がPythonと互換になる。[pylyzer](https://github.com/mtshiba/pylyzer)のために使用される。
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
* ドキュメント内で初出の用語は、必ず定義や意味、またはリンクを併記する。
|
* ドキュメント内で初出の用語は、必ず定義や意味、またはリンクを併記する。
|
||||||
* ただし書きとしての()は、補助的ではあるものの本文の理解に必要な文の場合のみ使用し、本文の理解に必須でない文は脚注を使用する[<sup id="f1">1</sup>](#1)。
|
* ただし書きとしての()は、補助的ではあるものの本文の理解に必要な文の場合のみ使用し、本文の理解に必須でない文は脚注を使用する[<sup id="f1">1</sup>](#1)。
|
||||||
* ドキュメントの内容が古くなっていた場合は、[この方法](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)に従って更新する。
|
* ドキュメントの内容が古くなっていた場合は、[この方法](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)に従って更新する。
|
||||||
|
* syntax以下のファイルは、ドキュメントに含めないものを除きファイル名の頭に連番を付ける。
|
||||||
|
* 挿入や入れ替えを自動で行うスクリプトがdoc/script内に存在する。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
pre-commitを使ってclippyのチェックやテストを自動で行わせています。
|
pre-commitを使ってclippyのチェックやテストを自動で行わせています。
|
||||||
バグがなくても最初の実行でチェックが失敗する場合があります。その場合はもう一度コミットを試みてください。
|
バグがなくても最初の実行でチェックが失敗する場合があります。その場合はもう一度コミットを試みてください。
|
||||||
|
|
||||||
* Python3インタープリタ
|
* Python3インタープリタ (3.7~3.11)
|
||||||
|
|
||||||
|
様々なバージョンでErgの挙動を検査したい場合は [pyenv](https://github.com/pyenv/pyenv) 等の導入をお勧めします。
|
||||||
|
|
||||||
## 推奨
|
## 推奨
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ C = Class {x = Int}
|
||||||
.method self = ...
|
.method self = ...
|
||||||
```
|
```
|
||||||
|
|
||||||
`'''`の直後に言語コードを記述することで、ドキュメントの言語を指定することが出来ます。すると[Erg Language Server](https://github.com/erg-lang/erg/tree/main/compiler/els)は各言語バージョンに合わせたドキュメントをMarkdown形式で表示します(デフォルトの言語は英語です)。
|
`'''`の直後に言語コードを記述することで、ドキュメントの言語を指定することが出来ます。すると[Erg Language Server](https://github.com/erg-lang/erg/tree/main/crates/els)は各言語バージョンに合わせたドキュメントをMarkdown形式で表示します(デフォルトの言語は英語です)。
|
||||||
登録されている言語コードについては[こちら](https://github.com/erg-lang/erg/blob/main/doc/JA/dev_guide/i18n_messages.md)を参照してください。
|
登録されている言語コードについては[こちら](https://github.com/erg-lang/erg/blob/main/doc/JA/dev_guide/i18n_messages.md)を参照してください。
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
|
@ -82,25 +82,25 @@ assert 1e-10 == 0.0000000001
|
||||||
[], [1], [1, 2, 3], ["1", "2",], ...
|
[], [1], [1, 2, 3], ["1", "2",], ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [組リテラル(Tuple Literal)](./11_tuple.md)
|
### [組リテラル(Tuple Literal)](./13_tuple.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
(), (1, 2, 3), (1, "hello", True), ...
|
(), (1, 2, 3), (1, "hello", True), ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [辞書リテラル(Dict Literal)](./12_dict.md)
|
### [辞書リテラル(Dict Literal)](./11_dict.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
|
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [レコードリテラル(Record Literal)](./13_record.md)
|
### [レコードリテラル(Record Literal)](./14_record.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
|
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [集合リテラル(Set Literal)](./14_set.md)
|
### [集合リテラル(Set Literal)](./15_set.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, ...
|
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, ...
|
||||||
|
|
|
@ -112,7 +112,7 @@ X = !1 # TypeError: cannot define Int! object as a constant
|
||||||
|
|
||||||
`Del`関数を使うことで、代数を削除することが出来ます。その代数に依存している(その代数の値を直接参照している)他の代数もまとめて削除されます。
|
`Del`関数を使うことで、代数を削除することが出来ます。その代数に依存している(その代数の値を直接参照している)他の代数もまとめて削除されます。
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
x = 1
|
x = 1
|
||||||
y = 2
|
y = 2
|
||||||
z = 3
|
z = 3
|
||||||
|
|
23
doc/scripts/align_files.py
Normal file
23
doc/scripts/align_files.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
"""
|
||||||
|
Align file prefixes when they are not numbered consecutively.
|
||||||
|
existing files: 01_foo.md, 03_bar.md, 04_baz.md
|
||||||
|
result: 01_foo.md, 02_bar.md, 03_baz.md
|
||||||
|
"""
|
||||||
|
if __name__ == '__main__':
|
||||||
|
prev = None
|
||||||
|
diff = None
|
||||||
|
for f in sorted(glob.glob("[0-9][0-9]_*")):
|
||||||
|
if prev != None:
|
||||||
|
now_file_no = int(f.split("_")[0])
|
||||||
|
diff = now_file_no - prev
|
||||||
|
if diff != 1:
|
||||||
|
replace_to = "_".join([f"{now_file_no-diff+1:02d}", *f.split("_")[1:]])
|
||||||
|
os.rename(f, replace_to)
|
||||||
|
prev = now_file_no - diff + 1
|
||||||
|
else:
|
||||||
|
prev = now_file_no
|
||||||
|
else:
|
||||||
|
prev = int(f.split("_")[0])
|
43
doc/scripts/insert_file.py
Normal file
43
doc/scripts/insert_file.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
|
||||||
|
"""
|
||||||
|
Insert a file into files followed by a sequential number. Existing files are shifted by one.
|
||||||
|
example:
|
||||||
|
existing files: 01_foo.md, 02_bar.md, 03_baz.md
|
||||||
|
1st arg(inserting file): qux.md
|
||||||
|
2nd arg(file no): 2
|
||||||
|
result: 01_foo.md, 02_qux.md, 03_bar.md, 04_baz.md
|
||||||
|
"""
|
||||||
|
if __name__ == '__main__':
|
||||||
|
file = sys.argv[1]
|
||||||
|
file_no = sys.argv[2]
|
||||||
|
if not file_no.isdigit():
|
||||||
|
raise ValueError('File number must be a number')
|
||||||
|
else:
|
||||||
|
file_no = int(file_no)
|
||||||
|
|
||||||
|
if len(glob.glob("_[0-9][0-9]_*")) > 0:
|
||||||
|
raise Exception("Escaped file already exists, rename it")
|
||||||
|
# escaping
|
||||||
|
for esc in sorted(glob.glob("[0-9][0-9]_*")):
|
||||||
|
if int(esc.split("_")[0]) < file_no: continue
|
||||||
|
else: os.rename(esc, "_" + esc)
|
||||||
|
|
||||||
|
target = f"{file_no:02d}_" + file
|
||||||
|
if os.path.exists(target):
|
||||||
|
raise OSError(f"File {target} already exists")
|
||||||
|
os.rename(file, target)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
nxt = glob.glob(f"_{file_no:02d}_*")
|
||||||
|
if len(nxt) == 0:
|
||||||
|
exit(0)
|
||||||
|
elif len(nxt) >= 2:
|
||||||
|
raise ValueError("More than one file with the same number")
|
||||||
|
else:
|
||||||
|
target = nxt[0]
|
||||||
|
replace_to = "_".join([f"{file_no+1:02d}", *target.split("_")[2:]])
|
||||||
|
os.rename(target, replace_to)
|
||||||
|
file_no += 1
|
|
@ -108,7 +108,7 @@ C = Class {x = Int}
|
||||||
```
|
```
|
||||||
|
|
||||||
您可以通过在`'''`之后立即写入语言代码来指定文档的语言。然后,[Erg语言服务器](https://github.com/erg-lang/erg/tree/main/compiler/els)将以Markdown格式显示每种语言版本的文档(默认语言为英语)。
|
您可以通过在`'''`之后立即写入语言代码来指定文档的语言。然后,[Erg语言服务器](https://github.com/erg-lang/erg/tree/main/compiler/els)将以Markdown格式显示每种语言版本的文档(默认语言为英语)。
|
||||||
参见[这里](https://github.com/erg-lang/erg/blob/main/doc/JA/dev_guide/i18n_messages.md)获取多语言相关文档
|
参见[这里](https://github.com/erg-lang/erg/blob/main/doc/zh_CN/dev_guide/i18n_messages.md)获取多语言相关文档
|
||||||
|
|
||||||
```python
|
```python
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -78,25 +78,25 @@ assert 1e-10 == 0.0000000001
|
||||||
[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
|
[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [元组字面量](./11_tuple.md)
|
### [元组字面量](./13_tuple.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
(), (1, 2, 3), (1, "hello", True), ...
|
(), (1, 2, 3), (1, "hello", True), ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [字典字面量](./12_dict.md)
|
### [字典字面量](./11_dict.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
|
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Record 字面量](./13_record.md)
|
### [Record 字面量](./14_record.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
|
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Set 字面量](./14_set.md)
|
### [Set 字面量](./15_set.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
|
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=14b0c449efc9e9da3e10a09c912a960ecfaf1c9d)
|
[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=14b0c449efc9e9da3e10a09c912a960ecfaf1c9d)
|
||||||
|
|
||||||
## 变量
|
## 变量
|
||||||
|
|
||||||
变量是一种代数; Erg 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能
|
变量是一种代数; Erg 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能
|
||||||
|
|
||||||
变量定义如下
|
变量定义如下
|
||||||
|
@ -24,9 +25,12 @@ n: Nat = 1
|
||||||
|
|
||||||
请注意,与其他语言不同,不允许多次分配
|
请注意,与其他语言不同,不允许多次分配
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
# NG
|
# NG
|
||||||
l1 = l2 = [1, 2, 3] # 语法错误: 不允许多重赋值
|
l1 = l2 = [1, 2, 3] # 语法错误: 不允许多重赋值
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
# OK
|
# OK
|
||||||
l1 = [1, 2, 3]
|
l1 = [1, 2, 3]
|
||||||
l2 = l1.clone()
|
l2 = l1.clone()
|
||||||
|
@ -67,7 +71,7 @@ assert x == 0
|
||||||
常数也是一种代数。如果标识符以大写字母开头,则将其视为常量。它们被称为常量,因为一旦定义,它们就不会改变
|
常数也是一种代数。如果标识符以大写字母开头,则将其视为常量。它们被称为常量,因为一旦定义,它们就不会改变
|
||||||
`N` 部分称为常量名(或标识符)。否则,它与变量相同
|
`N` 部分称为常量名(或标识符)。否则,它与变量相同
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
N = 0
|
N = 0
|
||||||
if True, do:
|
if True, do:
|
||||||
N = 1 # 赋值错误: 常量不能被遮蔽
|
N = 1 # 赋值错误: 常量不能被遮蔽
|
||||||
|
@ -100,6 +104,9 @@ match! x:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
X = 1 # OK
|
X = 1 # OK
|
||||||
|
```
|
||||||
|
|
||||||
|
```python,compile_fail
|
||||||
X = !1 # 类型错误: 无法定义 Int! 对象作为常量
|
X = !1 # 类型错误: 无法定义 Int! 对象作为常量
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -107,7 +114,7 @@ X = !1 # 类型错误: 无法定义 Int! 对象作为常量
|
||||||
|
|
||||||
您可以使用 `Del` 函数删除变量。依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除
|
您可以使用 `Del` 函数删除变量。依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除
|
||||||
|
|
||||||
```python
|
```python,checker_ignore
|
||||||
x = 1
|
x = 1
|
||||||
y = 2
|
y = 2
|
||||||
z = 3
|
z = 3
|
||||||
|
@ -122,7 +129,7 @@ f(2) # 名称错误: f 未定义(在第 6 行中删除)
|
||||||
|
|
||||||
注意 `Del` 只能删除用户自定义模块中定义的变量。无法删除诸如"True"之类的内置常量
|
注意 `Del` 只能删除用户自定义模块中定义的变量。无法删除诸如"True"之类的内置常量
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
Del True # 类型错误: 无法删除内置常量
|
Del True # 类型错误: 无法删除内置常量
|
||||||
Del print! # TypeError: 无法删除内置变量
|
Del print! # TypeError: 无法删除内置变量
|
||||||
```
|
```
|
||||||
|
|
|
@ -107,8 +107,8 @@ C = Class {x = Int}
|
||||||
.method self = ...
|
.method self = ...
|
||||||
```
|
```
|
||||||
|
|
||||||
您可以通過在`'''`之后立即寫入語言代碼來指定文檔的語言。然后,[Erg語言服務器](https://github.com/erg-lang/erg/tree/main/compiler/els)將以Markdown格式顯示每種語言版本的文檔(默認語言為英語)。
|
您可以通過在`'''`之后立即寫入語言代碼來指定文檔的語言。然后,[Erg語言服務器](https://github.com/erg-lang/erg/tree/main/crates/els)將以Markdown格式顯示每種語言版本的文檔(默認語言為英語)。
|
||||||
參見[這里](https://github.com/erg-lang/erg/blob/main/doc/JA/dev_guide/i18n_messages.md)獲取多語言相關文檔
|
參見[這里](https://github.com/erg-lang/erg/blob/main/doc/zh_TW/dev_guide/i18n_messages.md)獲取多語言相關文檔
|
||||||
|
|
||||||
```python
|
```python
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -78,25 +78,25 @@ assert 1e-10 == 0.0000000001
|
||||||
[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
|
[], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [元組字面量](./11_tuple.md)
|
### [元組字面量](./13_tuple.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
(), (1, 2, 3), (1, "hello", True), ...
|
(), (1, 2, 3), (1, "hello", True), ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [字典字面量](./12_dict.md)
|
### [字典字面量](./11_dict.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
|
{:}, {"one": 1}, {"one": 1, "two": 2}, {"1": 1, "2": 2}, {1: "1", 2: True, "three": [1]}, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Record 字面量](./13_record.md)
|
### [Record 字面量](./14_record.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
|
{=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Set 字面量](./14_set.md)
|
### [Set 字面量](./15_set.md)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
|
{}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ...
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=14b0c449efc9e9da3e10a09c912a960ecfaf1c9d)
|
[](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/02_name.md&commit_hash=14b0c449efc9e9da3e10a09c912a960ecfaf1c9d)
|
||||||
|
|
||||||
## 變量
|
## 變量
|
||||||
|
|
||||||
變量是一種代數; Erg 中的代數 - 如果沒有混淆,有時簡稱為變量 - 指的是命名對象并使它們可從代碼的其他地方引用的功能
|
變量是一種代數; Erg 中的代數 - 如果沒有混淆,有時簡稱為變量 - 指的是命名對象并使它們可從代碼的其他地方引用的功能
|
||||||
|
|
||||||
變量定義如下
|
變量定義如下
|
||||||
|
@ -24,9 +25,12 @@ n: Nat = 1
|
||||||
|
|
||||||
請注意,與其他語言不同,不允許多次分配
|
請注意,與其他語言不同,不允許多次分配
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
# NG
|
# NG
|
||||||
l1 = l2 = [1, 2, 3] # 語法錯誤: 不允許多重賦值
|
l1 = l2 = [1, 2, 3] # 語法錯誤: 不允許多重賦值
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
# OK
|
# OK
|
||||||
l1 = [1, 2, 3]
|
l1 = [1, 2, 3]
|
||||||
l2 = l1.clone()
|
l2 = l1.clone()
|
||||||
|
@ -67,7 +71,7 @@ assert x == 0
|
||||||
常數也是一種代數。如果標識符以大寫字母開頭,則將其視為常量。它們被稱為常量,因為一旦定義,它們就不會改變
|
常數也是一種代數。如果標識符以大寫字母開頭,則將其視為常量。它們被稱為常量,因為一旦定義,它們就不會改變
|
||||||
`N` 部分稱為常量名(或標識符)。否則,它與變量相同
|
`N` 部分稱為常量名(或標識符)。否則,它與變量相同
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
N = 0
|
N = 0
|
||||||
if True, do:
|
if True, do:
|
||||||
N = 1 # 賦值錯誤: 常量不能被遮蔽
|
N = 1 # 賦值錯誤: 常量不能被遮蔽
|
||||||
|
@ -100,6 +104,9 @@ match! x:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
X = 1 # OK
|
X = 1 # OK
|
||||||
|
```
|
||||||
|
|
||||||
|
```python,compile_fail
|
||||||
X = !1 # 類型錯誤: 無法定義 Int! 對象作為常量
|
X = !1 # 類型錯誤: 無法定義 Int! 對象作為常量
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -107,7 +114,7 @@ X = !1 # 類型錯誤: 無法定義 Int! 對象作為常量
|
||||||
|
|
||||||
您可以使用 `Del` 函數刪除變量。依賴于變量的所有其他變量(即直接引用變量值的變量)也將被刪除
|
您可以使用 `Del` 函數刪除變量。依賴于變量的所有其他變量(即直接引用變量值的變量)也將被刪除
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
x = 1
|
x = 1
|
||||||
y = 2
|
y = 2
|
||||||
z = 3
|
z = 3
|
||||||
|
@ -122,7 +129,7 @@ f(2) # 名稱錯誤: f 未定義(在第 6 行中刪除)
|
||||||
|
|
||||||
注意 `Del` 只能刪除用戶自定義模塊中定義的變量。無法刪除諸如"True"之類的內置常量
|
注意 `Del` 只能刪除用戶自定義模塊中定義的變量。無法刪除諸如"True"之類的內置常量
|
||||||
|
|
||||||
```python
|
```python,compile_fail
|
||||||
Del True # 類型錯誤: 無法刪除內置常量
|
Del True # 類型錯誤: 無法刪除內置常量
|
||||||
Del print! # TypeError: 無法刪除內置變量
|
Del print! # TypeError: 無法刪除內置變量
|
||||||
```
|
```
|
||||||
|
|
29
src/dummy.rs
29
src/dummy.rs
|
@ -19,6 +19,14 @@ use erg_compiler::Compiler;
|
||||||
pub type EvalError = CompileError;
|
pub type EvalError = CompileError;
|
||||||
pub type EvalErrors = CompileErrors;
|
pub type EvalErrors = CompileErrors;
|
||||||
|
|
||||||
|
fn find_available_port() -> u16 {
|
||||||
|
let socket = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0);
|
||||||
|
TcpListener::bind(socket)
|
||||||
|
.and_then(|listener| listener.local_addr())
|
||||||
|
.map(|sock_addr| sock_addr.port())
|
||||||
|
.expect("No free port found.")
|
||||||
|
}
|
||||||
|
|
||||||
/// Open the Python interpreter as a server and act as an Erg interpreter by mediating communication
|
/// Open the Python interpreter as a server and act as an Erg interpreter by mediating communication
|
||||||
///
|
///
|
||||||
/// Pythonインタープリタをサーバーとして開き、通信を仲介することでErgインタープリタとして振る舞う
|
/// Pythonインタープリタをサーバーとして開き、通信を仲介することでErgインタープリタとして振る舞う
|
||||||
|
@ -208,24 +216,3 @@ impl DummyVM {
|
||||||
Runnable::eval(self, src)
|
Runnable::eval(self, src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
fn find_available_port() -> u16 {
|
|
||||||
require_free_port()
|
|
||||||
}
|
|
||||||
#[cfg(not(test))]
|
|
||||||
fn find_available_port() -> u16 {
|
|
||||||
const DEFAULT_PORT: u16 = 8736;
|
|
||||||
TcpListener::bind(SocketAddrV4::new(Ipv4Addr::LOCALHOST, DEFAULT_PORT))
|
|
||||||
.is_ok()
|
|
||||||
.then_some(DEFAULT_PORT)
|
|
||||||
.unwrap_or_else(require_free_port)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn require_free_port() -> u16 {
|
|
||||||
let socket = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0);
|
|
||||||
TcpListener::bind(socket)
|
|
||||||
.and_then(|listener| listener.local_addr())
|
|
||||||
.map(|sock_addr| sock_addr.port())
|
|
||||||
.expect("No free port found.")
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,9 +5,7 @@ import sys as __sys
|
||||||
import importlib as __importlib
|
import importlib as __importlib
|
||||||
import io as __io
|
import io as __io
|
||||||
|
|
||||||
__server_socket = __socket.socket(__socket.AF_INET, __socket.SOCK_STREAM)
|
__server_socket = __socket.socket()
|
||||||
if __sys.platform == 'linux':
|
|
||||||
__server_socket.setsockopt(__socket.SOL_SOCKET, __socket.SO_REUSEADDR, 1)
|
|
||||||
# DummyVM will replace this __PORT__ with free port
|
# DummyVM will replace this __PORT__ with free port
|
||||||
__server_socket.bind(('127.0.0.1', __PORT__))
|
__server_socket.bind(('127.0.0.1', __PORT__))
|
||||||
__server_socket.listen(1)
|
__server_socket.listen(1)
|
||||||
|
|
|
@ -5,7 +5,7 @@ use erg_common::config::{DummyStdin, ErgConfig, Input};
|
||||||
use erg_common::error::MultiErrorDisplay;
|
use erg_common::error::MultiErrorDisplay;
|
||||||
use erg_common::python_util::PythonVersion;
|
use erg_common::python_util::PythonVersion;
|
||||||
use erg_common::spawn::exec_new_thread;
|
use erg_common::spawn::exec_new_thread;
|
||||||
use erg_common::style::{GREEN, RESET};
|
use erg_common::style::{colors::DEBUG_MAIN, RESET};
|
||||||
use erg_common::traits::{ExitStatus, Runnable, Stream};
|
use erg_common::traits::{ExitStatus, Runnable, Stream};
|
||||||
|
|
||||||
use erg_compiler::error::CompileErrors;
|
use erg_compiler::error::CompileErrors;
|
||||||
|
@ -107,7 +107,7 @@ fn set_cfg(mut cfg: ErgConfig) -> ErgConfig {
|
||||||
/// The test is intend to run only on 3.11 for fast execution.
|
/// The test is intend to run only on 3.11 for fast execution.
|
||||||
/// To execute on other versions, change the version and magic number.
|
/// To execute on other versions, change the version and magic number.
|
||||||
fn _exec_file(file_path: &'static str) -> Result<i32, CompileErrors> {
|
fn _exec_file(file_path: &'static str) -> Result<i32, CompileErrors> {
|
||||||
println!("{GREEN}[test] exec {file_path}{RESET}");
|
println!("{DEBUG_MAIN}[test] exec {file_path}{RESET}");
|
||||||
let cfg = ErgConfig::with_main_path(PathBuf::from(file_path));
|
let cfg = ErgConfig::with_main_path(PathBuf::from(file_path));
|
||||||
let mut vm = DummyVM::new(set_cfg(cfg));
|
let mut vm = DummyVM::new(set_cfg(cfg));
|
||||||
vm.exec()
|
vm.exec()
|
||||||
|
@ -115,7 +115,7 @@ fn _exec_file(file_path: &'static str) -> Result<i32, CompileErrors> {
|
||||||
|
|
||||||
/// WARN: You must quit REPL manually (use `:exit`, `:quit` or call something shutdowns the interpreter)
|
/// WARN: You must quit REPL manually (use `:exit`, `:quit` or call something shutdowns the interpreter)
|
||||||
pub fn _exec_repl(name: &'static str, lines: Vec<String>) -> Result<ExitStatus, CompileErrors> {
|
pub fn _exec_repl(name: &'static str, lines: Vec<String>) -> Result<ExitStatus, CompileErrors> {
|
||||||
println!("{GREEN}[test] exec dummy REPL: {lines:?}{RESET}");
|
println!("{DEBUG_MAIN}[test] exec dummy REPL: {lines:?}{RESET}");
|
||||||
let cfg = ErgConfig {
|
let cfg = ErgConfig {
|
||||||
input: Input::DummyREPL(DummyStdin::new(name.to_string(), lines)),
|
input: Input::DummyREPL(DummyStdin::new(name.to_string(), lines)),
|
||||||
quiet_repl: true,
|
quiet_repl: true,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue