From 4028bd0e1a3d6b499a7021e9c44175cd7de74d5c Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Wed, 25 Jan 2023 20:18:18 +0900 Subject: [PATCH 01/11] Add ntpath/posixpath.d.er --- .cargo/config.toml | 3 ++ crates/erg_compiler/lib/pystd/ntpath.d.er | 31 ++++++++++++++++++++ crates/erg_compiler/lib/pystd/posixpath.d.er | 31 ++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 crates/erg_compiler/lib/pystd/ntpath.d.er create mode 100644 crates/erg_compiler/lib/pystd/posixpath.d.er diff --git a/.cargo/config.toml b/.cargo/config.toml index dbf9ceed..5dd6829b 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -56,3 +56,6 @@ bd_re = "build --features debug --release" bd_ja_re = "build --features debug --features japanese --release" bd_zh_cn_re = "build --features debug --features simplified_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" diff --git a/crates/erg_compiler/lib/pystd/ntpath.d.er b/crates/erg_compiler/lib/pystd/ntpath.d.er new file mode 100644 index 00000000..0ba24079 --- /dev/null +++ b/crates/erg_compiler/lib/pystd/ntpath.d.er @@ -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 diff --git a/crates/erg_compiler/lib/pystd/posixpath.d.er b/crates/erg_compiler/lib/pystd/posixpath.d.er new file mode 100644 index 00000000..f444f7fb --- /dev/null +++ b/crates/erg_compiler/lib/pystd/posixpath.d.er @@ -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 From 4b08fd21a286916b0f3e3499aec2b9299082516d Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Wed, 25 Jan 2023 20:21:17 +0900 Subject: [PATCH 02/11] Update repl_server.py --- src/dummy.rs | 29 ++++++++--------------------- src/scripts/repl_server.py | 4 +--- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/src/dummy.rs b/src/dummy.rs index d8ff877d..78ad9ca7 100644 --- a/src/dummy.rs +++ b/src/dummy.rs @@ -19,6 +19,14 @@ use erg_compiler::Compiler; pub type EvalError = CompileError; 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 /// /// Pythonインタープリタをサーバーとして開き、通信を仲介することでErgインタープリタとして振る舞う @@ -208,24 +216,3 @@ impl DummyVM { 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.") -} diff --git a/src/scripts/repl_server.py b/src/scripts/repl_server.py index deffc55f..b0ce71f2 100644 --- a/src/scripts/repl_server.py +++ b/src/scripts/repl_server.py @@ -5,9 +5,7 @@ import sys as __sys import importlib as __importlib import io as __io -__server_socket = __socket.socket(__socket.AF_INET, __socket.SOCK_STREAM) -if __sys.platform == 'linux': - __server_socket.setsockopt(__socket.SOL_SOCKET, __socket.SO_REUSEADDR, 1) +__server_socket = __socket.socket() # DummyVM will replace this __PORT__ with free port __server_socket.bind(('127.0.0.1', __PORT__)) __server_socket.listen(1) From cbaf48c04b46fadc680fa4e05e8ad22cbdaf6c47 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Thu, 26 Jan 2023 13:45:23 +0900 Subject: [PATCH 03/11] Update docs --- CONTRIBUTING.md | 2 +- doc/CONTRIBUTING/CONTRIBUTING_JA.md | 6 ++-- doc/EN/compiler/architecture.md | 54 +++++++++++++++++++++++------ doc/EN/compiler/index.md | 2 +- doc/EN/dev_guide/build_features.md | 4 +++ doc/EN/dev_guide/doc_guideline.md | 4 ++- doc/EN/dev_guide/env.md | 4 ++- doc/JA/compiler/architecture.md | 44 ++++++++++++++++------- doc/JA/dev_guide/build_features.md | 4 +++ doc/JA/dev_guide/doc_guideline.md | 2 ++ doc/JA/dev_guide/env.md | 4 ++- doc/scripts/align_files.py | 23 ++++++++++++ doc/scripts/insert_file.py | 43 +++++++++++++++++++++++ 13 files changed, 164 insertions(+), 32 deletions(-) create mode 100644 doc/scripts/align_files.py create mode 100644 doc/scripts/insert_file.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4ad3db4c..cb00e60c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ Beginners should read the instructions [here](https://github.com/erg-lang/erg/is ## 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. diff --git a/doc/CONTRIBUTING/CONTRIBUTING_JA.md b/doc/CONTRIBUTING/CONTRIBUTING_JA.md index 1081e168..e89d8fd0 100644 --- a/doc/CONTRIBUTING/CONTRIBUTING_JA.md +++ b/doc/CONTRIBUTING/CONTRIBUTING_JA.md @@ -7,7 +7,7 @@ ## ドキュメント -Erg への貢献を考えている場合は、`doc/*/dev_guide` にあるドキュメントを読む必要があります。特に`env.md`に書かれているものを事前にインストールしてください。 +Erg への貢献を考えている場合は、`doc/*/dev_guide` にあるドキュメントを読む必要があります。特に[`env.md`](../JA/dev_guide/env.md)に書かれているものを事前にインストールしてください。 Erg の内部構造に興味がある場合は、`doc/*/compiler` が役に立つかもしれません。 @@ -23,11 +23,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)でお気軽にお問い合わせください。 ## 開発・実装に関して diff --git a/doc/EN/compiler/architecture.md b/doc/EN/compiler/architecture.md index 217a51bb..a0cb77e8 100644 --- a/doc/EN/compiler/architecture.md +++ b/doc/EN/compiler/architecture.md @@ -1,6 +1,8 @@ # 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()`) * `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. * `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`. * `AST` is the wrapper type of `Vec`. It is for "Abstract Syntax Tree". ### 2.1 Desugaring `AST` +src: [erg_parser/desugar.rs](../../../crates/erg_parser/desugar.rs) + * expand nested vars (`Desugarer::desugar_nest_vars_pattern`) * desugar multiple pattern definition syntax (`Desugarer::desugar_multiple_pattern_def`) ### 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". * `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. * 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 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. - There will be several more layers of intermediate processes for this conversion process. +* Load all modules, resolve dependencies, and combine into a single HIR + +## 8. Generate Bytecode (`CodeObj`) from `HIR` + +src: [erg_compiler/codegen.rs](../../../crates/erg_compiler/codegen.rs) diff --git a/doc/EN/compiler/index.md b/doc/EN/compiler/index.md index 6c364ff0..d162a1e2 100644 --- a/doc/EN/compiler/index.md +++ b/doc/EN/compiler/index.md @@ -26,4 +26,4 @@ ## [transpile](./transpile.md) -## [type_var_normalization.](type_var_normalization.md) \ No newline at end of file +## [type_var_normalization.](type_var_normalization.md) diff --git a/doc/EN/dev_guide/build_features.md b/doc/EN/dev_guide/build_features.md index d0928a36..2b610c48 100644 --- a/doc/EN/dev_guide/build_features.md +++ b/doc/EN/dev_guide/build_features.md @@ -36,3 +36,7 @@ Increase the thread stack size. Used for Windows execution and test execution. `--language-server` option becomes available. `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). diff --git a/doc/EN/dev_guide/doc_guideline.md b/doc/EN/dev_guide/doc_guideline.md index 26f717a9..d4b09212 100644 --- a/doc/EN/dev_guide/doc_guideline.md +++ b/doc/EN/dev_guide/doc_guideline.md @@ -7,7 +7,9 @@ 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. * 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[1](#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). +* 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. --- -1 See this for how to write footnotes. [↩](#f1) \ No newline at end of file +1 See this for how to write footnotes. [↩](#f1) diff --git a/doc/EN/dev_guide/env.md b/doc/EN/dev_guide/env.md index cf58fa3b..595b5e5d 100644 --- a/doc/EN/dev_guide/env.md +++ b/doc/EN/dev_guide/env.md @@ -12,7 +12,9 @@ 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. -* 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 diff --git a/doc/JA/compiler/architecture.md b/doc/JA/compiler/architecture.md index 6b7b7cf9..90d5c39d 100644 --- a/doc/JA/compiler/architecture.md +++ b/doc/JA/compiler/architecture.md @@ -2,7 +2,9 @@ [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/compiler/architecture.md%26commit_hash%3Da711efa99b325ba1012f6897e7b0e2bdb947d8a1)](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()` によって生成できる) * [`Lexer`](./phases/01_lex.md) は `Lexer::new` または `Lexer::from_str` から構築される。`Lexer::new` はファイルまたはコマンド オプションからコードを読み取る。 @@ -11,29 +13,43 @@ * `Lexer` を単体で使用する場合は、代わりに`LexerRunner` を使用します。`Lexer` は単なるイテレータであり、`Runnable` トレイトを実装していない。 * `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` を返す。 * `AST`は`Vec`のラッパー型で、「抽象構文木」を表す。 ### 2.1 `AST`の脱糖 +src: [erg_parser/desugar.rs](../../../crates/erg_parser/desugar.rs) + * [`Desugarer`](./phases/03_desugar.md) * パターンマッチを単一の変数代入列へ変換 (`Desugarer::desugar_nest_vars_pattern`) * 複数パターン定義構文をmatchへ変換 (`Desugarer::desugar_multiple_pattern_def`) +### 2.2 `AST`の並び替え・結合 + +src: [erg_compiler/reorder.rs](../../../crates\erg_compiler\reorder.rs) + +* クラスメソッドをクラス定義に結合する + * メソッド定義は定義ファイル外でも可能となっている + * 現在の実装は不完全、同一ファイル内のみ + ## 3. `AST` -> `HIR` -(主要な)ソースコード: [erg_compiler/lower.rs](../../../compiler/erg_compiler/lower.rs) +(主要な)ソースコード: [erg_compiler/lower.rs](../../../crates/erg_compiler/lower.rs) ## 3.1 名前解決 +現在の実装では型チェック中に行われる + * 型推論の前に全てのAST(importされたモジュール含む)を走査し、名前解決を行う * 定数の循環検査や並び替えなどが行われるほか、型推論のためのContextが作成される(ただし、このContextに登録された変数の情報ははまだ殆どが未確定) ### 3.2 型チェックと推論 -ソースコード: [erg_compiler/lower.rs](../../../compiler/erg_compiler/lower.rs) +ソースコード: [erg_compiler/lower.rs](../../../crates/erg_compiler/lower.rs) * `HIR` は、すべての変数の型情報を持っており、「高レベルの中間表現」を表す。 * `ASTLowerer` は Parser や Lexer と同じように構築できる。 @@ -43,23 +59,25 @@ ## 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の文法と整合しない部分を変換する -* クラスのメンバ変数を関数に変換 + * クラスのメンバ変数を関数に変換 -## 6. リンク +## 7. リンク + +ソースコード: [erg_compiler/link.rs](../../../crates/erg_compiler/link.rs) * 全てのモジュールを読み込み、依存関係を解決し、単一の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) diff --git a/doc/JA/dev_guide/build_features.md b/doc/JA/dev_guide/build_features.md index fbd1c969..4cfb462b 100644 --- a/doc/JA/dev_guide/build_features.md +++ b/doc/JA/dev_guide/build_features.md @@ -38,3 +38,7 @@ Erg 内部オプション、ヘルプ (ヘルプ、著作権、ライセンス `--language-server`オプションが利用可能になる。 `erg --language-server`でLanguage Serverが起動する。 + +## py_compatible + +Python互換モードを有効にする。APIや文法の一部がPythonと互換になる。[pylyzer](https://github.com/mtshiba/pylyzer)のために使用される。 diff --git a/doc/JA/dev_guide/doc_guideline.md b/doc/JA/dev_guide/doc_guideline.md index 2e09a6df..03c6d032 100644 --- a/doc/JA/dev_guide/doc_guideline.md +++ b/doc/JA/dev_guide/doc_guideline.md @@ -9,6 +9,8 @@ * ドキュメント内で初出の用語は、必ず定義や意味、またはリンクを併記する。 * ただし書きとしての()は、補助的ではあるものの本文の理解に必要な文の場合のみ使用し、本文の理解に必須でない文は脚注を使用する[1](#1)。 * ドキュメントの内容が古くなっていた場合は、[この方法](https://github.com/erg-lang/erg/issues/48#issuecomment-1218247362)に従って更新する。 +* syntax以下のファイルは、ドキュメントに含めないものを除きファイル名の頭に連番を付ける。 + * 挿入や入れ替えを自動で行うスクリプトがdoc/script内に存在する。 --- diff --git a/doc/JA/dev_guide/env.md b/doc/JA/dev_guide/env.md index 51e4f748..282d81a3 100644 --- a/doc/JA/dev_guide/env.md +++ b/doc/JA/dev_guide/env.md @@ -14,7 +14,9 @@ pre-commitを使ってclippyのチェックやテストを自動で行わせています。 バグがなくても最初の実行でチェックが失敗する場合があります。その場合はもう一度コミットを試みてください。 -* Python3インタープリタ +* Python3インタープリタ (3.7~3.11) + +様々なバージョンでErgの挙動を検査したい場合は [pyenv](https://github.com/pyenv/pyenv) 等の導入をお勧めします。 ## 推奨 diff --git a/doc/scripts/align_files.py b/doc/scripts/align_files.py new file mode 100644 index 00000000..6192accb --- /dev/null +++ b/doc/scripts/align_files.py @@ -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]) diff --git a/doc/scripts/insert_file.py b/doc/scripts/insert_file.py new file mode 100644 index 00000000..64dfdc71 --- /dev/null +++ b/doc/scripts/insert_file.py @@ -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 From bdfe59ac7ca50bd8597f0a4efc82080fbbe462d7 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Thu, 26 Jan 2023 13:51:57 +0900 Subject: [PATCH 04/11] Rename Array!(T, N).mf -> Array!(T,N).md --- doc/EN/API/types/classes/{Array!(T, N).md => Array!(T,N).md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/EN/API/types/classes/{Array!(T, N).md => Array!(T,N).md} (100%) diff --git a/doc/EN/API/types/classes/Array!(T, N).md b/doc/EN/API/types/classes/Array!(T,N).md similarity index 100% rename from doc/EN/API/types/classes/Array!(T, N).md rename to doc/EN/API/types/classes/Array!(T,N).md From eaded7ac5d05d43259d0a51388de61ef940fb99f Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Thu, 26 Jan 2023 14:12:43 +0900 Subject: [PATCH 05/11] Add PyCodeGenerator::deopt_instr --- .gitignore | 1 + README.md | 4 ++-- README_JA.md | 2 +- README_zh-CN.md | 2 +- README_zh-TW.md | 4 ++-- crates/erg_compiler/codegen.rs | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 40 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 12b1fcd2..4ca76d8b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ /*/.DS_Store /.idea/ /timeit.dat +**/__pycache__/ # Nix .direnv diff --git a/README.md b/README.md index 4b696c8d..fffdb77e 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ even for and while expressions are just one of the subroutines, so this is possible. ```python - loop! block = while! do(True), block + loop! block! = while! do! True, block! # equals to `while! do(True), do! print! "hello"` loop! do!: @@ -202,7 +202,7 @@ nix build By enabling the `--features` flag, you can customize the installation and build. - You can change the language of the error message by using `--features {language}` -```sh +```sh --features japanese --features simplified_chinese --features traditional_chinese diff --git a/README_JA.md b/README_JA.md index 02673cb4..a020d567 100644 --- a/README_JA.md +++ b/README_JA.md @@ -77,7 +77,7 @@ Ergでは特別扱いされる構文要素がとても少なく、例えば予約語が一つもありません。以下のような芸当も可能です。 ```python - loop! block = while! do(True), block + loop! block! = while! do! True, block! # `while! do(True), do! print! "hello"`と同じです loop! do!: diff --git a/README_zh-CN.md b/README_zh-CN.md index 7a052a62..db927dd4 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -77,7 +77,7 @@ 在Erg中,很少有东西被认为是特殊的,没有关键字,因此for和while表达式也只是子程序之一 ```python - loop! block = while! do(True), block + loop! block! = while! do! True, block! # equals to `while! do(True), do! print! "hello"` loop! do!: diff --git a/README_zh-TW.md b/README_zh-TW.md index aa03f287..e0765677 100644 --- a/README_zh-TW.md +++ b/README_zh-TW.md @@ -77,9 +77,9 @@ 在Erg中,很少有東西被認為是特殊的,沒有關鍵字,因此for和while表達式也只是子程序之一 ```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!: print! "hello" ``` diff --git a/crates/erg_compiler/codegen.rs b/crates/erg_compiler/codegen.rs index 13249bf3..606ad084 100644 --- a/crates/erg_compiler/codegen.rs +++ b/crates/erg_compiler/codegen.rs @@ -46,6 +46,18 @@ use crate::ty::{HasType, Type, TypeCode, TypePair}; use erg_common::fresh::fresh_varname; 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 attr -> variable fn debind(ident: &Identifier) -> Option { @@ -1604,6 +1616,21 @@ impl PyCodeGenerator { 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) { log!(info "entered {}", fn_name!()); let init_stack_len = self.stack_len(); @@ -1670,6 +1697,9 @@ impl PyCodeGenerator { fn emit_for_instr(&mut self, mut args: 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 iterable = args.remove(0); self.emit_expr(iterable); @@ -1716,6 +1746,9 @@ impl PyCodeGenerator { fn emit_while_instr(&mut self, mut args: 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(); // e.g. is_foo!: () => Bool, do!(is_bar) let cond_block = args.remove(0); From 73248f21dfbffb109f9e94e97ebb9227012a5808 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Thu, 26 Jan 2023 14:23:07 +0900 Subject: [PATCH 06/11] Update codegen.rs --- crates/erg_compiler/codegen.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/crates/erg_compiler/codegen.rs b/crates/erg_compiler/codegen.rs index 606ad084..de66a6a9 100644 --- a/crates/erg_compiler/codegen.rs +++ b/crates/erg_compiler/codegen.rs @@ -2041,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!()); - 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 lambda = enum_unwrap!(args.remove(0), Expr::Lambda); let params = self.gen_param_names(&lambda.params); @@ -2087,9 +2089,11 @@ impl PyCodeGenerator { 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!()); - 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 lambda = enum_unwrap!(args.remove(0), Expr::Lambda); let params = self.gen_param_names(&lambda.params); @@ -2138,9 +2142,11 @@ impl PyCodeGenerator { 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!()); - 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 lambda = enum_unwrap!(args.remove(0), Expr::Lambda); let params = self.gen_param_names(&lambda.params); From db12bb1e2db3683ea48e5a33d3e63baf4ec8fef8 Mon Sep 17 00:00:00 2001 From: GreasrySlug <9619abgoni@gmai.com> Date: Thu, 26 Jan 2023 14:45:15 +0900 Subject: [PATCH 07/11] update: colors mod and feature --- crates/erg_common/style.rs | 77 ++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 45 deletions(-) diff --git a/crates/erg_common/style.rs b/crates/erg_common/style.rs index 8c5c6830..07b824e0 100644 --- a/crates/erg_common/style.rs +++ b/crates/erg_common/style.rs @@ -1,29 +1,44 @@ +use self::colors::*; use std::borrow::Cow; pub const ATTR_RESET: &str = "\x1b[0m"; pub const BOLD: &str = "\x1b[1m"; pub const UNDERLINE: &str = "\x1b[4m"; pub const REVERSED: &str = "\x1b[7m"; +pub const RESET: &str = "\x1b[m"; // Escape sequences change the color of the terminal -pub const RESET: &str = "\x1b[m"; -pub const BLACK: &str = "\x1b[30m"; -pub const BLUE: &str = "\x1b[94m"; -pub const CYAN: &str = "\x1b[96m"; -pub const GRAY: &str = "\x1b[37m"; -pub const GREEN: &str = "\x1b[92m"; -pub const MAGENTA: &str = "\x1b[95m"; -pub const RED: &str = "\x1b[91m"; -pub const WHITE: &str = "\x1b[97m"; -pub const YELLOW: &str = "\x1b[93m"; +#[cfg(not(feature = "pretty"))] +pub mod colors { + pub const BLACK: &str = "\x1b[30m"; + pub const BLUE: &str = "\x1b[94m"; + pub const CYAN: &str = "\x1b[96m"; + pub const GRAY: &str = "\x1b[37m"; + pub const GREEN: &str = "\x1b[92m"; + pub const MAGENTA: &str = "\x1b[95m"; + pub const RED: &str = "\x1b[91m"; + pub const WHITE: &str = "\x1b[97m"; + 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` -pub const CUSTOM_RED: &str = "\x1b[38;2;255;76;76m"; -pub const CUSTOM_BLUE: &str = "\x1b[38;2;76;76;255m"; -pub const CUSTOM_GRAY: &str = "\x1b[38;2;231;231;235m"; -pub const CUSTOM_CYAN: &str = "\x1b[38;2;76;255;255m"; -pub const CUSTOM_MAGENTA: &str = "\x1b[38;2;165;76;255m"; -pub const CUSTOM_GREEN: &str = "\x1b[38;2;76;255;76m"; -pub const CUSTOM_YELLOW: &str = "\x1b[38;2;255;255;76m"; +#[cfg(feature = "pretty")] +pub mod colors { + pub const BLACK: &str = "\x1b[30m"; + pub const BLUE: &str = "\x1b[38;2;76;76;255m"; + pub const CYAN: &str = "\x1b[38;2;76;255;255m"; + pub const GRAY: &str = "\x1b[38;2;231;231;235m"; + 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 { s.replace(RED, "") @@ -53,13 +68,6 @@ pub enum Color { Red, White, Yellow, - CustomRed, - CustomBlue, - CustomGray, - CustomCyan, - CustomMagenta, - CustomGreen, - CustomYellow, } impl Color { @@ -75,13 +83,6 @@ impl Color { Color::Red => RED, Color::Yellow => YELLOW, 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, } -#[cfg(not(feature = "pretty"))] pub const COLORS: ThemeColors = ThemeColors { error: Color::Red, warning: Color::Yellow, @@ -125,16 +125,6 @@ pub const COLORS: ThemeColors = ThemeColors { 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)] pub struct Characters { hat: char, // error @@ -524,9 +514,6 @@ mod tests { println!("{BLUE}Hello{RESET}, {GREEN}World{RESET}"); println!("{MAGENTA}Hello{RESET}, {BLACK}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] From 97cde41592e25b02472adde541fd8cc1a8d0e00a Mon Sep 17 00:00:00 2001 From: GreasrySlug <9619abgoni@gmai.com> Date: Thu, 26 Jan 2023 14:46:44 +0900 Subject: [PATCH 08/11] update: use debug colors --- crates/erg_common/macros.rs | 22 +++++++++++----------- crates/erg_compiler/context/compare.rs | 3 ++- crates/erg_compiler/ownercheck.rs | 3 ++- crates/erg_parser/parse.rs | 6 +++--- tests/common.rs | 6 +++--- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/crates/erg_common/macros.rs b/crates/erg_common/macros.rs index 3001f126..1e6a7d07 100644 --- a/crates/erg_common/macros.rs +++ b/crates/erg_common/macros.rs @@ -356,11 +356,11 @@ macro_rules! debug_enum_assert { macro_rules! debug_info { ($output:ident) => {{ #[allow(unused_imports)] - use $crate::style::{CYAN, RESET}; + use $crate::style::{colors::DEBUG, RESET}; write!( $output, "[{}DEBUG{}] {}:{:04}: ", - CYAN, + DEBUG, RESET, file!(), line!() @@ -369,8 +369,8 @@ macro_rules! debug_info { }}; () => {{ #[allow(unused_imports)] - use $crate::style::{CYAN, RESET}; - print!("[{}DEBUG{}] {}:{:04}: ", CYAN, RESET, file!(), line!()); + use $crate::style::{colors::DEBUG, RESET}; + print!("[{}DEBUG{}] {}:{:04}: ", DEBUG, RESET, file!(), line!()); }}; } @@ -386,25 +386,25 @@ macro_rules! debug_info { #[macro_export] macro_rules! log { (info $($arg: tt)*) => {{ - $crate::log!(c GREEN, $($arg)*); + $crate::log!(c DEBUG_MAIN, $($arg)*); }}; (err $($arg: tt)*) => {{ - $crate::log!(c RED, $($arg)*); + $crate::log!(c DEBUG_ERROR, $($arg)*); }}; (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)*) => {{ - $crate::log!(f+c $output, RED, $($arg)*); + $crate::log!(f+c $output, DEBUG_ERROR, $($arg)*); }}; (f $output: ident, $($arg: tt)*) => {{ if cfg!(feature = "debug") { #[allow(unused_imports)] - use $crate::color::{RESET, GREEN, RED}; + use $crate::color::{RESET, colors::DEBUG_MAIN, colors::DEBUG_ERROR}; $crate::debug_info!($output); write!($output, $($arg)*).unwrap(); write!($output, "{}", RESET).unwrap(); // color color anyway @@ -415,7 +415,7 @@ macro_rules! log { (c $color:ident, $($arg: tt)*) => {{ if cfg!(feature = "debug") { #[allow(unused_imports)] - use $crate::style::{RESET, GREEN, RED}; + use $crate::style::{RESET, colors::DEBUG_MAIN, colors::DEBUG_ERROR}; $crate::debug_info!(); print!("{}", $color); println!($($arg)*); @@ -426,7 +426,7 @@ macro_rules! log { (f+c $output:ident, $color:ident, $($arg: tt)*) => {{ if cfg!(feature = "debug") { #[allow(unused_imports)] - use $crate::style::{RESET, GREEN}; + use $crate::style::{RESET, colors::DEBUG_MAIN}; $crate::debug_info!($output); write!($output, "{}{}{}", $color, $($arg)*, RESET).unwrap(); write!($output, $($arg)*).unwrap(); diff --git a/crates/erg_compiler/context/compare.rs b/crates/erg_compiler/context/compare.rs index 75d83168..d9c01809 100644 --- a/crates/erg_compiler/context/compare.rs +++ b/crates/erg_compiler/context/compare.rs @@ -2,6 +2,7 @@ use std::option::Option; // conflicting to Type::Option use erg_common::error::{Location, MultiErrorDisplay}; +use erg_common::style::colors::DEBUG_ERROR; use crate::ty::constructors::{and, not, or, poly}; use crate::ty::free::{Constraint, FreeKind}; @@ -131,7 +132,7 @@ impl Context { || self.nominal_supertype_of(lhs, rhs) } }; - log!("answer: {lhs} {RED}:>{RESET} {rhs} == {res}"); + log!("answer: {lhs} {DEBUG_ERROR}:>{RESET} {rhs} == {res}"); res } diff --git a/crates/erg_compiler/ownercheck.rs b/crates/erg_compiler/ownercheck.rs index 87feeef4..554ba263 100644 --- a/crates/erg_compiler/ownercheck.rs +++ b/crates/erg_compiler/ownercheck.rs @@ -4,6 +4,7 @@ use erg_common::config::ErgConfig; use erg_common::dict::Dict; use erg_common::error::Location; use erg_common::set::Set; +use erg_common::style::colors::DEBUG_MAIN; use erg_common::traits::{Locational, Stream}; use erg_common::vis::Visibility; use erg_common::Str; @@ -78,7 +79,7 @@ impl OwnershipChecker { self.check_expr(chunk, Ownership::Owned, true); } 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() ); if self.errs.is_empty() { diff --git a/crates/erg_parser/parse.rs b/crates/erg_parser/parse.rs index 0cbf9e24..091972b2 100644 --- a/crates/erg_parser/parse.rs +++ b/crates/erg_parser/parse.rs @@ -33,7 +33,7 @@ macro_rules! debug_call_info { ($self: ident) => { $self.level += 1; log!( - c GREEN, + c DEBUG_MAIN, "\n{} ({}) entered {}, cur: {}", "・".repeat(($self.level as f32 / 4.0).floor() as usize), $self.level, @@ -48,7 +48,7 @@ macro_rules! debug_exit_info { ($self: ident) => { $self.level -= 1; log!( - c GREEN, + c DEBUG_MAIN, "\n{} ({}) exit {}, cur: {}", "・".repeat(($self.level as f32 / 4.0).floor() as usize), $self.level, @@ -228,7 +228,7 @@ impl Parser { pub(crate) fn stack_dec(&mut self, fn_name: &str) { self.level -= 1; log!( - c GREEN, + c DEBUG_MAIN, "\n{} ({}) exit {}, cur: {}", "・".repeat((self.level as f32 / 4.0).floor() as usize), self.level, diff --git a/tests/common.rs b/tests/common.rs index b2e78c58..8c33b08f 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -5,7 +5,7 @@ use erg_common::config::{DummyStdin, ErgConfig, Input}; use erg_common::error::MultiErrorDisplay; use erg_common::python_util::PythonVersion; 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_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. /// To execute on other versions, change the version and magic number. fn _exec_file(file_path: &'static str) -> Result { - 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 mut vm = DummyVM::new(set_cfg(cfg)); vm.exec() @@ -115,7 +115,7 @@ fn _exec_file(file_path: &'static str) -> Result { /// WARN: You must quit REPL manually (use `:exit`, `:quit` or call something shutdowns the interpreter) pub fn _exec_repl(name: &'static str, lines: Vec) -> Result { - println!("{GREEN}[test] exec dummy REPL: {lines:?}{RESET}"); + println!("{DEBUG_MAIN}[test] exec dummy REPL: {lines:?}{RESET}"); let cfg = ErgConfig { input: Input::DummyREPL(DummyStdin::new(name.to_string(), lines)), quiet_repl: true, From 748cd2c99d156ab552811a2a91a6e2bfd083d5c5 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Thu, 26 Jan 2023 22:37:57 +0900 Subject: [PATCH 09/11] Update funcs.rs --- crates/erg_compiler/context/initialize/funcs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/erg_compiler/context/initialize/funcs.rs b/crates/erg_compiler/context/initialize/funcs.rs index a1bbc5cb..e47fce00 100644 --- a/crates/erg_compiler/context/initialize/funcs.rs +++ b/crates/erg_compiler/context/initialize/funcs.rs @@ -113,7 +113,7 @@ impl Context { None, 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_len = nd_func( vec![kw(KW_S, poly(SEQ, vec![TyParam::erased(Type)]))], From 04f40b86915c54a6048792013313611984f4d18e Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Fri, 27 Jan 2023 00:31:01 +0900 Subject: [PATCH 10/11] Fix broken links --- doc/EN/syntax/00_basic.md | 4 +- doc/EN/syntax/01_literal.md | 8 +- doc/EN/syntax/07_side_effect.md | 2 +- doc/EN/syntax/14_record.md | 4 +- doc/EN/syntax/indexes.md | 136 ++++++++++++++++---------------- doc/JA/syntax/00_basic.md | 2 +- doc/JA/syntax/01_literal.md | 8 +- doc/zh_CN/syntax/00_basic.md | 2 +- doc/zh_CN/syntax/01_literal.md | 8 +- doc/zh_TW/syntax/00_basic.md | 4 +- doc/zh_TW/syntax/01_literal.md | 8 +- doc/zh_TW/syntax/02_name.md | 1 + 12 files changed, 94 insertions(+), 93 deletions(-) diff --git a/doc/EN/syntax/00_basic.md b/doc/EN/syntax/00_basic.md index 7ee32596..a2289c87 100644 --- a/doc/EN/syntax/00_basic.md +++ b/doc/EN/syntax/00_basic.md @@ -112,8 +112,8 @@ C = Class {x = Int} .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). -See [here](https://github.com/erg-lang/erg/blob/main/doc/JA/dev_guide/i18n_messages.md) for registered language codes. +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/EN/dev_guide/i18n_messages.md) for registered language codes. ```python ''' diff --git a/doc/EN/syntax/01_literal.md b/doc/EN/syntax/01_literal.md index 84fb151c..002739a2 100644 --- a/doc/EN/syntax/01_literal.md +++ b/doc/EN/syntax/01_literal.md @@ -76,25 +76,25 @@ Each of these literals has its own documentation describing them separately, so [], [1], [1, 2, 3], ["1", "2",], ... ``` -### [Tuple Literal](./11_tuple.md) +### [Tuple Literal](./13_tuple.md) ```python (), (1, 2, 3), (1, "hello", True), ... ``` -### [Dict Literal](./12_dict.md) +### [Dict Literal](./11_dict.md) ```python {:}, {"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 {=}, {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 {}, {1}, {1, 2, 3}, {"1", "2", "1"}, ... diff --git a/doc/EN/syntax/07_side_effect.md b/doc/EN/syntax/07_side_effect.md index 72c214b2..ed3d77c0 100644 --- a/doc/EN/syntax/07_side_effect.md +++ b/doc/EN/syntax/07_side_effect.md @@ -28,7 +28,7 @@ C!. 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 n = 1 diff --git a/doc/EN/syntax/14_record.md b/doc/EN/syntax/14_record.md index 7d4dc4dd..f88b0479 100644 --- a/doc/EN/syntax/14_record.md +++ b/doc/EN/syntax/14_record.md @@ -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. 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_. -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 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. -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 # record diff --git a/doc/EN/syntax/indexes.md b/doc/EN/syntax/indexes.md index ae6c98a0..70e88b92 100644 --- a/doc/EN/syntax/indexes.md +++ b/doc/EN/syntax/indexes.md @@ -8,15 +8,15 @@ Also, see [here](../terms.md) for terminology. * ! → [side effect](./07_side_effect.md) * !-type → [mutable type](./type/18_mut.md) -* ? → [error handling](./30_error_handling.md) -* # → [Str](./00_basic.md/#comment) +* ? → [error handling](./31_error_handling.md) +* # → [Str](./00_basic.md/#comments) * $ → [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) -* () → [Tuple](./11_tuple.md) +* () → [Tuple](./13_tuple.md) * * * * → [*-less multiplication](./01_literal.md/#less-multiplication) * + (prefix) → [operator](./06_operator.md) @@ -28,19 +28,19 @@ Also, see [here](../terms.md) for terminology. * −_ → − (prefix) * − (infix) → [operator](./06_operator.md) * − (infix) → [Trait](./type/03_trait.md) - * −> → [anonymous function](./21_lambda.md) -* . → [Visibility](./19_visibility.md) + * −> → [anonymous function](./22_lambda.md) +* . → [Visibility](./20_visibility.md) * .. → [closed 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) * / * : * : → [Colon application style](./04_function.md) - * : → [Type ascription](./03_declaration.md.md) + * : → [Type ascription](./03_declaration.md) * : → [Keyword arguments](./04_function.md) - * :: → [private variable modifier](./19_visibility.md) + * :: → [private variable modifier](./20_visibility.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) * <..< → [open range operator](./01_literal.md/#range-object) -* = → [Variable](./19_visibility.md) +* = → [Variable](./20_visibility.md) * == * => → [anonymous procedure operator](./08_procedure.md) * > * >> * >= -* @ → [decorator](./29_decorator.md) +* @ → [decorator](./30_decorator.md) * [] → [Array](./10_array.md) * \ → [Escaping](./00_basic.md) * ^ @@ -63,11 +63,11 @@ Also, see [here](../terms.md) for terminology. * _ → [Type erasure](./type/advanced/erasure.md) * _+_ → + (infix) * _-_ → − (infix) -* [`` (back quote)](./22_subroutine.md#operator) +* [`` (back quote)](./23_subroutine.md#operator) * {} * [{} type](./type/01_type_system.md) * {=} → [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/) * ~ @@ -83,11 +83,11 @@ Also, see [here](../terms.md) for terminology. * [algebraic type](./type/13_algebraic.md) * [And] * [and] -* [anonymous function](./21_lambda.md) +* [anonymous function](./22_lambda.md) * anonymous type → [Type system](./type/01_type_system.md) * [Array](./10_array.md) -* [assert] -* [Attach](./29_decorator.md#attach) +* assert +* [Attach](./30_decorator.md#attach) * [attribute](type/09_attributive.md) * [Attribute definitions](./type/02_basic.md#attribute-definitions) * [Attribute type](./type/09_attributive.md) @@ -96,7 +96,7 @@ Also, see [here](../terms.md) for terminology. * [Bool, Boolean](./01_literal.md#boolean-object) * [Boolean object](./01_literal.md#boolean-object) -* [borrowing](./18_ownership.md#borrow) +* [borrowing](./19_ownership.md#borrow) ### C @@ -104,43 +104,43 @@ Also, see [here](../terms.md) for terminology. * [Comments](./00_basic.md#comments) * [Complex object](./01_literal.md#complex-object) * [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 relationship](./type/04_class.md#class-relationships) * [Class upcasting](./type/16_subtyping.md#class-upcasting) * [Colon application style](./04_function.md#colon-application-style) -* [Closure](./23_closure.md) +* [Closure](./24_closure.md) * [Compound literals](./01_literal.md#compound-literals) * [Complement](./type/13_algebraic.md#complement) -* [Comprehension](./27_comprehension.md) -* [constant](./17_mutability.md#constant) +* [Comprehension](./28_comprehension.md) +* [constant](./18_mutability.md#constant) * [Constants](./02_name.md#constants) -* [Context](./30_error_handling.md#context) +* [Context](./31_error_handling.md#context) ### D * [Data type](./type/01_type_system.md#data-type) * [Declaration](./03_declaration.md) -* [decorator](./29_decorator.md) +* [decorator](./30_decorator.md) * [Default parameters](./04_function.md#default-parameters) * [Del](./02_name.md#delete-an-variable) * [Dependent type](./type/14_dependent.md) * Deprecated -* [Dict](./12_dict.md) +* [Dict](./11_dict.md) * [Diff](./type/13_algebraic.md#diff) * distinct * [Downcasting](./type/17_type_casting.md#downcasting) ### E -* [Empty record](./13_record.md#empty-record) +* [Empty record](./14_record.md#empty-record) * [Enum class](./type/04_class.md#enum-class) * [Enum type](./type/11_enum.md) * [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) * [Exponential literal](./01_literal.md#exponential-literal) -* [Extract assignment](./28_spread_syntax.md#extract-assignment) +* [Extract assignment](./29_spread_syntax.md#extract-assignment) ### F @@ -148,14 +148,14 @@ Also, see [here](../terms.md) for terminology. * [Float object](./01_literal.md#float-object) * [for](./05_builtin_funcs.md#for) * [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 definition with multiple patterns](./04_function.md#function-definition-with-multiple-patterns) ### G * [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) ### H @@ -166,19 +166,19 @@ Also, see [here](../terms.md) for terminology. * [id](./09_builtin_procs.md#id) * [if](./05_builtin_funcs.md#if) -* [import](./33_package_system.md) -* [impl](./29_decorator.md#impl) -* [in] +* [import](./34_package_system.md) +* [impl](./30_decorator.md#impl) +* in * [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) -* [inheritable](./29_decorator.md#inheritable) +* [inheritable](./30_decorator.md#inheritable) * [inheritance](./type/05_inheritance.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) * [Intersection](./type/13_algebraic.md#intersection) -* [Iterator](./16_iterator.md) +* [Iterator](./17_iterator.md) ### J @@ -189,59 +189,59 @@ Also, see [here](../terms.md) for terminology. ### L -* lambda → [anonymous function](./21_lambda.md) +* lambda → [anonymous function](./22_lambda.md) * let-polymorphism → [rank 1 polymorphism] -* [Literal Identifiers](./20_naming_rule.md#literal-identifiers) +* [Literal Identifiers](./21_naming_rule.md#literal-identifiers) ### M -* [match] +* match * [Marker trait](./type/advanced/marker_trait.md) * [Method](./07_side_effect.md#methods) -* Modifier → [decorator](./29_decorator.md) -* [module](./24_module.md) +* Modifier → [decorator](./30_decorator.md) +* [module](./25_module.md) * [Multiple inheritance](type/05_inheritance.md#multiple-inheritance) * [Multi-layer (multi-level) Inheritance](type/05_inheritance.md#multi-layer-multi-level-inheritance) * [Mutable type](./type/18_mut.md) * [Mutable structure type](./type/advanced/mut_struct.md) -* [Mutability](./17_mutability.md) +* [Mutability](./18_mutability.md) ### N * [Nat](./01_literal.md#int-literal) -* [Never] +* Never * [New type](./type/advanced/newtype.md) -* [Heterogeneous Dict](./12_dict.md#heterogeneous-dict) +* [Heterogeneous Dict](./11_dict.md#heterogeneous-dict) * None → [None Object] -* [None Object] +* None Object * Nominal Subtyping → [Class](./type/04_class.md) -* [Not] -* [not] +* Not +* not ### O -* [Object](./25_object_system.md) +* [Object](./26_object_system.md) * [Option] * [Or] * [or] * [Ord] -* [ownership system](./18_ownership.md) +* [ownership system](./19_ownership.md) * [Overloading](./type/advanced/overloading.md) * [Overriding](./type/05_inheritance.md#overriding) * [Override in trait](./type/03_trait.md#override-in-trait) ### P -* [Panic](./30_error_handling.md#panic) +* [Panic](./31_error_handling.md#panic) * [Patch](./type/07_patch.md) -* [Pattern match](./26_pattern_matching.md) +* [Pattern match](./27_pattern_matching.md) * [Phantom class](./type/advanced/phantom.md) -* [pipeline operator](./31_pipeline.md) +* [pipeline operator](./32_pipeline.md) * [Predicate](./type/19_bound.md#predicate) -* [print!] +* print! * [Procedures](./08_procedure.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 @@ -251,15 +251,15 @@ Also, see [here](../terms.md) for terminology. ### R * [Range Object](./01_literal.md#range-object) -* [ref] -* [ref!] -* [Record](./13_record.md) +* ref +* ref! +* [Record](./14_record.md) * [Recursive functions](./04_function.md#recursive-functions) * [Refinement pattern](./type/12_refinement.md#refinement-pattern) * [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) -* Result → [error handling](./30_error_handling.md) +* Result → [error handling](./31_error_handling.md) ### S @@ -269,9 +269,9 @@ Also, see [here](../terms.md) for terminology. * [Shared reference](./type/advanced/shared.md) * [side-effect](./07_side_effect.md) * [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) -* [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) * [Structural patch](./type/07_patch.md#structural-patch) * [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) * [Subtype specification](./type/02_basic.md#subtype-specification) * [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 -* [Test](./29_decorator.md#test) +* [Test](./30_decorator.md#test) * [Traits](./type/03_trait.md) * [Trait inclusion](./type/03_trait.md#trait-inclusion) * True → [Boolean object](./01_literal.md#boolean-object) * [True algebraic type](./type/13_algebraic.md#true-algebraic-type) -* [Type] -* [type](./15_type.md) +* Type +* [type](./16_type.md) * [Type arguments in method definitions](./type/15_quantified.md#type-arguments-in-method-definitions) * [Type bound](./type/19_bound.md) * [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 system](./type/01_type_system.md) * [Type widening](./type/advanced/widening.md) -* [Tuple](./11_tuple.md) +* [Tuple](./13_tuple.md) ### U * [union](type/13_algebraic.md#union) -* [Unit](./11_tuple.md#unit) +* [Unit](./13_tuple.md#unit) * [Upcasting](type/17_type_casting.md#upcasting) ### V @@ -317,7 +317,7 @@ Also, see [here](../terms.md) for terminology. ### W -* [while] +* while! ### X diff --git a/doc/JA/syntax/00_basic.md b/doc/JA/syntax/00_basic.md index 9f92d3bd..0679ba75 100644 --- a/doc/JA/syntax/00_basic.md +++ b/doc/JA/syntax/00_basic.md @@ -89,7 +89,7 @@ C = Class {x = Int} .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)を参照してください。 ```python diff --git a/doc/JA/syntax/01_literal.md b/doc/JA/syntax/01_literal.md index 92723168..f4f1097f 100644 --- a/doc/JA/syntax/01_literal.md +++ b/doc/JA/syntax/01_literal.md @@ -82,25 +82,25 @@ assert 1e-10 == 0.0000000001 [], [1], [1, 2, 3], ["1", "2",], ... ``` -### [組リテラル(Tuple Literal)](./11_tuple.md) +### [組リテラル(Tuple Literal)](./13_tuple.md) ```python (), (1, 2, 3), (1, "hello", True), ... ``` -### [辞書リテラル(Dict Literal)](./12_dict.md) +### [辞書リテラル(Dict Literal)](./11_dict.md) ```python {:}, {"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 {=}, {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 {}, {1}, {1, 2, 3}, {"1", "2", "1"}, ... diff --git a/doc/zh_CN/syntax/00_basic.md b/doc/zh_CN/syntax/00_basic.md index 8d18d46c..a910a8aa 100644 --- a/doc/zh_CN/syntax/00_basic.md +++ b/doc/zh_CN/syntax/00_basic.md @@ -108,7 +108,7 @@ C = Class {x = Int} ``` 您可以通过在`'''`之后立即写入语言代码来指定文档的语言。然后,[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 ''' diff --git a/doc/zh_CN/syntax/01_literal.md b/doc/zh_CN/syntax/01_literal.md index 259944c9..67dd3779 100644 --- a/doc/zh_CN/syntax/01_literal.md +++ b/doc/zh_CN/syntax/01_literal.md @@ -78,25 +78,25 @@ assert 1e-10 == 0.0000000001 [], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... ``` -### [元组字面量](./11_tuple.md) +### [元组字面量](./13_tuple.md) ```python (), (1, 2, 3), (1, "hello", True), ... ``` -### [字典字面量](./12_dict.md) +### [字典字面量](./11_dict.md) ```python {:}, {"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 {=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... ``` -### [Set 字面量](./14_set.md) +### [Set 字面量](./15_set.md) ```python {}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... diff --git a/doc/zh_TW/syntax/00_basic.md b/doc/zh_TW/syntax/00_basic.md index c9467685..c276808b 100644 --- a/doc/zh_TW/syntax/00_basic.md +++ b/doc/zh_TW/syntax/00_basic.md @@ -107,8 +107,8 @@ C = Class {x = Int} .method self = ... ``` -您可以通過在`'''`之后立即寫入語言代碼來指定文檔的語言。然后,[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)獲取多語言相關文檔 +您可以通過在`'''`之后立即寫入語言代碼來指定文檔的語言。然后,[Erg語言服務器](https://github.com/erg-lang/erg/tree/main/crates/els)將以Markdown格式顯示每種語言版本的文檔(默認語言為英語)。 +參見[這里](https://github.com/erg-lang/erg/blob/main/doc/zh_TW/dev_guide/i18n_messages.md)獲取多語言相關文檔 ```python ''' diff --git a/doc/zh_TW/syntax/01_literal.md b/doc/zh_TW/syntax/01_literal.md index e10d2562..383e1d16 100644 --- a/doc/zh_TW/syntax/01_literal.md +++ b/doc/zh_TW/syntax/01_literal.md @@ -78,25 +78,25 @@ assert 1e-10 == 0.0000000001 [], [1], [1, 2, 3], ["1", "2",], [1, "1", True, [1]], ... ``` -### [元組字面量](./11_tuple.md) +### [元組字面量](./13_tuple.md) ```python (), (1, 2, 3), (1, "hello", True), ... ``` -### [字典字面量](./12_dict.md) +### [字典字面量](./11_dict.md) ```python {:}, {"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 {=}, {one = 1}, {one = 1; two = 2}, {.name = "John"; .age = 12}, {.name = Str; .age = Nat}, ... ``` -### [Set 字面量](./14_set.md) +### [Set 字面量](./15_set.md) ```python {}, {1}, {1, 2, 3}, {"1", "2", "1"}, {1, "1", True, [1]} ... diff --git a/doc/zh_TW/syntax/02_name.md b/doc/zh_TW/syntax/02_name.md index 17bec189..3699952f 100644 --- a/doc/zh_TW/syntax/02_name.md +++ b/doc/zh_TW/syntax/02_name.md @@ -3,6 +3,7 @@ [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/02_name.md%26commit_hash%3D14b0c449efc9e9da3e10a09c912a960ecfaf1c9d)](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 中的代數 - 如果沒有混淆,有時簡稱為變量 - 指的是命名對象并使它們可從代碼的其他地方引用的功能 變量定義如下 From d6bbb910151e054643ce1a8c01ab7c579db2d705 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Fri, 27 Jan 2023 00:38:08 +0900 Subject: [PATCH 11/11] Update docs --- doc/EN/syntax/02_name.md | 4 ++-- doc/JA/syntax/02_name.md | 2 +- doc/zh_CN/syntax/02_name.md | 15 +++++++++++---- doc/zh_TW/syntax/02_name.md | 14 ++++++++++---- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/doc/EN/syntax/02_name.md b/doc/EN/syntax/02_name.md index 1faaf9ba..5daf535c 100644 --- a/doc/EN/syntax/02_name.md +++ b/doc/EN/syntax/02_name.md @@ -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. 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 ``` -```python +```python,compile_fail X = !1 # TypeError: cannot define Int! object as a constant ``` diff --git a/doc/JA/syntax/02_name.md b/doc/JA/syntax/02_name.md index 28c2458c..b9314052 100644 --- a/doc/JA/syntax/02_name.md +++ b/doc/JA/syntax/02_name.md @@ -112,7 +112,7 @@ X = !1 # TypeError: cannot define Int! object as a constant `Del`関数を使うことで、代数を削除することが出来ます。その代数に依存している(その代数の値を直接参照している)他の代数もまとめて削除されます。 -```python +```python,compile_fail x = 1 y = 2 z = 3 diff --git a/doc/zh_CN/syntax/02_name.md b/doc/zh_CN/syntax/02_name.md index 599460f6..4631b609 100644 --- a/doc/zh_CN/syntax/02_name.md +++ b/doc/zh_CN/syntax/02_name.md @@ -3,6 +3,7 @@ [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/02_name.md%26commit_hash%3D14b0c449efc9e9da3e10a09c912a960ecfaf1c9d)](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 中的代数 - 如果没有混淆,有时简称为变量 - 指的是命名对象并使它们可从代码的其他地方引用的功能 变量定义如下 @@ -24,9 +25,12 @@ n: Nat = 1 请注意,与其他语言不同,不允许多次分配 -```python +```python,compile_fail # NG l1 = l2 = [1, 2, 3] # 语法错误: 不允许多重赋值 +``` + +```python # OK l1 = [1, 2, 3] l2 = l1.clone() @@ -67,7 +71,7 @@ assert x == 0 常数也是一种代数。如果标识符以大写字母开头,则将其视为常量。它们被称为常量,因为一旦定义,它们就不会改变 `N` 部分称为常量名(或标识符)。否则,它与变量相同 -```python +```python,compile_fail N = 0 if True, do: N = 1 # 赋值错误: 常量不能被遮蔽 @@ -100,6 +104,9 @@ match! x: ```python X = 1 # OK +``` + +```python,compile_fail X = !1 # 类型错误: 无法定义 Int! 对象作为常量 ``` @@ -107,7 +114,7 @@ X = !1 # 类型错误: 无法定义 Int! 对象作为常量 您可以使用 `Del` 函数删除变量。依赖于变量的所有其他变量(即直接引用变量值的变量)也将被删除 -```python +```python,checker_ignore x = 1 y = 2 z = 3 @@ -122,7 +129,7 @@ f(2) # 名称错误: f 未定义(在第 6 行中删除) 注意 `Del` 只能删除用户自定义模块中定义的变量。无法删除诸如"True"之类的内置常量 -```python +```python,compile_fail Del True # 类型错误: 无法删除内置常量 Del print! # TypeError: 无法删除内置变量 ``` diff --git a/doc/zh_TW/syntax/02_name.md b/doc/zh_TW/syntax/02_name.md index 3699952f..56f3b7a8 100644 --- a/doc/zh_TW/syntax/02_name.md +++ b/doc/zh_TW/syntax/02_name.md @@ -25,9 +25,12 @@ n: Nat = 1 請注意,與其他語言不同,不允許多次分配 -```python +```python,compile_fail # NG l1 = l2 = [1, 2, 3] # 語法錯誤: 不允許多重賦值 +``` + +```python # OK l1 = [1, 2, 3] l2 = l1.clone() @@ -68,7 +71,7 @@ assert x == 0 常數也是一種代數。如果標識符以大寫字母開頭,則將其視為常量。它們被稱為常量,因為一旦定義,它們就不會改變 `N` 部分稱為常量名(或標識符)。否則,它與變量相同 -```python +```python,compile_fail N = 0 if True, do: N = 1 # 賦值錯誤: 常量不能被遮蔽 @@ -101,6 +104,9 @@ match! x: ```python X = 1 # OK +``` + +```python,compile_fail X = !1 # 類型錯誤: 無法定義 Int! 對象作為常量 ``` @@ -108,7 +114,7 @@ X = !1 # 類型錯誤: 無法定義 Int! 對象作為常量 您可以使用 `Del` 函數刪除變量。依賴于變量的所有其他變量(即直接引用變量值的變量)也將被刪除 -```python +```python,compile_fail x = 1 y = 2 z = 3 @@ -123,7 +129,7 @@ f(2) # 名稱錯誤: f 未定義(在第 6 行中刪除) 注意 `Del` 只能刪除用戶自定義模塊中定義的變量。無法刪除諸如"True"之類的內置常量 -```python +```python,compile_fail Del True # 類型錯誤: 無法刪除內置常量 Del print! # TypeError: 無法刪除內置變量 ```