Merge branch 'main' into improve-repl

This commit is contained in:
Cai Bingjun 2023-02-05 14:07:08 +08:00 committed by GitHub
commit c22cd79a89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 574 additions and 66 deletions

View file

@ -2,6 +2,7 @@ name: Docs
on:
push:
branches: [main]
paths:
- "doc/**"
- "**.md"

View file

@ -11,6 +11,8 @@ on:
- "**.md"
- "**.yml"
- "LICENSE-**"
- ".gitmessage"
- ".pre-commit-config.yaml"
pull_request:
branches: [main]
paths-ignore:
@ -21,6 +23,8 @@ on:
- "**.md"
- "**.yml"
- "LICENSE-**"
- ".gitmessage"
- ".pre-commit-config.yaml"
env:
CARGO_TERM_COLOR: always
@ -39,8 +43,6 @@ jobs:
python-version: "3.11.0"
- uses: Swatinem/rust-cache@v2
- run: rustup update stable
- name: Compile
run: cargo test --features large_thread --all --verbose --no-run
- name: Run tests (Windows)
if: runner.os == 'Windows'
# HACK: The cause is unknown, but on windows, the exit code is 1 even if tests are successful.

50
.gitmessage Normal file
View file

@ -0,0 +1,50 @@
# type(scope): description (#issue)
# body
# Wrap at 72 chars. ################################## which is here: #
#
# footer
# Wrap at 72 chars. ################################## which is here: #
#
########################################################################
#
# ## Help ##
#
# ## type: must ##
# feat: new feature
# fix: bug fix or issue resolution
# docs: documentation changes
# style: code style changes
# refactor: refactoring
# perf: performance improvement
# test: adding or changing tests
# build: build-related/version/dependency
# ci: CI-related changes
# chore: internal/minor changes
# revert: revert commit
# * fix, refactor, style and chore are lower priority
#
# ## scope: optional ##
# Indicates the scope
# e.g.
# - parser
# - compiler
# - els
# - REPL
# - linter
#
# ## !: optional ##
# Destructive change
#
# ## description: must ##
# Summary of the commit
# No more than 50 chars
#
# ## issue: optional ##
# Related issue/PR number
#
# ## body: optional ##
# Indicates the details of the commit
#
# ## footer: optional ##
# Represents information related to the commit

View file

@ -2,14 +2,14 @@ repos:
- repo: local
hooks:
- id: rustfmt
exclude: ^doc/|^.github/
exclude: ^doc/|^.github/|^.gitmessage|.md
name: rustfmt
description: Check if all files follow the rustfmt style
entry: cargo fmt --all
language: system
pass_filenames: false
- id: cargo-test
exclude: ^doc/|^.github/
exclude: ^doc/|^.github/|^.gitmessage|.md
name: Cargo test
entry: cargo test --features pre-commit -- --nocapture
language: system

10
Cargo.lock generated
View file

@ -94,7 +94,7 @@ dependencies = [
[[package]]
name = "els"
version = "0.1.15"
version = "0.1.16-nightly.0"
dependencies = [
"erg_common",
"erg_compiler",
@ -105,7 +105,7 @@ dependencies = [
[[package]]
name = "erg"
version = "0.6.3"
version = "0.6.4-nightly.0"
dependencies = [
"els",
"erg_common",
@ -115,7 +115,7 @@ dependencies = [
[[package]]
name = "erg_common"
version = "0.6.3"
version = "0.6.4-nightly.0"
dependencies = [
"backtrace-on-stack-overflow",
"crossterm",
@ -126,7 +126,7 @@ dependencies = [
[[package]]
name = "erg_compiler"
version = "0.6.3"
version = "0.6.4-nightly.0"
dependencies = [
"erg_common",
"erg_parser",
@ -134,7 +134,7 @@ dependencies = [
[[package]]
name = "erg_parser"
version = "0.6.3"
version = "0.6.4-nightly.0"
dependencies = [
"erg_common",
"unicode-xid",

View file

@ -20,7 +20,7 @@ members = [
]
[workspace.package]
version = "0.6.3"
version = "0.6.4-nightly.0"
authors = ["erg-lang team <moderation.erglang@gmail.com>"]
license = "MIT OR Apache-2.0"
edition = "2021"
@ -64,10 +64,10 @@ full = ["els", "full-repl", "unicode", "pretty"]
[workspace.dependencies]
erg_common = { version = "0.6.3", path = "./crates/erg_common" }
erg_parser = { version = "0.6.3", path = "./crates/erg_parser" }
erg_compiler = { version = "0.6.3", path = "./crates/erg_compiler" }
els = { version = "0.1.15", path = "./crates/els" }
erg_common = { version = "0.6.4-nightly.0", path = "./crates/erg_common" }
erg_parser = { version = "0.6.4-nightly.0", path = "./crates/erg_parser" }
erg_compiler = { version = "0.6.4-nightly.0", path = "./crates/erg_compiler" }
els = { version = "0.1.16-nightly.0", path = "./crates/els" }
[dependencies]
erg_common = { workspace = true }

View file

@ -2,7 +2,7 @@
name = "els"
description = "An Erg compiler frontend for IDEs, implements LSP."
documentation = "http://docs.rs/els"
version = "0.1.15"
version = "0.1.16-nightly.0"
authors.workspace = true
license.workspace = true
edition.workspace = true

View file

@ -296,10 +296,13 @@ impl ScriptGenerator {
// TODO: more smart way
fn replace_import(src: &str) -> String {
src.replace("from _erg_nat import Nat", "")
src.replace("from _erg_nat import NatMut", "")
.replace("from _erg_nat import Nat", "")
.replace("from _erg_int import IntMut", "")
.replace("from _erg_int import Int", "")
.replace("from _erg_bool import BoolMut", "")
.replace("from _erg_bool import Bool", "")
.replace("from _erg_str import StrMut", "")
.replace("from _erg_str import Str", "")
.replace("from _erg_array import Array", "")
.replace("from _erg_range import Range", "")

View file

@ -0,0 +1,169 @@
# Guidelines for Commit Messages
This guideline is intended to
* Clarify how commit messages should be written
* Make it easier to refer to the commit message later
and so on. It is an effort goal, and does not require you to rebase and modify your commit message if it deviates from the format (you can use the `--amend` option if you want to change the previous commit message).
There are two rules you should follow:
* Automatically-added commit messages (e.g. `Update xxx.md`, `Automatic update xxx`, `Merge pull request #XXX ...`) should be sent as they are, without modification.
* Manual commit messages should conform to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#specification)
BNF for conventional commits is as follows.
```bnf
commit ::= type ('('' scope ')')? '!' ? ':' description body? footer*.
type ::= 'feat' | 'fix' | 'docs' | 'style' | 'refactor' | 'perf' | 'test' | 'build' | 'ci' | 'chore' | 'revert'
```
Since we develop on GitHub, we'll extend this a bit and allow issue/PR numbers to be added after the description.
```bnf
commit ::= type ('('' scope ')')? '!' ? ':' description ('(' '#' issue ')')? body?
```
The meaning of each part is as follows.
* `type` indicates the type of commit. Please write it in lower case (automatic commits start with a capital letter, so this distinguishes whether it is a manual commit or not).
| type | description |
| ---------- | ---------------------------------------- |
| `feat` | a new feature |
| `fix` | a bug fix or issue resolution |
| `docs` | a change in documentation |
| `style` | a change in code style |
| `refactor` | a refactoring |
| `perf` | performance improvement |
| `test` | adding or changing tests |
| `build` | build-related/version/dependency changes |
| `ci` | CI-related changes |
| `chore` | internal/minor changes |
| `revert` | revert |
* `scope` is optional and indicates the scope of the commit. For example, the commit message `fix(parser):` indicates a bug fix for the parser. You may specify multiple scopes separated by commas, but in that case you should also consider splitting the commit. Examples of scopes are:
* `parser`
* `compiler`
* `els`
* `REPL`
* `linter`
* The `!` mark indicates that the commit has destructive changes. If this mark is set, the reason for the destructive change must be written. Destructive changes include language specification changes, compiler API changes, and so on.
* `description` is a summary of the commit. It should not be too short, but should be approximately 50 characters or less. Basically it should be written in English. Do not begin with a lowercase letter unless it begins with an uppercase word. Do not include a period.
* `body` is optional and indicates the details of the commit.
* `footer` is optional and represents information related to the commit (e.g. list of reviewers, related issue/PR numbers, links, etc.).
---
Here are examples:
```txt
feat(parser): add support for foo (#123)
```
```txt
fix: address CVE-XXXX-YYYY
Ref: https://cve.mitre.org/...
```
```txt
docs!: remove `xxx.md`
The contents of xxx.md are old and inaccurate, so it is deleted.
```
```txt
docs: update commit hash of `xxx.md`
```
```txt
refactor(compiler): `Foo` => `FooBar`
```
```txt
build: update version (v0.1.2 => v0.1.3)
```
```txt
style: fix typo
```
As you can see from the examples, API and file/directory names should be enclosed in ``.
## Supplemental
You are free to write commits in the middle of your work. When you finally squash and organize your work, please follow the rules.
Basically use the present and ongoing tenses for sentences.
If there are messy commits in PR, please change the PR name (use commit_message specification) and use squash and merge(If the commit is clear, merge directly)
## Template configuration
If you want to config the git commit template, you should use the following command.
```shell
git config commit.template .gitmessage
```
This will use this commit message template only in the Erg repository
```txt
# type(scope): description (#issue)
# body
# Wrap at 72 chars. ################################## which is here: #
#
# footer
# Wrap at 72 chars. ################################## which is here: #
#
########################################################################
#
# ## Help ##
#
# ## type: must ##
# feat: new feature
# fix: bug fix or issue resolution
# docs: documentation changes
# style: code style changes
# refactor: refactoring
# perf: performance improvement
# test: adding or changing tests
# build: build-related/version/dependency
# ci: CI-related changes
# chore: internal/minor changes
# revert: revert commit
# * fix, refactor, style and chore are lower priority
#
# ## scope: optional ##
# Indicates the scope
# e.g.
# - parser
# - compiler
# - els
# - REPL
# - linter
#
# ## !: optional ##
# Destructive change
#
# ## description: must ##
# Summary of the commit
# No more than 50 chars
#
# ## issue: optional ##
# Related issue/PR number
#
# ## body: optional ##
# Indicates the details of the commit
#
# ## footer: optional ##
# Represents information related to the commit
```

View file

@ -0,0 +1,171 @@
# コミットメッセージに関するガイドライン
[![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/dev_guide/commit_message.md%26commit_hash%3D1ea58db851c577805696b61b0b56c7f062d0a941)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/commit_message.md&commit_hash=1ea58db851c577805696b61b0b56c7f062d0a941)
このガイドラインは、
* コミットメッセージをどうやって書けば良いのかを明確化する
* コミットメッセージを後から参照しやすくする
などを目的としています。努力目標であり、フォーマットから外れたコミットをした場合でもrebaseして修正などを要求するものではありません(直前のコミットメッセージを変更したい場合は`--amend`オプションが使えます)。
あなたが守るべきガイドラインは以下の2点です。
* 自動的につけられたコミットメッセージ(e.g. `Update xxx.md`, `Automatic update xxx`, `Merge pull request #XXX ...`)は手を加えずそのまま送る
* 手動コミットのメッセージは[conventional commits](https://www.conventionalcommits.org/ja/v1.0.0/#%e4%bb%95%e6%a7%98)に準拠する
conventional commitsのBNFは以下のようになっています。
```bnf
commit ::= type ('(' scope ')')? '!'? ':' description body? footer*
type ::= 'feat' | 'fix' | 'docs' | 'style' | 'refactor' | 'perf' | 'test' | 'build' | 'ci' | 'chore' | 'revert'
```
我々はGitHub上で開発するので、これを少し拡張して、issue/PR番号をdescriptionの後に追加して良いことにします。
```bnf
commit ::= type ('(' scope ')')? '!'? ':' description ('(' '#' issue ')')? body? footer*
```
各部分の意味は以下の通りです。
* `type`はcommitの型を表します。小文字で書いてください(自動commitは大文字で始まるので、これによって手動コミットかどうかを区別します)
| type | 説明 |
| ---------- | -------------------------------------- |
| `feat` | 新しい機能 |
| `fix` | バグの修正やissueの解決 |
| `docs` | ドキュメントの変更 |
| `style` | コードスタイルの変更 |
| `refactor` | リファクタリング |
| `perf` | パフォーマンスの改善 |
| `test` | テストの追加や変更 |
| `build` | ビルド関連・バージョン・依存関係の変更 |
| `ci` | CI関連の変更 |
| `chore` | 内部的・軽微な変更 |
| `revert` | revert |
複数該当する場合は、より具体的なtypeを選んでください。優先度の低いtypeは`fix`, `refactor`, `style`, `chore`になります。例えば、ドキュメント(docs)の修正(fix)は`docs`、テスト(test)のリファクタリング(refactor)は`test`になります。
* `scope`は省略可能で、コミットの影響範囲を表します。例えば、`fix(parser):`というコミットメッセージはパーサーのバグ修正であることを示します。コンマ区切りで複数のスコープを指定することもできますが、その場合コミットを分割することも検討してください。スコープの例は以下の通りです。
* `parser`
* `compiler`
* `els`
* `REPL`
* `linter`
* `!`マークはコミットが破壊的な変更であることを示します。このマークがついている場合、破壊的変更の理由を書く必要があります。破壊的変更は、言語の仕様変更やコンパイラAPIの変更などが該当します。
* `description`はコミットの概要を表します。あまり短すぎてはいけませんが、おおよそ50文字以内に収めるべきです。原則として英語で書いてください。大文字の単語で始まるとき以外は小文字で始めてください。ピリオドは付けないでください。
* `body`は省略可能で、コミットの詳細を表します。
* `footer`は省略可能で、コミットの関連情報を表します(レビュアーの一覧や、関連するissue/PR番号を書くなど)。
---
例としては以下になります。
```txt
feat(parser): add support for foo (#123)
```
```txt
fix: address CVE-XXXX-YYYY
Ref: https://cve.mitre.org/...
```
```txt
docs!: remove `xxx.md`
The contents of xxx.md are old and inaccurate, so it is deleted.
```
```txt
docs: update commit hash of `xxx.md`
```
```txt
refactor(compiler): `Foo` => `FooBar`
```
```txt
build: update version (v0.1.2 => v0.1.3)
```
```txt
style: fix typo
```
例から分かる通り、APIやファイル・ディレクトリ名は``で囲ってください。
## 補足
作業途中のコミットは自由に書いて構いません。最終的にsquash等をして整理するときに、規則に従ってください。
文は特に理由のない場合現在形・現在進行形で書いてください。
PRに乱雑なコミットがある場合は、PR名を変更し(commit_message仕様を使用)、squash and mergeを使用してください(コミットが明確な場合は直接マージしてください)
## テンプレートの設定
もしテンプレートを利用したい場合は以下のコマンドを利用してください
```shell
git config commit.template .gitmessage
```
これによりErgのリポジトリ内でのみこのコミットメッセージのテンプレートが利用されます
```txt
# type(scope): description (#issue)
# body
# Wrap at 72 chars. ################################## which is here: #
#
# footer
# Wrap at 72 chars. ################################## which is here: #
#
########################################################################
#
# ## Help ##
#
# ## type: must ##
# feat: new feature
# fix: bug fix or issue resolution
# docs: documentation changes
# style: code style changes
# refactor: refactoring
# perf: performance improvement
# test: adding or changing tests
# build: build-related/version/dependency
# ci: CI-related changes
# chore: internal/minor changes
# revert: revert commit
# * fix, refactor, style and chore are lower priority
#
# ## scope: optional ##
# Indicates the scope
# e.g.
# - parser
# - compiler
# - els
# - REPL
# - linter
#
# ## !: optional ##
# Destructive change
#
# ## description: must ##
# Summary of the commit
# No more than 50 chars
#
# ## issue: optional ##
# Related issue/PR number
#
# ## body: optional ##
# Indicates the details of the commit
#
# ## footer: optional ##
# Represents information related to the commit
```

View file

@ -99,6 +99,7 @@ This This file is generated automatically. If you want to edit this, edit [`doc/
| [dev_guide/about.md](../EN/dev_guide/about.md) | [📝](../JA/dev_guide/about.md) Badge not found |
| [dev_guide/branches.md](../EN/dev_guide/branches.md) | [📝](../JA/dev_guide/branches.md) [![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/dev_guide/branches.md%26commit_hash%3Dbf5df01d09e42ec8433a628420e096ac55e4d3e4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=bf5df01d09e42ec8433a628420e096ac55e4d3e4) |
| [dev_guide/build_features.md](../EN/dev_guide/build_features.md) | [📝](../JA/dev_guide/build_features.md) [![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/dev_guide/build_features.md%26commit_hash%3D06f8edc9e2c0cee34f6396fd7c64ec834ffb5352)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=06f8edc9e2c0cee34f6396fd7c64ec834ffb5352) |
| [dev_guide/commit_message.md](../EN/dev_guide/commit_message.md) | [📝](../JA/dev_guide/commit_message.md) [![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/dev_guide/commit_message.md%26commit_hash%3D1ea58db851c577805696b61b0b56c7f062d0a941)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/commit_message.md&commit_hash=1ea58db851c577805696b61b0b56c7f062d0a941) |
| [dev_guide/directories.md](../EN/dev_guide/directories.md) | [📝](../JA/dev_guide/directories.md) [![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/dev_guide/directories.md%26commit_hash%3D94185d534afe909d112381b53d60895389d02f95)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=94185d534afe909d112381b53d60895389d02f95) |
| [dev_guide/doc_guideline.md](../EN/dev_guide/doc_guideline.md) | [📝](../JA/dev_guide/doc_guideline.md) [![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/dev_guide/doc_guideline.md%26commit_hash%3Da9d45b743cc655543e0d7f586426499091cead3d)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=a9d45b743cc655543e0d7f586426499091cead3d) |
| [dev_guide/embedding.md](../EN/dev_guide/embedding.md) | [📝](../JA/dev_guide/embedding.md) [![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/dev_guide/embedding.md%26commit_hash%3D94185d534afe909d112381b53d60895389d02f95)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/embedding.md&commit_hash=94185d534afe909d112381b53d60895389d02f95) |

View file

@ -99,6 +99,7 @@ This This file is generated automatically. If you want to edit this, edit [`doc/
| [dev_guide/about.md](../EN/dev_guide/about.md) | [📝](../zh_CN/dev_guide/about.md) Badge not found |
| [dev_guide/branches.md](../EN/dev_guide/branches.md) | [📝](../zh_CN/dev_guide/branches.md) [![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/dev_guide/branches.md%26commit_hash%3Dbf5df01d09e42ec8433a628420e096ac55e4d3e4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=bf5df01d09e42ec8433a628420e096ac55e4d3e4) |
| [dev_guide/build_features.md](../EN/dev_guide/build_features.md) | [📝](../zh_CN/dev_guide/build_features.md) [![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/dev_guide/build_features.md%26commit_hash%3Dcbaf48c04b46fadc680fa4e05e8ad22cbdaf6c47)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=cbaf48c04b46fadc680fa4e05e8ad22cbdaf6c47) |
| [dev_guide/commit_message.md](../EN/dev_guide/commit_message.md) | [📝](../zh_CN/dev_guide/commit_message.md) File not found |
| [dev_guide/directories.md](../EN/dev_guide/directories.md) | [📝](../zh_CN/dev_guide/directories.md) [![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/dev_guide/directories.md%26commit_hash%3D94185d534afe909d112381b53d60895389d02f95)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=94185d534afe909d112381b53d60895389d02f95) |
| [dev_guide/doc_guideline.md](../EN/dev_guide/doc_guideline.md) | [📝](../zh_CN/dev_guide/doc_guideline.md) [![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/dev_guide/doc_guideline.md%26commit_hash%3Da9d45b743cc655543e0d7f586426499091cead3d)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=a9d45b743cc655543e0d7f586426499091cead3d) |
| [dev_guide/embedding.md](../EN/dev_guide/embedding.md) | [📝](../zh_CN/dev_guide/embedding.md) [![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/dev_guide/embedding.md%26commit_hash%3D94185d534afe909d112381b53d60895389d02f95)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/embedding.md&commit_hash=94185d534afe909d112381b53d60895389d02f95) |

View file

@ -99,6 +99,7 @@ This This file is generated automatically. If you want to edit this, edit [`doc/
| [dev_guide/about.md](../EN/dev_guide/about.md) | [📝](../zh_TW/dev_guide/about.md) Badge not found |
| [dev_guide/branches.md](../EN/dev_guide/branches.md) | [📝](../zh_TW/dev_guide/branches.md) [![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/dev_guide/branches.md%26commit_hash%3Dbf5df01d09e42ec8433a628420e096ac55e4d3e4)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/branches.md&commit_hash=bf5df01d09e42ec8433a628420e096ac55e4d3e4) |
| [dev_guide/build_features.md](../EN/dev_guide/build_features.md) | [📝](../zh_TW/dev_guide/build_features.md) [![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/dev_guide/build_features.md%26commit_hash%3Dcbaf48c04b46fadc680fa4e05e8ad22cbdaf6c47)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/build_features.md&commit_hash=cbaf48c04b46fadc680fa4e05e8ad22cbdaf6c47) |
| [dev_guide/commit_message.md](../EN/dev_guide/commit_message.md) | [📝](../zh_TW/dev_guide/commit_message.md) File not found |
| [dev_guide/directories.md](../EN/dev_guide/directories.md) | [📝](../zh_TW/dev_guide/directories.md) [![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/dev_guide/directories.md%26commit_hash%3D94185d534afe909d112381b53d60895389d02f95)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/directories.md&commit_hash=94185d534afe909d112381b53d60895389d02f95) |
| [dev_guide/doc_guideline.md](../EN/dev_guide/doc_guideline.md) | [📝](../zh_TW/dev_guide/doc_guideline.md) [![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/dev_guide/doc_guideline.md%26commit_hash%3Da9d45b743cc655543e0d7f586426499091cead3d)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/doc_guideline.md&commit_hash=a9d45b743cc655543e0d7f586426499091cead3d) |
| [dev_guide/embedding.md](../EN/dev_guide/embedding.md) | [📝](../zh_TW/dev_guide/embedding.md) [![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/dev_guide/embedding.md%26commit_hash%3D94185d534afe909d112381b53d60895389d02f95)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/dev_guide/embedding.md&commit_hash=94185d534afe909d112381b53d60895389d02f95) |

View file

@ -70,7 +70,7 @@ impl Runnable for DummyVM {
let port = find_available_port();
let code = include_str!("scripts/repl_server.py")
.replace("__PORT__", port.to_string().as_str())
.replace("__MODULE__", &cfg.dump_filename());
.replace("__MODULE__", &cfg.dump_filename().replace('/', "."));
spawn_py(cfg.py_command, &code);
let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, port);
if !cfg.quiet_repl {

View file

@ -1,17 +1,44 @@
//! for performance, 1 function per 1~2 test
use crate::eval::{eval, successful_output};
#[test]
fn eval_print() {
fn eval_print_1() {
assert_eq!(eval("print! 1"), successful_output("1\n"));
}
#[test]
fn eval_print_str() {
assert_eq!(eval("print! \"abc\""), successful_output("abc\n"));
assert_eq!(eval("print!(\"a\")"), successful_output("a\n"));
}
#[test]
fn eval_print_ratio() {
assert_eq!(eval("print! \"0.3\""), successful_output("0.3\n"));
}
#[test]
fn eval_print_bool() {
assert_eq!(eval("print! True"), successful_output("True\n"));
}
#[test]
fn eval_print_unit() {
assert_eq!(eval("print! (())"), successful_output("()\n"));
}
#[test]
fn eval_interpolation() {
assert_eq!(
eval("world = \"world\"\nprint! \"hello \\{world}\""),
successful_output("hello world\n")
);
assert_eq!(eval("print! \"0.3\""), successful_output("0.3\n"));
assert_eq!(eval("print! True"), successful_output("True\n"));
assert_eq!(eval("print! (())"), successful_output("()\n"));
assert_eq!(eval("print! \"\\{0.005}\""), successful_output("0.005\n"));
}
#[test]
fn eval_multiline_str() {
assert_eq!(
eval(
r#"print! """A
@ -20,33 +47,58 @@ D""""#
),
successful_output("A\nB C \nD\n")
);
assert_eq!(eval("print!(\"a\")"), successful_output("a\n"));
}
#[test]
fn eval_keyword_call() {
assert_eq!(
eval("print! \"a\", \"b\", 3, end := \"\""),
successful_output("a b 3")
);
}
{
let output = eval("print 1"); // print! is correct
assert_eq!(output.stdout, "");
assert!(!output.stderr.is_empty());
assert_eq!(output.status_code, Some(1));
}
#[test]
fn eval_invalid_print() {
let output = eval("print 1"); // print! is correct
assert_eq!(output.stdout, "");
assert!(!output.stderr.is_empty());
assert_eq!(output.status_code, Some(1));
}
#[test]
fn eval_assign_and_print() {
assert_eq!(eval("num = -3\nprint! num * 2").stdout, "-6\n");
}
#[test]
fn eval_assert() {
fn eval_assert_true() {
assert_eq!(eval("assert True"), successful_output(""));
assert_eq!(eval("assert 1"), successful_output(""));
assert_eq!(eval("flag = True\nassert flag"), successful_output(""));
}
{
let output = eval("assert False");
assert_eq!(output.stdout, "");
assert!(!output.stderr.is_empty());
assert_eq!(output.status_code, Some(1));
}
#[test]
fn eval_assert_1() {
assert_eq!(eval("assert 1"), successful_output(""));
}
#[test]
fn eval_assign_and_assert() {
assert_eq!(eval("flag = True\nassert flag"), successful_output(""));
}
#[test]
fn eval_assert_false() {
let output = eval("assert False");
assert_eq!(output.stdout, "");
assert!(!output.stderr.is_empty());
assert_eq!(output.status_code, Some(1));
}
#[test]
fn eval_assert_0point2() {
assert_eq!(eval("assert 0.2").status_code, Some(1));
}
#[test]
fn eval_invalid_assert() {
assert_eq!(eval("assert! True").status_code, Some(1));
}

View file

@ -1,30 +1,57 @@
use crate::eval::{eval, successful_output};
#[test]
fn eval_string() {
fn eval_assert_str() {
assert_eq!(
eval("assert \"abcdef\" == \"abcdef\""),
successful_output("")
);
}
#[test]
fn eval_assert_interpolation() {
assert_eq!(
eval("assert \"1234567890ABC\" == \"\\{1234567890}ABC\""),
successful_output("")
);
}
#[test]
fn eval_print_empty() {
assert_eq!(eval("print! \"\""), successful_output("\n"));
}
#[test]
fn eval_assert_empty() {
assert_eq!(eval("assert \"\" == \"\""), successful_output(""));
assert_eq!(eval("print! \"A\""), successful_output("A\n"));
}
#[test]
fn eval_assert_interpolation_2() {
assert_eq!(
eval(r#"a = 10;print! "2 * 5 = \{a}""#),
successful_output("2 * 5 = 10\n")
eval(r#"a = 10;assert "\{2 * 5}" == "\{a}""#),
successful_output("")
);
}
#[test]
fn eval_interpolation() {
assert_eq!(
eval(r#"print! " \{"b"}\{False} \{[1]}""#),
successful_output(" bFalse [1]\n")
);
}
#[test]
fn eval_interpolation_2() {
assert_eq!(
eval(r#"print! "a\{"b"}c\{"d \{" e\{"f"}g\{-2+3}"}"}""#),
successful_output("abcd efg1\n")
);
}
#[test]
fn eval_multiline_string() {
assert_eq!(
eval(
r#"print! """abc
@ -34,6 +61,10 @@ j kl """"#
),
successful_output("abc\ndef\n ghi\nj kl \n")
);
}
#[test]
fn eval_multiline_string_interpolation() {
assert_eq!(
eval(
r#"print! """
@ -44,38 +75,64 @@ a
successful_output("\n ()\na\n\n")
);
// TODO: more diverse characters
}
{
let output = eval("assert \"abcde\" == \"abcdef\"");
assert_eq!(output.stdout, "");
assert!(!output.stderr.is_empty());
assert_eq!(output.status_code, Some(1));
}
#[test]
fn eval_invalid_assertion() {
let output = eval("assert \"abcde\" == \"abcdef\"");
assert_eq!(output.stdout, "");
assert!(!output.stderr.is_empty());
assert_eq!(output.status_code, Some(1));
}
#[test]
fn eval_invalid_closing_string() {
assert_eq!(eval("print! \"\\\"").status_code, Some(1));
}
#[test]
fn eval_int() {
fn eval_assert_99() {
assert_eq!(eval("assert 99 == 99"), successful_output(""));
assert_eq!(eval("print! 256"), successful_output("256\n"));
// assert_eq!(eval_code("assert -2 == -2"), success_output("")); // failed
assert_eq!(eval("print! 0"), successful_output("0\n"));
// assert_eq!(eval_code("print! -1000"), success_output("-1000\n")); // failed
assert_eq!(eval("print! 0 == 0"), successful_output("True\n"));
assert_eq!(eval("print! 2147483647"), successful_output("2147483647\n"));
// assert_eq!(eval("print! 2147483648"), successful_output("2147483648\n")); // should be ok?
assert_eq!(
eval("print!(-2147483648)"),
successful_output("-2147483648\n")
);
// assert_eq!(eval("print!(-2147483649)"), successful_output("-2147483649\n")); // should be ok?
}
{
let result = eval("assert 100 == 1000");
assert_eq!(result.stdout, "");
assert!(!result.stderr.is_empty());
assert_eq!(result.status_code, Some(1));
}
#[test]
fn eval_assert_minus2() {
assert_eq!(eval("assert -2 == -2"), successful_output(""));
}
#[test]
fn eval_minus1000() {
assert_eq!(eval("print! -1000"), successful_output("-1000\n"));
}
#[test]
fn eval_0_eq_0() {
assert_eq!(eval("print! 0 == 0"), successful_output("True\n"));
}
// TODO: support big numbers
/*
#[test]
fn eval_bignum() {
assert_eq!(eval("print! 214748364778473683657867814876187416"), successful_output("214748364778473683657867814876187416\n"));
}
#[test]
fn eval_neg_bignum() {
assert_eq!(eval("print!(-214748364778473683657867814876187416)"), successful_output("-214748364778473683657867814876187416\n"));
}
*/
#[test]
fn eval_assert_inequality() {
let result = eval("assert 100 == 1000");
assert_eq!(result.stdout, "");
assert!(!result.stderr.is_empty());
assert_eq!(result.status_code, Some(1));
}
#[test]
fn eval_assert_inequality_2() {
assert_eq!(eval("assert 10 == 11").status_code, Some(1));
}