From dc840e2949ef21db4d505a8ed3cb481e3e1e96e8 Mon Sep 17 00:00:00 2001 From: illusory0x0 Date: Wed, 20 Aug 2025 14:57:10 +0800 Subject: [PATCH 1/2] docs: add native FFI documentation for MoonBit Sources example authored by @illusory0x0 Documentation generated by moon-pilort and reviewed by @illusory0x0 --- .gitignore | 4 +- next/example/index.md | 4 +- .../example/native-ffi/funcref_map_inplace.md | 144 ++++++++++++++++++ next/example/native-ffi/funcref_qsort.md | 108 +++++++++++++ .../native-ffi/funcref_qsort_closure.md | 136 +++++++++++++++++ .../native-ffi/funcref_register_callback.md | 106 +++++++++++++ next/example/native-ffi/index.md | 18 +++ next/sources/native-ffi/CMakeLists.txt | 15 ++ next/sources/native-ffi/README.md | 3 + next/sources/native-ffi/main.c | 4 + next/sources/native-ffi/moon.mod.json | 11 ++ .../funcref_map_inplace.mbti | 22 +++ .../src/funcref_map_inplace/moon.pkg.json | 13 ++ .../native-ffi/src/funcref_map_inplace/stub.c | 26 ++++ .../src/funcref_map_inplace/top.mbt | 53 +++++++ .../src/funcref_qsort/funcref_qsort.mbti | 22 +++ .../src/funcref_qsort/moon.pkg.json | 13 ++ .../native-ffi/src/funcref_qsort/stub.c | 58 +++++++ .../native-ffi/src/funcref_qsort/top.mbt | 42 +++++ .../funcref_qsort_closure.mbti | 22 +++ .../src/funcref_qsort_closure/moon.pkg.json | 13 ++ .../src/funcref_qsort_closure/stub.c | 67 ++++++++ .../src/funcref_qsort_closure/top.mbt | 54 +++++++ .../funcref_register_callback.mbti | 13 ++ .../funcref_register_callback/moon.pkg.json | 13 ++ .../src/funcref_register_callback/stub.c | 24 +++ .../src/funcref_register_callback/top.mbt | 48 ++++++ 27 files changed, 1054 insertions(+), 2 deletions(-) create mode 100644 next/example/native-ffi/funcref_map_inplace.md create mode 100644 next/example/native-ffi/funcref_qsort.md create mode 100644 next/example/native-ffi/funcref_qsort_closure.md create mode 100644 next/example/native-ffi/funcref_register_callback.md create mode 100644 next/example/native-ffi/index.md create mode 100644 next/sources/native-ffi/CMakeLists.txt create mode 100644 next/sources/native-ffi/README.md create mode 100644 next/sources/native-ffi/main.c create mode 100644 next/sources/native-ffi/moon.mod.json create mode 100644 next/sources/native-ffi/src/funcref_map_inplace/funcref_map_inplace.mbti create mode 100644 next/sources/native-ffi/src/funcref_map_inplace/moon.pkg.json create mode 100644 next/sources/native-ffi/src/funcref_map_inplace/stub.c create mode 100644 next/sources/native-ffi/src/funcref_map_inplace/top.mbt create mode 100644 next/sources/native-ffi/src/funcref_qsort/funcref_qsort.mbti create mode 100644 next/sources/native-ffi/src/funcref_qsort/moon.pkg.json create mode 100644 next/sources/native-ffi/src/funcref_qsort/stub.c create mode 100644 next/sources/native-ffi/src/funcref_qsort/top.mbt create mode 100644 next/sources/native-ffi/src/funcref_qsort_closure/funcref_qsort_closure.mbti create mode 100644 next/sources/native-ffi/src/funcref_qsort_closure/moon.pkg.json create mode 100644 next/sources/native-ffi/src/funcref_qsort_closure/stub.c create mode 100644 next/sources/native-ffi/src/funcref_qsort_closure/top.mbt create mode 100644 next/sources/native-ffi/src/funcref_register_callback/funcref_register_callback.mbti create mode 100644 next/sources/native-ffi/src/funcref_register_callback/moon.pkg.json create mode 100644 next/sources/native-ffi/src/funcref_register_callback/stub.c create mode 100644 next/sources/native-ffi/src/funcref_register_callback/top.mbt diff --git a/.gitignore b/.gitignore index cb760dd5..24895f32 100644 --- a/.gitignore +++ b/.gitignore @@ -29,8 +29,10 @@ _build/ # MoonBit .mooncakes/ +.moonagent/ # Python __pycache__/ *.pyc -*.pyo \ No newline at end of file +*.pyo + diff --git a/next/example/index.md b/next/example/index.md index 8b660fd9..092d32a4 100644 --- a/next/example/index.md +++ b/next/example/index.md @@ -13,4 +13,6 @@ sudoku/index lambda/index gmachine/index myers-diff/index -segment-tree/index \ No newline at end of file +segment-tree/index +native-ffi/index +``` \ No newline at end of file diff --git a/next/example/native-ffi/funcref_map_inplace.md b/next/example/native-ffi/funcref_map_inplace.md new file mode 100644 index 00000000..d0882e5a --- /dev/null +++ b/next/example/native-ffi/funcref_map_inplace.md @@ -0,0 +1,144 @@ +# In-place Map Transformation Example + +```{admonition} ⚠️ Critical Technique: Closure First Parameter Reference Counting +:class: warning + +This example uses adapter function type `FuncRef[((Point) -> Point, Point) -> Point]`, note that **closure is the first parameter**. + +**Important rule**: Before each call to this adapter function in C code, you must execute `moonbit_incref(closure)` on the closure, otherwise it will cause use-after-free errors. + +In the example, each array element is called twice, so two `moonbit_incref` calls are needed. +``` + +This example demonstrates how to implement in-place array transformation operations, showcasing MoonBit closure usage in array element transformations. + +## Overview + +This example implements a `map_inplace` function that can apply transformation functions to each element in an array. Unlike the previous sorting examples, this focuses on element transformation rather than comparison operations. + +## FFI Function Declaration + +MoonBit side FFI declaration: + +```{literalinclude} /sources/native-ffi/src/funcref_map_inplace/top.mbt +:language: moonbit +:start-after: start map inplace ffi declaration +:end-before: end map inplace ffi declaration +``` + +Function parameter analysis: + +1. **`xs : FixedArray[Point]`**: Array to be transformed +2. **⚠️ `call : FuncRef[((Point) -> Point, Point) -> Point]`**: Adapter function type + - **Key**: First parameter `(Point) -> Point` is the closure itself + - Second parameter `Point` is the input value passed to the closure + - Return value `Point` is the execution result of the closure +3. **`closure : (Point) -> Point`**: Actual transformation closure + +## Wrapper Function + +```{literalinclude} /sources/native-ffi/src/funcref_map_inplace/top.mbt +:language: moonbit +:start-after: start map inplace wrapper +:end-before: end map inplace wrapper +``` + +This wrapper function provides a clean interface, hiding FFI complexity. + +## C Implementation Details + +### Type Definitions + +```{literalinclude} /sources/native-ffi/src/funcref_map_inplace/stub.c +:language: c +:start-after: start map inplace types +:end-before: end map inplace types +``` + +Simplified type definitions: +- `moonbit_closure_t`: Represents MoonBit closures +- `moonbit_point_t`: Represents Point objects + +### Core Implementation + +```{literalinclude} /sources/native-ffi/src/funcref_map_inplace/stub.c +:language: c +:start-after: start map inplace implementation +:end-before: end map inplace implementation +``` + +### Implementation Detail Analysis + +1. **Array length retrieval**: Use `Moonbit_array_length(xs)` to get array length +2. **Loop processing**: Iterate through each element in the array +3. **Double call**: Each element is called by transformation function twice (for demonstration) +4. **⚠️ Critical reference count management**: Need `moonbit_incref(closure)` before each call + - **Reason**: Closure as first parameter of adapter function consumes one reference when called + - **Must**: Execute `moonbit_incref(closure)` before each `call(closure, xs[i])` + - **Consequence**: Forgetting to increment reference count leads to use-after-free or memory leaks + +### Memory Management Points + +- **Closure lifetime**: Increment closure reference count before each call +- **In-place modification**: Directly modify array elements `xs[i] = call(closure, xs[i])` +- **No manual release**: Due to `#borrow` attribute, MoonBit compiler-generated code automatically manages memory + +## Test Case Analysis + +```{literalinclude} /sources/native-ffi/src/funcref_map_inplace/top.mbt +:language: moonbit +:lines: 19-39 +``` + +### Test Highlights + +1. **Counter closure**: Transformation function captures external variable `i` to count call times +2. **Identity transformation**: Function returns input Point unchanged, focus is on verifying call count +3. **Multiple call verification**: + - After first call: `i = 8` (4 elements × 2 calls each) + - After second call: `i = 16` + - After third call: `i = 24` + +### Call Count Calculation + +For an array of length 4: +- Each element is transformed 2 times in one `map_inplace` call +- Total: 4 × 2 = 8 function calls +- Three `map_inplace` calls: 8 × 3 = 24 times + +## Design Pattern Analysis + +### Adapter Pattern Application + +```moonbit +ffi_map_inplace(xs, fn(f, x) { f(x) }, closure) +``` + +The `fn(f, x) { f(x) }` here is an adapter function that: +1. Receives closure `f` and parameter `x` +2. Calls closure and returns result +3. Bridges MoonBit closures and C function pointers + +### FFI Design Principles + +1. **Type safety**: Ensure correct function signatures through type system +2. **Memory safety**: Use `#borrow` to simplify lifetime management +3. **Performance optimization**: In-place modification avoids additional memory allocation +4. **Interface simplification**: Provide clean user interfaces through wrapper functions + +## Comparison with Other Examples + +| Example | Operation Type | Closure Features | C Implementation Complexity | +|---------|----------------|------------------|---------------------------| +| register_callback | Callback registration | Multiple calls | Simple | +| qsort | Comparison sorting | Returns integer | Medium (cross-platform) | +| qsort_closure | Comparison sorting | Variable capture | Medium | +| map_inplace | Element transformation | Returns object | Simple | + +## Key Learning Points + +1. **In-place operation pattern**: Understand how to implement efficient in-place array operations through FFI +2. **Object return handling**: Master how to handle closures that return MoonBit objects +3. **Counter pattern**: Learn how to monitor execution through closure-captured state +4. **Performance considerations**: Understand performance advantages of in-place operations compared to creating new arrays +5. **FFI design best practices**: Understand core principles of FFI interface design through this simple example \ No newline at end of file diff --git a/next/example/native-ffi/funcref_qsort.md b/next/example/native-ffi/funcref_qsort.md new file mode 100644 index 00000000..34695bc6 --- /dev/null +++ b/next/example/native-ffi/funcref_qsort.md @@ -0,0 +1,108 @@ +# Quick Sort with Comparison Function Example + +This example demonstrates how to pass MoonBit comparison functions to the C standard library's `qsort` function, showcasing `FuncRef` type usage in practical algorithms. + +## Overview + +This example sorts MoonBit's `FixedArray[Point]` by calling the C standard library's `qsort_r` function, demonstrating: + +1. How to handle different `qsort_r` signatures across different platforms +2. Using `FuncRef` type as comparison functions +3. Cross-platform compatibility handling + +## Data Structure Definition + +First, define the `Point` structure used for sorting: + +```{literalinclude} /sources/native-ffi/src/funcref_qsort/top.mbt +:language: moonbit +:start-after: start point definition +:end-before: end point definition +``` + +The `Point` structure derives multiple traits, including `Compare`, allowing us to directly use the `compare` method for comparison. + +## FFI Function Declaration + +MoonBit side FFI declaration: + +```{literalinclude} /sources/native-ffi/src/funcref_qsort/top.mbt +:language: moonbit +:start-after: start qsort ffi declaration +:end-before: end qsort ffi declaration +``` + +Key features: + +1. **`#borrow` attribute**: Avoids manual reference count management +2. **`FixedArray[Point]`**: Represented as `Point*` on the C side +3. **`FuncRef[(Point, Point) -> Int]`**: Comparison function type, returns integer indicating comparison result + +## C Implementation Details + +### Type Definitions and Context Structure + +```{literalinclude} /sources/native-ffi/src/funcref_qsort/stub.c +:language: c +:start-after: start type definitions +:end-before: end type definitions +``` + +These type definitions: +- `moonbit_point_t`: C representation of MoonBit Point objects +- `moonbit_fixedarray_point_t`: C representation of Point arrays +- `comp_context`: Context structure wrapping comparison functions + +### Cross-platform Comparison Function + +Due to different `qsort_r` function signatures on different platforms, conditional compilation is needed: + +```{literalinclude} /sources/native-ffi/src/funcref_qsort/stub.c +:language: c +:start-after: start cross platform comparison function +:end-before: end cross platform comparison function +``` + +### Memory Management + +In the comparison function: +1. **Reference count increment**: Call `moonbit_incref` to increase parameter reference counts +2. **Function call**: Call MoonBit comparison function through function pointer +3. **Automatic cleanup**: Due to `#borrow` usage, MoonBit compiler-generated code automatically handles reference counting + +### Main Sorting Function + +```{literalinclude} /sources/native-ffi/src/funcref_qsort/stub.c +:language: c +:start-after: start main qsort function +:end-before: end main qsort function +``` + +### Cross-platform Compatibility + +Different platforms use different sorting functions: +- **Windows**: Uses `qsort_s` +- **macOS**: Uses `qsort_r` (BSD style) +- **Linux**: Uses `qsort_r` (GNU style) + +## Test Case + +```{literalinclude} /sources/native-ffi/src/funcref_qsort/top.mbt +:language: moonbit +:lines: 14-36 +``` + +Test flow: + +1. **Data generation**: Use `@quickcheck.samples` to generate random test data +2. **Comparison function**: Create `FuncRef` type comparison function +3. **Sort comparison**: Use both C's `qsort` and MoonBit's `sort` method +4. **Result verification**: Ensure both sorting methods produce identical results + +## Key Learning Points + +1. **Cross-platform handling**: Learn how to handle differences in C standard libraries across platforms +2. **Function pointer passing**: Master techniques for passing MoonBit functions as C function pointers +3. **Memory safety**: Understand the importance of correctly managing reference counts in callback functions +4. **Type mapping**: Learn how MoonBit complex types are represented on the C side +5. **Context passing**: Pass additional context information to callback functions through structures \ No newline at end of file diff --git a/next/example/native-ffi/funcref_qsort_closure.md b/next/example/native-ffi/funcref_qsort_closure.md new file mode 100644 index 00000000..70adc158 --- /dev/null +++ b/next/example/native-ffi/funcref_qsort_closure.md @@ -0,0 +1,136 @@ +# Quick Sort with Closure Example + +```{admonition} ⚠️ Critical Technique: Closure First Parameter Reference Counting +:class: warning + +This example uses adapter function type `FuncRef[((Point, Point) -> Int, Point, Point) -> Int]`, note that **closure is the first parameter**. + +**Important rule**: Before each call to this adapter function in C code, you must execute `moonbit_incref(closure)` on the closure, otherwise it will cause use-after-free errors. + +This is one of the most error-prone areas in MoonBit Native FFI! +``` + +This example shows how to pass MoonBit closures to C functions. Unlike the previous example, the comparison function used here can capture external variables. + +## Overview + +This example implements a more advanced sorting interface that supports passing closures that can capture variables as comparison functions. It demonstrates: + +1. How MoonBit closures are handled in C FFI +2. Differences and conversions between closures and `FuncRef` +3. Complex function type FFI declarations + +## FFI Function Declaration + +The MoonBit side FFI declaration is more complex than the previous example: + +```{literalinclude} /sources/native-ffi/src/funcref_qsort_closure/top.mbt +:language: moonbit +:start-after: start closure qsort ffi declaration +:end-before: end closure qsort ffi declaration +``` + +Key feature analysis: + +1. **Three parameters**: + - `xs`: Array to be sorted + - `comp`: Adapter function, type `FuncRef[((Point, Point) -> Int, Point, Point) -> Int]` + - `closure`: Actual comparison closure, type `(Point, Point) -> Int` + +2. **⚠️ Important details of adapter function signature**: + - Note `comp` type: `((Point, Point) -> Int, Point, Point) -> Int` + - **First parameter is the closure itself**, subsequent parameters are passed to the closure + - This design requires special handling of closure reference counting on the C side + +3. **Adapter pattern**: Call `closure` through `comp` function, this is the standard pattern for handling closures + +## Wrapper Function + +MoonBit provides a simplified interface: + +```{literalinclude} /sources/native-ffi/src/funcref_qsort_closure/top.mbt +:language: moonbit +:start-after: start closure qsort wrapper +:end-before: end closure qsort wrapper +``` + +This wrapper function: +- Accepts regular closure function `comp : (Point, Point) -> Int` +- Creates adapter function `fn(f, x, y) { f(x, y) }` +- Hides FFI complexity + +## C Implementation Details + +### Type Definitions and Context Structure + +```{literalinclude} /sources/native-ffi/src/funcref_qsort_closure/stub.c +:language: c +:start-after: start closure type definitions +:end-before: end closure type definitions +``` + +Main differences from the previous example: +- Added `moonbit_closure_t` type to represent closures +- Context structure contains the closure object itself + +### Comparison Function Implementation + +```{literalinclude} /sources/native-ffi/src/funcref_qsort_closure/stub.c +:language: c +:start-after: start closure comparison function +:end-before: end closure comparison function +``` + +Critical memory management: +1. **⚠️ Closure reference count critical technique**: `moonbit_incref(context->closure)` increments closure reference count + - **Important**: Since closure is the first parameter of adapter function, it consumes one reference when called + - Must execute `moonbit_incref` before each call, otherwise leads to use-after-free errors +2. **Parameter reference count**: Increment reference counts for both Point parameters respectively +3. **Three-parameter call**: Call adapter function, passing closure and two parameters + +### Main Sorting Function + +```{literalinclude} /sources/native-ffi/src/funcref_qsort_closure/stub.c +:language: c +:start-after: start closure qsort function +:end-before: end closure qsort function +``` + +Context setup: +- Save adapter function pointer +- Save closure object reference + +## Closure vs FuncRef Differences + +### FuncRef Characteristics: +- Must be closed functions (don't capture external variables) +- Represented as simple function pointers on C side +- Lower performance overhead + +### Closure Characteristics: +- Can capture external variables +- Require additional context data on C side +- Need more complex memory management + +## Test Case + +```{literalinclude} /sources/native-ffi/src/funcref_qsort_closure/top.mbt +:language: moonbit +:lines: 19-40 +``` + +Test highlights: + +1. **Variable capture**: Comparison function captures external `mut i` variable +2. **State statistics**: Modify `i` to count comparison operations +3. **Functionality verification**: Ensure sorting results are correct + +Note: The comment in the test mentions that `inspect` cannot be used inside closures due to error handling limitations. + +## Key Learning Points + +1. **Closure passing pattern**: Understand how to pass closures through adapter functions +2. **Memory management complexity**: Closures require more careful reference count management +3. **Performance trade-offs**: Closures provide greater flexibility but have additional runtime overhead +4. **Type system design**: MoonBit distinguishes between `FuncRef` and closures through the type system +5. **FFI design patterns**: Adapter pattern is the standard method for handling complex callbacks \ No newline at end of file diff --git a/next/example/native-ffi/funcref_register_callback.md b/next/example/native-ffi/funcref_register_callback.md new file mode 100644 index 00000000..c78fe25d --- /dev/null +++ b/next/example/native-ffi/funcref_register_callback.md @@ -0,0 +1,106 @@ +# Callback Registration Example + +```{admonition} ⚠️ Critical Technique: Closure First Parameter Reference Counting +:class: warning + +This example uses adapter function type `FuncRef[(() -> Unit) -> Unit]`, note that **closure is the first (and only) parameter**. + +**Important rule**: Before each call to this adapter function in C code, you must execute `moonbit_incref(closure)` on the closure, otherwise it will cause use-after-free errors. + +The example calls three times, so it needs three `moonbit_incref` calls. +``` + +This example demonstrates how to implement callback function mechanisms in MoonBit and how to properly manage closure lifetimes. + +## Overview + +This example implements a callback registration system that allows MoonBit functions to be called multiple times by C code. It showcases MoonBit closure runtime representation and memory management strategies. + +## MoonBit Closure Runtime Representation + +In the C backend, MoonBit closures are represented as `void*` type pointers: + +```{literalinclude} /sources/native-ffi/src/funcref_register_callback/stub.c +:language: c +:start-after: start moonbit closure definition +:end-before: end moonbit closure definition +``` + +This type definition illustrates how MoonBit closures are represented on the C side. All closure objects are passed through pointers. + +## FFI Function Declaration + +In MoonBit, we declare an external C function: + +```{literalinclude} /sources/native-ffi/src/funcref_register_callback/top.mbt +:language: moonbit +:start-after: start ffi declaration +:end-before: end ffi declaration +``` + +Key features explanation: + +1. **`#borrow` attribute**: Specifies that `call` and `closure` parameters use borrow semantics, avoiding manual reference count management +2. **⚠️ `FuncRef[(() -> Unit) -> Unit]`**: This is a function reference type + - **First parameter**: `() -> Unit` type closure + - **Function**: Accepts and calls a closure + - **Important**: Closure passed as first parameter, consuming one reference when called +3. **`() -> Unit`**: Type of callback function to register + +## C Implementation + +The C side implementation demonstrates how to properly handle MoonBit closure lifetimes: + +```{literalinclude} /sources/native-ffi/src/funcref_register_callback/stub.c +:language: c +:start-after: start register_callback definition +:end-before: end register_callback definition +``` + +### Memory Management Details + +1. **⚠️ Critical reference counting technique**: Need to call `moonbit_incref(closure)` before each closure call + - **Reason**: In `call(closure)`, closure as first parameter will be consumed by adapter function + - **Rule**: Must `moonbit_incref` before each call, otherwise closure is freed on second call + - **Example**: Three calls in code, so three `moonbit_incref` calls +2. **Calling convention**: `call(closure)` directly calls the passed function pointer, MoonBit compiler handles closure expansion and calling at compile time +3. **Multiple calls**: Example demonstrates how to call the same closure multiple times + +## Wrapper Function + +MoonBit provides a convenient wrapper function: + +```{literalinclude} /sources/native-ffi/src/funcref_register_callback/top.mbt +:language: moonbit +:start-after: start wrapper function +:end-before: end wrapper function +``` + +This wrapper function: + +1. Creates a `FuncRef` type adapter function `fn(f) { f() }` +2. Passes user-provided closure to C function +3. Hides underlying FFI complexity + +## Test Case + +The example includes a complete test case: + +```{literalinclude} /sources/native-ffi/src/funcref_register_callback/top.mbt +:language: moonbit +:start-after: start test case +:end-before: end test case +``` + +### Test Description + +1. **Variable capture**: Closures capture external variables `s1` and `s2`, demonstrating closure variable capture capability +2. **Multiple execution**: Each registered callback is executed 3 times +3. **State maintenance**: Uses `StringBuilder` to collect output, verifying correct callback execution + +## Key Learning Points + +1. **FuncRef vs Closure**: `FuncRef` type is for functions that don't capture variables, while closures can capture external variables +2. **Lifetime management**: Use `#borrow` attribute to simplify reference count management +3. **Runtime representation**: Understand MoonBit closure memory layout and representation on C side +4. **Calling convention**: Master correct closure calling and memory management patterns \ No newline at end of file diff --git a/next/example/native-ffi/index.md b/next/example/native-ffi/index.md new file mode 100644 index 00000000..dd258b06 --- /dev/null +++ b/next/example/native-ffi/index.md @@ -0,0 +1,18 @@ +# MoonBit Native FFI Examples + +This section demonstrates MoonBit's Native FFI (Foreign Function Interface) capabilities through practical examples, focusing on `FuncRef` type usage and C language interoperability. + +## Overview + +These examples showcase how to use MoonBit's `FuncRef` type for safe and efficient interoperability with C code. Each example demonstrates different patterns for passing MoonBit functions to C libraries. + +## Examples + +```{toctree} +:maxdepth: 1 + +funcref_register_callback +funcref_qsort +funcref_qsort_closure +funcref_map_inplace +``` diff --git a/next/sources/native-ffi/CMakeLists.txt b/next/sources/native-ffi/CMakeLists.txt new file mode 100644 index 00000000..699b4629 --- /dev/null +++ b/next/sources/native-ffi/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.10.0) +project(moonbit_cxx_ffi VERSION 0.1.0 LANGUAGES C CXX) + + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +file(TO_CMAKE_PATH $ENV{MOON_BIN} MOON_BIN) + +add_executable(main main.c) + +include_directories(${MOON_BIN}/../include) \ No newline at end of file diff --git a/next/sources/native-ffi/README.md b/next/sources/native-ffi/README.md new file mode 100644 index 00000000..b24f20b9 --- /dev/null +++ b/next/sources/native-ffi/README.md @@ -0,0 +1,3 @@ +# moonbit-community/native-ffi + +MoonBit native FFI examples diff --git a/next/sources/native-ffi/main.c b/next/sources/native-ffi/main.c new file mode 100644 index 00000000..96bad283 --- /dev/null +++ b/next/sources/native-ffi/main.c @@ -0,0 +1,4 @@ +#include + +int main(int argc, char *argv[]) { +} \ No newline at end of file diff --git a/next/sources/native-ffi/moon.mod.json b/next/sources/native-ffi/moon.mod.json new file mode 100644 index 00000000..0722e207 --- /dev/null +++ b/next/sources/native-ffi/moon.mod.json @@ -0,0 +1,11 @@ +{ + "name": "username/hello", + "version": "0.1.0", + "readme": "README.md", + "repository": "", + "license": "Apache-2.0", + "keywords": [], + "description": "", + "source": "src", + "preferred-target": "native" +} diff --git a/next/sources/native-ffi/src/funcref_map_inplace/funcref_map_inplace.mbti b/next/sources/native-ffi/src/funcref_map_inplace/funcref_map_inplace.mbti new file mode 100644 index 00000000..f6282630 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_map_inplace/funcref_map_inplace.mbti @@ -0,0 +1,22 @@ +// Generated using `moon info`, DON'T EDIT IT +package "username/hello/funcref_map_inplace" + +import( + "moonbitlang/core/quickcheck/splitmix" +) + +// Values + +// Errors + +// Types and methods +type Point +impl Compare for Point +impl Eq for Point +impl Show for Point +impl @moonbitlang/core/quickcheck.Arbitrary for Point + +// Type aliases + +// Traits + diff --git a/next/sources/native-ffi/src/funcref_map_inplace/moon.pkg.json b/next/sources/native-ffi/src/funcref_map_inplace/moon.pkg.json new file mode 100644 index 00000000..9bbe0128 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_map_inplace/moon.pkg.json @@ -0,0 +1,13 @@ +{ + "warn-list": "-1-2-3-4-5-6-9-28", + "targets": { + "top.mbt": ["native"] + }, + "link": { + "native": { + "cc-flags": "-fsanitize=address -fsanitize=undefined", + "stub-cc-flags": "-fsanitize=address -fsanitize=undefined" + } + }, + "native-stub": ["stub.c"] +} diff --git a/next/sources/native-ffi/src/funcref_map_inplace/stub.c b/next/sources/native-ffi/src/funcref_map_inplace/stub.c new file mode 100644 index 00000000..221e0fc1 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_map_inplace/stub.c @@ -0,0 +1,26 @@ +#include + +// start map inplace types +typedef void *moonbit_closure_t; +typedef void *moonbit_point_t; +// end map inplace types + +// start map inplace implementation +void ffi_map_inplace(moonbit_point_t *xs, + moonbit_point_t (*call)(moonbit_closure_t, + moonbit_point_t), + moonbit_closure_t closure) { + int len = Moonbit_array_length(xs); + + for (int i = 0; i < len; ++i) { + // CRITICAL: increment reference count before each call + // because closure is the first parameter and will be consumed + moonbit_incref(closure); + xs[i] = call(closure, xs[i]); + + // CRITICAL: again, increment before second call + moonbit_incref(closure); + xs[i] = call(closure, xs[i]); + } +} +// end map inplace implementation \ No newline at end of file diff --git a/next/sources/native-ffi/src/funcref_map_inplace/top.mbt b/next/sources/native-ffi/src/funcref_map_inplace/top.mbt new file mode 100644 index 00000000..27574861 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_map_inplace/top.mbt @@ -0,0 +1,53 @@ +///| +struct Point { + x : Int + y : Int +} derive(Show, Eq, Compare, @quickcheck.Arbitrary) + +///| +// start map inplace ffi declaration +#borrow(xs, call, closure) +extern "c" fn ffi_map_inplace( + xs : FixedArray[Point], + call : FuncRef[((Point) -> Point, Point) -> Point], + closure : (Point) -> Point, +) = "ffi_map_inplace" +// end map inplace ffi declaration + +///| +// start map inplace wrapper +fn map_inplace(xs : FixedArray[Point], closure : (Point) -> Point) -> Unit { + ffi_map_inplace(xs, fn(f, x) { f(x) }, closure) +} +// end map inplace wrapper + +///| +test "map_inplace functionality" { + let xs : FixedArray[Point] = @quickcheck.samples(4) |> FixedArray::from_array + let mut i = 0 + fn f(x) { + // Note: i increments on each call, but we can't use inspect inside closure + i += 1 + x + } + + inspect(i, content="0") + map_inplace(xs, f) + inspect( + xs, + content="[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}]", + ) + inspect(i, content="8") + map_inplace(xs, f) + inspect( + xs, + content="[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}]", + ) + inspect(i, content="16") + map_inplace(xs, f) + inspect( + xs, + content="[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}]", + ) + inspect(i, content="24") +} diff --git a/next/sources/native-ffi/src/funcref_qsort/funcref_qsort.mbti b/next/sources/native-ffi/src/funcref_qsort/funcref_qsort.mbti new file mode 100644 index 00000000..e9fe9500 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_qsort/funcref_qsort.mbti @@ -0,0 +1,22 @@ +// Generated using `moon info`, DON'T EDIT IT +package "username/hello/funcref_qsort" + +import( + "moonbitlang/core/quickcheck/splitmix" +) + +// Values + +// Errors + +// Types and methods +type Point +impl Compare for Point +impl Eq for Point +impl Show for Point +impl @moonbitlang/core/quickcheck.Arbitrary for Point + +// Type aliases + +// Traits + diff --git a/next/sources/native-ffi/src/funcref_qsort/moon.pkg.json b/next/sources/native-ffi/src/funcref_qsort/moon.pkg.json new file mode 100644 index 00000000..ae68ce29 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_qsort/moon.pkg.json @@ -0,0 +1,13 @@ +{ + "warn-list": "-1-2-3-4-5-6-9-28", + "targets": { + "top.mbt": ["native"] + }, + "native-stub": ["stub.c"], + "link": { + "native": { + "cc-flags": "-fsanitize=address -fsanitize=undefined", + "stub-cc-flags": "-fsanitize=address -fsanitize=undefined" + } + } +} diff --git a/next/sources/native-ffi/src/funcref_qsort/stub.c b/next/sources/native-ffi/src/funcref_qsort/stub.c new file mode 100644 index 00000000..d42a8b34 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_qsort/stub.c @@ -0,0 +1,58 @@ +#include +#define __USE_GNU // to order to use qsort_r +#include + +// start type definitions +typedef void *moonbit_ref_t; +typedef moonbit_ref_t moonbit_point_t; +typedef moonbit_point_t *moonbit_fixedarray_point_t; + +struct comp_context { + int (*call)(moonbit_point_t lhs, moonbit_point_t rhs); +}; +// end type definitions + +// Currently need fresh renaming for all symbols +// https://github.com/moonbitlang/moon/issues/969 + +// start cross platform comparison function +#if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__) +#include +int fq_comp(struct comp_context *context, moonbit_point_t *lhs, + moonbit_point_t *rhs) +#else +#define __USE_GNU // to order to use qsort_r +#include +int fq_comp(moonbit_point_t *lhs, moonbit_point_t *rhs, + struct comp_context *context) +#endif +{ + moonbit_incref(*lhs); + moonbit_incref(*rhs); + int res = context->call(*lhs, *rhs); + return res; +} +// end cross platform comparison function + +// start main qsort function +// https://en.cppreference.com/w/c/algorithm/qsort +// both glibc and Windows CRT doesn't support ISO C qsort_s +void fq_ffi_qsort(moonbit_fixedarray_point_t xs, + int (*call)(moonbit_point_t lhs, moonbit_point_t rhs)) { + size_t count = Moonbit_array_length(xs); + size_t elem_size = sizeof(moonbit_point_t); + + struct comp_context context; + context.call = call; +#if defined(_WIN32) || defined(_WIN64) + // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/qsort-s?view=msvc-170 + qsort_s(xs, count, elem_size, (void *)fq_comp, &context); +#elif defined(__APPLE__) + // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/qsort_r.3.html + qsort_r(xs, count, elem_size, &context, (void *)fq_comp); +#else + // https://www.man7.org/linux/man-pages/man3/qsort.3.html + qsort_r(xs, count, elem_size, (void *)fq_comp, &context); +#endif +} +// end main qsort function \ No newline at end of file diff --git a/next/sources/native-ffi/src/funcref_qsort/top.mbt b/next/sources/native-ffi/src/funcref_qsort/top.mbt new file mode 100644 index 00000000..e282a49e --- /dev/null +++ b/next/sources/native-ffi/src/funcref_qsort/top.mbt @@ -0,0 +1,42 @@ +///| +// start point definition +struct Point { + x : Int + y : Int +} derive(@quickcheck.Arbitrary, Compare, Eq, Show) +// end point definition + +///| +// start qsort ffi declaration +#borrow(xs, comp) +extern "c" fn qsort( + xs : FixedArray[Point], + comp : FuncRef[(Point, Point) -> Int], +) = "fq_ffi_qsort" +// end qsort ffi declaration + +///| +test "qsort functionality" { + let xs : FixedArray[Point] = @quickcheck.samples(10) |> FixedArray::from_array + let ys = xs.copy() + let comp : FuncRef[(Point, Point) -> Int] = fn(x, y) { x.compare(y) } + inspect( + xs, + content="[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}, {x: -2, y: 2}, {x: 0, y: 2}, {x: -5, y: -2}, {x: 2, y: 3}, {x: 3, y: 7}, {x: 1, y: 0}]", + ) + inspect( + ys, + content="[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}, {x: -2, y: 2}, {x: 0, y: 2}, {x: -5, y: -2}, {x: 2, y: 3}, {x: 3, y: 7}, {x: 1, y: 0}]", + ) + xs |> qsort(comp) + ys.sort() + inspect( + xs, + content="[{x: -5, y: -2}, {x: -2, y: 2}, {x: 0, y: -1}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 2}, {x: 1, y: 0}, {x: 2, y: 0}, {x: 2, y: 3}, {x: 3, y: 7}]", + ) + inspect( + ys, + content="[{x: -5, y: -2}, {x: -2, y: 2}, {x: 0, y: -1}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 2}, {x: 1, y: 0}, {x: 2, y: 0}, {x: 2, y: 3}, {x: 3, y: 7}]", + ) + assert_eq(xs, ys) +} diff --git a/next/sources/native-ffi/src/funcref_qsort_closure/funcref_qsort_closure.mbti b/next/sources/native-ffi/src/funcref_qsort_closure/funcref_qsort_closure.mbti new file mode 100644 index 00000000..3eb0faf4 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_qsort_closure/funcref_qsort_closure.mbti @@ -0,0 +1,22 @@ +// Generated using `moon info`, DON'T EDIT IT +package "username/hello/funcref_qsort_closure" + +import( + "moonbitlang/core/quickcheck/splitmix" +) + +// Values + +// Errors + +// Types and methods +type Point +impl Compare for Point +impl Eq for Point +impl Show for Point +impl @moonbitlang/core/quickcheck.Arbitrary for Point + +// Type aliases + +// Traits + diff --git a/next/sources/native-ffi/src/funcref_qsort_closure/moon.pkg.json b/next/sources/native-ffi/src/funcref_qsort_closure/moon.pkg.json new file mode 100644 index 00000000..ae68ce29 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_qsort_closure/moon.pkg.json @@ -0,0 +1,13 @@ +{ + "warn-list": "-1-2-3-4-5-6-9-28", + "targets": { + "top.mbt": ["native"] + }, + "native-stub": ["stub.c"], + "link": { + "native": { + "cc-flags": "-fsanitize=address -fsanitize=undefined", + "stub-cc-flags": "-fsanitize=address -fsanitize=undefined" + } + } +} diff --git a/next/sources/native-ffi/src/funcref_qsort_closure/stub.c b/next/sources/native-ffi/src/funcref_qsort_closure/stub.c new file mode 100644 index 00000000..8e3482cb --- /dev/null +++ b/next/sources/native-ffi/src/funcref_qsort_closure/stub.c @@ -0,0 +1,67 @@ +#include +#define __USE_GNU // to order to use qsort_r +#include + +// start closure type definitions +typedef void *moonbit_ref_t; +typedef moonbit_ref_t moonbit_point_t; +typedef moonbit_point_t *moonbit_fixedarray_point_t; + +typedef void* moonbit_closure_t; + +struct comp_context { + int (*call)(moonbit_closure_t closure,moonbit_point_t lhs, moonbit_point_t rhs); + moonbit_closure_t closure; +}; +// end closure type definitions + +// Currently need fresh renaming for all symbols +// https://github.com/moonbitlang/moon/issues/969 + + +// start closure comparison function +#if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__) +#include +int fqc_comp(struct comp_context *context, moonbit_point_t *lhs, + moonbit_point_t *rhs) +#else +#define __USE_GNU // to order to use qsort_r +#include +int fqc_comp(moonbit_point_t *lhs, moonbit_point_t *rhs, + struct comp_context *context) +#endif +{ + // CRITICAL: increment closure ref count because it's the first parameter + // The adapter function will consume this reference when called + moonbit_incref(context->closure); + moonbit_incref(*lhs); + moonbit_incref(*rhs); + int res = context->call(context->closure, *lhs, *rhs); + return res; +} +// end closure comparison function + +// start closure qsort function +// https://en.cppreference.com/w/c/algorithm/qsort +// both glibc and Windows CRT doesn't support ISO C qsort_s +void fqc_ffi_qsort(moonbit_fixedarray_point_t xs, + int (*call)(moonbit_closure_t closure,moonbit_point_t lhs, moonbit_point_t rhs), + moonbit_closure_t closure) { + size_t count = Moonbit_array_length(xs); + size_t elem_size = sizeof(moonbit_point_t); + + struct comp_context context; + context.call = call; + context.closure = closure; +#if defined(_WIN32) || defined(_WIN64) + // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/qsort-s?view=msvc-170 + qsort_s(xs, count, elem_size, (void *)fqc_comp, &context); +#elif defined(__APPLE__) + // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/qsort_r.3.html + qsort_r(xs, count, elem_size, &context, (void *)fqc_comp); +#else + // https://www.man7.org/linux/man-pages/man3/qsort.3.html + qsort_r(xs, count, elem_size, (void *)fqc_comp, &context); +#endif +} +// end closure qsort function \ No newline at end of file diff --git a/next/sources/native-ffi/src/funcref_qsort_closure/top.mbt b/next/sources/native-ffi/src/funcref_qsort_closure/top.mbt new file mode 100644 index 00000000..43d776ac --- /dev/null +++ b/next/sources/native-ffi/src/funcref_qsort_closure/top.mbt @@ -0,0 +1,54 @@ +///| +struct Point { + x : Int + y : Int +} derive(@quickcheck.Arbitrary, Compare, Eq, Show) + +///| +// start closure qsort ffi declaration +#borrow(xs, comp, closure) +extern "c" fn ffi_qsort( + xs : FixedArray[Point], + comp : FuncRef[((Point, Point) -> Int, Point, Point) -> Int], + closure : (Point, Point) -> Int, +) = "fqc_ffi_qsort" +// end closure qsort ffi declaration + +///| +// start closure qsort wrapper +fn qsort(xs : FixedArray[Point], comp : (Point, Point) -> Int) -> Unit { + ffi_qsort(xs, fn(f, x, y) { f(x, y) }, comp) +} +// end closure qsort wrapper + +///| +test "qsort_closure functionality" { + let xs : FixedArray[Point] = @quickcheck.samples(10) |> FixedArray::from_array + let ys = xs.copy() + let mut i = 0 + let comp : (Point, Point) -> Int = fn(x, y) { + i += 1 + // Note: can't use inspect inside closure due to error handling + x.compare(y) + } + inspect( + xs, + content="[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}, {x: -2, y: 2}, {x: 0, y: 2}, {x: -5, y: -2}, {x: 2, y: 3}, {x: 3, y: 7}, {x: 1, y: 0}]", + ) + inspect( + ys, + content="[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}, {x: -2, y: 2}, {x: 0, y: 2}, {x: -5, y: -2}, {x: 2, y: 3}, {x: 3, y: 7}, {x: 1, y: 0}]", + ) + inspect(i, content="0") + xs |> qsort(comp) + ys.sort() + inspect( + xs, + content="[{x: -5, y: -2}, {x: -2, y: 2}, {x: 0, y: -1}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 2}, {x: 1, y: 0}, {x: 2, y: 0}, {x: 2, y: 3}, {x: 3, y: 7}]", + ) + inspect( + ys, + content="[{x: -5, y: -2}, {x: -2, y: 2}, {x: 0, y: -1}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 2}, {x: 1, y: 0}, {x: 2, y: 0}, {x: 2, y: 3}, {x: 3, y: 7}]", + ) + assert_eq(xs, ys) +} diff --git a/next/sources/native-ffi/src/funcref_register_callback/funcref_register_callback.mbti b/next/sources/native-ffi/src/funcref_register_callback/funcref_register_callback.mbti new file mode 100644 index 00000000..0f86cdb1 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_register_callback/funcref_register_callback.mbti @@ -0,0 +1,13 @@ +// Generated using `moon info`, DON'T EDIT IT +package "username/hello/funcref_register_callback" + +// Values + +// Errors + +// Types and methods + +// Type aliases + +// Traits + diff --git a/next/sources/native-ffi/src/funcref_register_callback/moon.pkg.json b/next/sources/native-ffi/src/funcref_register_callback/moon.pkg.json new file mode 100644 index 00000000..ae68ce29 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_register_callback/moon.pkg.json @@ -0,0 +1,13 @@ +{ + "warn-list": "-1-2-3-4-5-6-9-28", + "targets": { + "top.mbt": ["native"] + }, + "native-stub": ["stub.c"], + "link": { + "native": { + "cc-flags": "-fsanitize=address -fsanitize=undefined", + "stub-cc-flags": "-fsanitize=address -fsanitize=undefined" + } + } +} diff --git a/next/sources/native-ffi/src/funcref_register_callback/stub.c b/next/sources/native-ffi/src/funcref_register_callback/stub.c new file mode 100644 index 00000000..b704784f --- /dev/null +++ b/next/sources/native-ffi/src/funcref_register_callback/stub.c @@ -0,0 +1,24 @@ +#include + +// start moonbit closure definition +typedef void* moonbit_closure_t; +// end moonbit closure definition + +// start register_callback definition +// +// `call` indicates how to consume `closure` +void register_callback(void (*call)(moonbit_closure_t), moonbit_closure_t closure) { + // CRITICAL: increment ref count before each call + // because closure is the first (and only) parameter to the adapter function + moonbit_incref(closure); + call(closure); // call closure directly + + // CRITICAL: increment again before second call + moonbit_incref(closure); + call(closure); + + // CRITICAL: increment again before third call + moonbit_incref(closure); + call(closure); +} +// end register_callback definition \ No newline at end of file diff --git a/next/sources/native-ffi/src/funcref_register_callback/top.mbt b/next/sources/native-ffi/src/funcref_register_callback/top.mbt new file mode 100644 index 00000000..f58fa140 --- /dev/null +++ b/next/sources/native-ffi/src/funcref_register_callback/top.mbt @@ -0,0 +1,48 @@ +///| +// start ffi declaration +#borrow(call, closure) +extern "c" fn ffi_register_callback( + call : FuncRef[(() -> Unit) -> Unit], + closure : () -> Unit, +) = "register_callback" +// end ffi declaration + +///| +// start wrapper function +fn register_callback(closure : () -> Unit) -> Unit { + ffi_register_callback( + fn(f) { f() }, // moonc know how to consume `closure` + closure, + ) +} +// end wrapper function + +///| +// start test case +test "register_callback functionality" { + let output = StringBuilder::new() + let s1 = "moonbit" + inspect(s1, content="moonbit") // capture free variables before registering + register_callback(fn() { + output.write_string(s1) + output.write_char('\n') + }) + let s2 = "apple" + register_callback(fn() { + output.write_string(s2) + output.write_char('\n') + }) + inspect( + output, + content=( + #|moonbit + #|moonbit + #|moonbit + #|apple + #|apple + #|apple + #| + ), + ) +} +// end test case From 5e44e5430be69d26e147d01b87c510994009192f Mon Sep 17 00:00:00 2001 From: illusory0x0 Date: Thu, 21 Aug 2025 15:30:37 +0800 Subject: [PATCH 2/2] Update translation template --- next/locales/zh_CN/LC_MESSAGES/example.po | 1492 +++++++++++++- next/locales/zh_CN/LC_MESSAGES/language.po | 2074 +++++++++++++++----- 2 files changed, 3116 insertions(+), 450 deletions(-) diff --git a/next/locales/zh_CN/LC_MESSAGES/example.po b/next/locales/zh_CN/LC_MESSAGES/example.po index b85c74ac..6ee64cce 100644 --- a/next/locales/zh_CN/LC_MESSAGES/example.po +++ b/next/locales/zh_CN/LC_MESSAGES/example.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: MoonBit Document \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-08-13 13:51+0800\n" +"POT-Creation-Date: 2025-08-21 15:28+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -771,6 +771,7 @@ msgid "" msgstr "堆:这是存储表达式图和与超组合子对应的指令序列的地方。" #: ../../example/gmachine/gmachine-1.md:251 +#, python-format msgid "" "// Use the struct tuple to encapsulate an address type.\n" "struct Addr(Int) derive(Eq, Show)\n" @@ -2876,7 +2877,7 @@ msgstr "" "在本文中,我们将深入研究惰性求值机制,全面研究其原理和实现方法,然后探索如何在 " "[MoonBit](https://www.moonbitlang.com/) 中实现 Haskell 的求值语义。" -#: ../../example/index.md:1 +#: ../../example/index.md:1 ../../example/native-ffi/index.md:9 msgid "Examples" msgstr "例子" @@ -4729,6 +4730,1493 @@ msgstr "" "除了默认的 diff 算法之外,Git 还提供了另一种 diff 算法,称为 `patience diff`。它在方法上与 Myers diff " "有很大不同,有时会产生更可读的 diff 结果。" +#: ../../example/native-ffi/funcref_map_inplace.md:1 +msgid "In-place Map Transformation Example" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:3 +#: ../../example/native-ffi/funcref_qsort_closure.md:3 +#: ../../example/native-ffi/funcref_register_callback.md:3 +msgid "⚠️ Critical Technique: Closure First Parameter Reference Counting" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:6 +msgid "" +"This example uses adapter function type `FuncRef[((Point) -> Point, " +"Point) -> Point]`, note that **closure is the first parameter**." +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:8 +#: ../../example/native-ffi/funcref_qsort_closure.md:8 +#: ../../example/native-ffi/funcref_register_callback.md:8 +msgid "" +"**Important rule**: Before each call to this adapter function in C code, " +"you must execute `moonbit_incref(closure)` on the closure, otherwise it " +"will cause use-after-free errors." +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:10 +msgid "" +"In the example, each array element is called twice, so two " +"`moonbit_incref` calls are needed." +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:13 +msgid "" +"This example demonstrates how to implement in-place array transformation " +"operations, showcasing MoonBit closure usage in array element " +"transformations." +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:15 +#: ../../example/native-ffi/funcref_qsort.md:5 +#: ../../example/native-ffi/funcref_qsort_closure.md:15 +#: ../../example/native-ffi/funcref_register_callback.md:15 +#: ../../example/native-ffi/index.md:5 +#, fuzzy +msgid "Overview" +msgstr "G-Machine 概述" + +#: ../../example/native-ffi/funcref_map_inplace.md:17 +msgid "" +"This example implements a `map_inplace` function that can apply " +"transformation functions to each element in an array. Unlike the previous" +" sorting examples, this focuses on element transformation rather than " +"comparison operations." +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:19 +#: ../../example/native-ffi/funcref_qsort.md:25 +#: ../../example/native-ffi/funcref_qsort_closure.md:23 +#: ../../example/native-ffi/funcref_register_callback.md:31 +msgid "FFI Function Declaration" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:21 +#: ../../example/native-ffi/funcref_qsort.md:27 +msgid "MoonBit side FFI declaration:" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:23 +msgid "" +"#borrow(xs, call, closure)\n" +"extern \"c\" fn ffi_map_inplace(\n" +" xs : FixedArray[Point],\n" +" call : FuncRef[((Point) -> Point, Point) -> Point],\n" +" closure : (Point) -> Point,\n" +") = \"ffi_map_inplace\"\n" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:29 +msgid "Function parameter analysis:" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:31 +msgid "**`xs : FixedArray[Point]`**: Array to be transformed" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:32 +msgid "" +"**⚠️ `call : FuncRef[((Point) -> Point, Point) -> Point]`**: Adapter " +"function type" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:33 +msgid "**Key**: First parameter `(Point) -> Point` is the closure itself" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:34 +msgid "Second parameter `Point` is the input value passed to the closure" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:35 +msgid "Return value `Point` is the execution result of the closure" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:36 +msgid "**`closure : (Point) -> Point`**: Actual transformation closure" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:38 +#: ../../example/native-ffi/funcref_qsort_closure.md:47 +#: ../../example/native-ffi/funcref_register_callback.md:69 +msgid "Wrapper Function" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:40 +msgid "" +"fn map_inplace(xs : FixedArray[Point], closure : (Point) -> Point) -> " +"Unit {\n" +" ffi_map_inplace(xs, fn(f, x) { f(x) }, closure)\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:46 +msgid "This wrapper function provides a clean interface, hiding FFI complexity." +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:48 +#: ../../example/native-ffi/funcref_qsort.md:41 +#: ../../example/native-ffi/funcref_qsort_closure.md:62 +#, fuzzy +msgid "C Implementation Details" +msgstr "代码实现" + +#: ../../example/native-ffi/funcref_map_inplace.md:50 +#, fuzzy +msgid "Type Definitions" +msgstr "基础定义" + +#: ../../example/native-ffi/funcref_map_inplace.md:52 +msgid "" +"typedef void *moonbit_closure_t;\n" +"typedef void *moonbit_point_t;\n" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:58 +msgid "Simplified type definitions:" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:59 +msgid "`moonbit_closure_t`: Represents MoonBit closures" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:60 +msgid "`moonbit_point_t`: Represents Point objects" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:62 +#, fuzzy +msgid "Core Implementation" +msgstr "代码实现" + +#: ../../example/native-ffi/funcref_map_inplace.md:64 +msgid "" +"void ffi_map_inplace(moonbit_point_t *xs,\n" +" moonbit_point_t (*call)(moonbit_closure_t,\n" +" moonbit_point_t),\n" +" moonbit_closure_t closure) {\n" +" int len = Moonbit_array_length(xs);\n" +"\n" +" for (int i = 0; i < len; ++i) {\n" +" // CRITICAL: increment reference count before each call\n" +" // because closure is the first parameter and will be consumed\n" +" moonbit_incref(closure);\n" +" xs[i] = call(closure, xs[i]);\n" +" \n" +" // CRITICAL: again, increment before second call\n" +" moonbit_incref(closure);\n" +" xs[i] = call(closure, xs[i]);\n" +" }\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:70 +#, fuzzy +msgid "Implementation Detail Analysis" +msgstr "实现" + +#: ../../example/native-ffi/funcref_map_inplace.md:72 +msgid "" +"**Array length retrieval**: Use `Moonbit_array_length(xs)` to get array " +"length" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:73 +msgid "**Loop processing**: Iterate through each element in the array" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:74 +msgid "" +"**Double call**: Each element is called by transformation function twice " +"(for demonstration)" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:75 +msgid "" +"**⚠️ Critical reference count management**: Need " +"`moonbit_incref(closure)` before each call" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:76 +msgid "" +"**Reason**: Closure as first parameter of adapter function consumes one " +"reference when called" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:77 +msgid "" +"**Must**: Execute `moonbit_incref(closure)` before each `call(closure, " +"xs[i])`" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:78 +msgid "" +"**Consequence**: Forgetting to increment reference count leads to use-" +"after-free or memory leaks" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:80 +msgid "Memory Management Points" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:82 +msgid "**Closure lifetime**: Increment closure reference count before each call" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:83 +msgid "" +"**In-place modification**: Directly modify array elements `xs[i] = " +"call(closure, xs[i])`" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:84 +msgid "" +"**No manual release**: Due to `#borrow` attribute, MoonBit compiler-" +"generated code automatically manages memory" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:86 +msgid "Test Case Analysis" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "" +"fn map_inplace(xs : FixedArray[Point], closure : (Point) -> Point) -> " +"Unit {\n" +" ffi_map_inplace(xs, fn(f, x) { f(x) }, closure)\n" +"}\n" +"// end map inplace wrapper\n" +"\n" +"///|\n" +"test \"map_inplace functionality\" {\n" +" let xs : FixedArray[Point] = @quickcheck.samples(4) |> " +"FixedArray::from_array\n" +" let mut i = 0\n" +" fn f(x) {\n" +" // Note: i increments on each call, but we can't use inspect inside " +"closure\n" +" i += 1\n" +" x\n" +" }\n" +"\n" +" inspect(i, content=\"0\")\n" +" map_inplace(xs, f)\n" +" inspect(\n" +" xs,\n" +" content=\"[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: " +"0}]\",\n" +" )\n" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:93 +msgid "Test Highlights" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:95 +msgid "" +"**Counter closure**: Transformation function captures external variable " +"`i` to count call times" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:96 +msgid "" +"**Identity transformation**: Function returns input Point unchanged, " +"focus is on verifying call count" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:97 +msgid "**Multiple call verification**:" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:98 +msgid "After first call: `i = 8` (4 elements × 2 calls each)" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:99 +msgid "After second call: `i = 16`" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:100 +msgid "After third call: `i = 24`" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:102 +msgid "Call Count Calculation" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:104 +msgid "For an array of length 4:" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:105 +msgid "Each element is transformed 2 times in one `map_inplace` call" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:106 +msgid "Total: 4 × 2 = 8 function calls" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:107 +msgid "Three `map_inplace` calls: 8 × 3 = 24 times" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:109 +msgid "Design Pattern Analysis" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:111 +msgid "Adapter Pattern Application" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:113 +msgid "ffi_map_inplace(xs, fn(f, x) { f(x) }, closure)\n" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:117 +msgid "The `fn(f, x) { f(x) }` here is an adapter function that:" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:118 +msgid "Receives closure `f` and parameter `x`" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:119 +msgid "Calls closure and returns result" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:120 +msgid "Bridges MoonBit closures and C function pointers" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:122 +msgid "FFI Design Principles" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:124 +msgid "**Type safety**: Ensure correct function signatures through type system" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:125 +msgid "**Memory safety**: Use `#borrow` to simplify lifetime management" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:126 +msgid "" +"**Performance optimization**: In-place modification avoids additional " +"memory allocation" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:127 +msgid "" +"**Interface simplification**: Provide clean user interfaces through " +"wrapper functions" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:129 +msgid "Comparison with Other Examples" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +#, fuzzy +msgid "Example" +msgstr "例子" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Operation Type" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Closure Features" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +#, fuzzy +msgid "C Implementation Complexity" +msgstr "代码实现" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "register_callback" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Callback registration" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Multiple calls" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Simple" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "qsort" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Comparison sorting" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Returns integer" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Medium (cross-platform)" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "qsort_closure" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +#, fuzzy +msgid "Variable capture" +msgstr "自由变量与变量捕获" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Medium" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "map_inplace" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +#, fuzzy +msgid "Element transformation" +msgstr "实现" + +#: ../../example/native-ffi/funcref_map_inplace.md:88 +msgid "Returns object" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:138 +#: ../../example/native-ffi/funcref_qsort.md:102 +#: ../../example/native-ffi/funcref_qsort_closure.md:130 +#: ../../example/native-ffi/funcref_register_callback.md:101 +msgid "Key Learning Points" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:140 +msgid "" +"**In-place operation pattern**: Understand how to implement efficient in-" +"place array operations through FFI" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:141 +msgid "" +"**Object return handling**: Master how to handle closures that return " +"MoonBit objects" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:142 +msgid "" +"**Counter pattern**: Learn how to monitor execution through closure-" +"captured state" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:143 +msgid "" +"**Performance considerations**: Understand performance advantages of in-" +"place operations compared to creating new arrays" +msgstr "" + +#: ../../example/native-ffi/funcref_map_inplace.md:144 +msgid "" +"**FFI design best practices**: Understand core principles of FFI " +"interface design through this simple example" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:1 +msgid "Quick Sort with Comparison Function Example" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:3 +msgid "" +"This example demonstrates how to pass MoonBit comparison functions to the" +" C standard library's `qsort` function, showcasing `FuncRef` type usage " +"in practical algorithms." +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:7 +msgid "" +"This example sorts MoonBit's `FixedArray[Point]` by calling the C " +"standard library's `qsort_r` function, demonstrating:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:9 +msgid "How to handle different `qsort_r` signatures across different platforms" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:10 +msgid "Using `FuncRef` type as comparison functions" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:11 +msgid "Cross-platform compatibility handling" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:13 +#, fuzzy +msgid "Data Structure Definition" +msgstr "基础定义" + +#: ../../example/native-ffi/funcref_qsort.md:15 +msgid "First, define the `Point` structure used for sorting:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:17 +msgid "" +"struct Point {\n" +" x : Int\n" +" y : Int\n" +"} derive(@quickcheck.Arbitrary, Compare, Eq, Show)\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:23 +msgid "" +"The `Point` structure derives multiple traits, including `Compare`, " +"allowing us to directly use the `compare` method for comparison." +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:29 +msgid "" +"#borrow(xs, comp)\n" +"extern \"c\" fn qsort(\n" +" xs : FixedArray[Point],\n" +" comp : FuncRef[(Point, Point) -> Int],\n" +") = \"fq_ffi_qsort\"\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:35 +msgid "Key features:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:37 +msgid "**`#borrow` attribute**: Avoids manual reference count management" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:38 +msgid "**`FixedArray[Point]`**: Represented as `Point*` on the C side" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:39 +msgid "" +"**`FuncRef[(Point, Point) -> Int]`**: Comparison function type, returns " +"integer indicating comparison result" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:43 +#: ../../example/native-ffi/funcref_qsort_closure.md:64 +msgid "Type Definitions and Context Structure" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:45 +msgid "" +"typedef void *moonbit_ref_t;\n" +"typedef moonbit_ref_t moonbit_point_t;\n" +"typedef moonbit_point_t *moonbit_fixedarray_point_t;\n" +"\n" +"struct comp_context {\n" +" int (*call)(moonbit_point_t lhs, moonbit_point_t rhs);\n" +"};\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:51 +#, fuzzy +msgid "These type definitions:" +msgstr "基础定义" + +#: ../../example/native-ffi/funcref_qsort.md:52 +msgid "`moonbit_point_t`: C representation of MoonBit Point objects" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:53 +msgid "`moonbit_fixedarray_point_t`: C representation of Point arrays" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:54 +msgid "`comp_context`: Context structure wrapping comparison functions" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:56 +msgid "Cross-platform Comparison Function" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:58 +msgid "" +"Due to different `qsort_r` function signatures on different platforms, " +"conditional compilation is needed:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:60 +msgid "" +"#if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__)\n" +"#include \n" +"int fq_comp(struct comp_context *context, moonbit_point_t *lhs,\n" +" moonbit_point_t *rhs)\n" +"#else\n" +"#define __USE_GNU // to order to use qsort_r\n" +"#include \n" +"int fq_comp(moonbit_point_t *lhs, moonbit_point_t *rhs,\n" +" struct comp_context *context)\n" +"#endif\n" +"{\n" +" moonbit_incref(*lhs);\n" +" moonbit_incref(*rhs);\n" +" int res = context->call(*lhs, *rhs);\n" +" return res;\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:66 +msgid "Memory Management" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:68 +msgid "In the comparison function:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:69 +msgid "" +"**Reference count increment**: Call `moonbit_incref` to increase " +"parameter reference counts" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:70 +msgid "" +"**Function call**: Call MoonBit comparison function through function " +"pointer" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:71 +msgid "" +"**Automatic cleanup**: Due to `#borrow` usage, MoonBit compiler-generated" +" code automatically handles reference counting" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:73 +#: ../../example/native-ffi/funcref_qsort_closure.md:91 +msgid "Main Sorting Function" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:75 +msgid "" +"// https://en.cppreference.com/w/c/algorithm/qsort\n" +"// both glibc and Windows CRT doesn't support ISO C qsort_s\n" +"void fq_ffi_qsort(moonbit_fixedarray_point_t xs,\n" +" int (*call)(moonbit_point_t lhs, moonbit_point_t rhs)) {\n" +" size_t count = Moonbit_array_length(xs);\n" +" size_t elem_size = sizeof(moonbit_point_t);\n" +"\n" +" struct comp_context context;\n" +" context.call = call;\n" +"#if defined(_WIN32) || defined(_WIN64)\n" +" // https://learn.microsoft.com/en-us/cpp/c-runtime-" +"library/reference/qsort-s?view=msvc-170\n" +" qsort_s(xs, count, elem_size, (void *)fq_comp, &context);\n" +"#elif defined(__APPLE__)\n" +" // " +"https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/qsort_r.3.html" +"\n" +" qsort_r(xs, count, elem_size, &context, (void *)fq_comp);\n" +"#else\n" +" // https://www.man7.org/linux/man-pages/man3/qsort.3.html\n" +" qsort_r(xs, count, elem_size, (void *)fq_comp, &context);\n" +"#endif\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:81 +msgid "Cross-platform Compatibility" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:83 +msgid "Different platforms use different sorting functions:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:84 +msgid "**Windows**: Uses `qsort_s`" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:85 +msgid "**macOS**: Uses `qsort_r` (BSD style)" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:86 +msgid "**Linux**: Uses `qsort_r` (GNU style)" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:88 +#: ../../example/native-ffi/funcref_qsort_closure.md:115 +#: ../../example/native-ffi/funcref_register_callback.md:85 +msgid "Test Case" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:90 +msgid "" +" comp : FuncRef[(Point, Point) -> Int],\n" +") = \"fq_ffi_qsort\"\n" +"// end qsort ffi declaration\n" +"\n" +"///|\n" +"test \"qsort functionality\" {\n" +" let xs : FixedArray[Point] = @quickcheck.samples(10) |> " +"FixedArray::from_array\n" +" let ys = xs.copy()\n" +" let comp : FuncRef[(Point, Point) -> Int] = fn(x, y) { x.compare(y) }\n" +" inspect(\n" +" xs,\n" +" content=\"[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}, " +"{x: -2, y: 2}, {x: 0, y: 2}, {x: -5, y: -2}, {x: 2, y: 3}, {x: 3, y: 7}, " +"{x: 1, y: 0}]\",\n" +" )\n" +" inspect(\n" +" ys,\n" +" content=\"[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}, " +"{x: -2, y: 2}, {x: 0, y: 2}, {x: -5, y: -2}, {x: 2, y: 3}, {x: 3, y: 7}, " +"{x: 1, y: 0}]\",\n" +" )\n" +" xs |> qsort(comp)\n" +" ys.sort()\n" +" inspect(\n" +" xs,\n" +" content=\"[{x: -5, y: -2}, {x: -2, y: 2}, {x: 0, y: -1}, {x: 0, y: " +"0}, {x: 0, y: 0}, {x: 0, y: 2}, {x: 1, y: 0}, {x: 2, y: 0}, {x: 2, y: 3}," +" {x: 3, y: 7}]\",\n" +" )\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:95 +msgid "Test flow:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:97 +msgid "" +"**Data generation**: Use `@quickcheck.samples` to generate random test " +"data" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:98 +msgid "**Comparison function**: Create `FuncRef` type comparison function" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:99 +msgid "**Sort comparison**: Use both C's `qsort` and MoonBit's `sort` method" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:100 +msgid "" +"**Result verification**: Ensure both sorting methods produce identical " +"results" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:104 +msgid "" +"**Cross-platform handling**: Learn how to handle differences in C " +"standard libraries across platforms" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:105 +msgid "" +"**Function pointer passing**: Master techniques for passing MoonBit " +"functions as C function pointers" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:106 +msgid "" +"**Memory safety**: Understand the importance of correctly managing " +"reference counts in callback functions" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:107 +msgid "" +"**Type mapping**: Learn how MoonBit complex types are represented on the " +"C side" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort.md:108 +msgid "" +"**Context passing**: Pass additional context information to callback " +"functions through structures" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:1 +msgid "Quick Sort with Closure Example" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:6 +msgid "" +"This example uses adapter function type `FuncRef[((Point, Point) -> Int, " +"Point, Point) -> Int]`, note that **closure is the first parameter**." +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:10 +msgid "This is one of the most error-prone areas in MoonBit Native FFI!" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:13 +msgid "" +"This example shows how to pass MoonBit closures to C functions. Unlike " +"the previous example, the comparison function used here can capture " +"external variables." +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:17 +msgid "" +"This example implements a more advanced sorting interface that supports " +"passing closures that can capture variables as comparison functions. It " +"demonstrates:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:19 +msgid "How MoonBit closures are handled in C FFI" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:20 +msgid "Differences and conversions between closures and `FuncRef`" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:21 +msgid "Complex function type FFI declarations" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:25 +msgid "" +"The MoonBit side FFI declaration is more complex than the previous " +"example:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:27 +msgid "" +"#borrow(xs, comp, closure)\n" +"extern \"c\" fn ffi_qsort(\n" +" xs : FixedArray[Point],\n" +" comp : FuncRef[((Point, Point) -> Int, Point, Point) -> Int],\n" +" closure : (Point, Point) -> Int,\n" +") = \"fqc_ffi_qsort\"\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:33 +msgid "Key feature analysis:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:35 +msgid "**Three parameters**:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:36 +msgid "`xs`: Array to be sorted" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:37 +msgid "" +"`comp`: Adapter function, type `FuncRef[((Point, Point) -> Int, Point, " +"Point) -> Int]`" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:38 +msgid "`closure`: Actual comparison closure, type `(Point, Point) -> Int`" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:40 +msgid "**⚠️ Important details of adapter function signature**:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:41 +msgid "Note `comp` type: `((Point, Point) -> Int, Point, Point) -> Int`" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:42 +msgid "" +"**First parameter is the closure itself**, subsequent parameters are " +"passed to the closure" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:43 +msgid "" +"This design requires special handling of closure reference counting on " +"the C side" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:45 +msgid "" +"**Adapter pattern**: Call `closure` through `comp` function, this is the " +"standard pattern for handling closures" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:49 +msgid "MoonBit provides a simplified interface:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:51 +msgid "" +"fn qsort(xs : FixedArray[Point], comp : (Point, Point) -> Int) -> Unit {\n" +" ffi_qsort(xs, fn(f, x, y) { f(x, y) }, comp)\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:57 +#: ../../example/native-ffi/funcref_register_callback.md:79 +msgid "This wrapper function:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:58 +msgid "Accepts regular closure function `comp : (Point, Point) -> Int`" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:59 +msgid "Creates adapter function `fn(f, x, y) { f(x, y) }`" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:60 +msgid "Hides FFI complexity" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:66 +msgid "" +"typedef void *moonbit_ref_t;\n" +"typedef moonbit_ref_t moonbit_point_t;\n" +"typedef moonbit_point_t *moonbit_fixedarray_point_t;\n" +"\n" +"typedef void* moonbit_closure_t;\n" +"\n" +"struct comp_context {\n" +" int (*call)(moonbit_closure_t closure,moonbit_point_t lhs, " +"moonbit_point_t rhs);\n" +" moonbit_closure_t closure;\n" +"};\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:72 +msgid "Main differences from the previous example:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:73 +msgid "Added `moonbit_closure_t` type to represent closures" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:74 +msgid "Context structure contains the closure object itself" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:76 +#, fuzzy +msgid "Comparison Function Implementation" +msgstr "惰性列表实现" + +#: ../../example/native-ffi/funcref_qsort_closure.md:78 +msgid "" +"#if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__)\n" +"#include \n" +"int fqc_comp(struct comp_context *context, moonbit_point_t *lhs,\n" +" moonbit_point_t *rhs)\n" +"#else\n" +"#define __USE_GNU // to order to use qsort_r\n" +"#include \n" +"int fqc_comp(moonbit_point_t *lhs, moonbit_point_t *rhs,\n" +" struct comp_context *context)\n" +"#endif\n" +"{\n" +" // CRITICAL: increment closure ref count because it's the first " +"parameter\n" +" // The adapter function will consume this reference when called\n" +" moonbit_incref(context->closure);\n" +" moonbit_incref(*lhs);\n" +" moonbit_incref(*rhs);\n" +" int res = context->call(context->closure, *lhs, *rhs);\n" +" return res;\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:84 +msgid "Critical memory management:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:85 +msgid "" +"**⚠️ Closure reference count critical technique**: " +"`moonbit_incref(context->closure)` increments closure reference count" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:86 +msgid "" +"**Important**: Since closure is the first parameter of adapter function, " +"it consumes one reference when called" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:87 +msgid "" +"Must execute `moonbit_incref` before each call, otherwise leads to use-" +"after-free errors" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:88 +msgid "" +"**Parameter reference count**: Increment reference counts for both Point " +"parameters respectively" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:89 +msgid "" +"**Three-parameter call**: Call adapter function, passing closure and two " +"parameters" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:93 +msgid "" +"// https://en.cppreference.com/w/c/algorithm/qsort\n" +"// both glibc and Windows CRT doesn't support ISO C qsort_s\n" +"void fqc_ffi_qsort(moonbit_fixedarray_point_t xs,\n" +" int (*call)(moonbit_closure_t closure,moonbit_point_t lhs," +" moonbit_point_t rhs),\n" +" moonbit_closure_t closure) {\n" +" size_t count = Moonbit_array_length(xs);\n" +" size_t elem_size = sizeof(moonbit_point_t);\n" +"\n" +" struct comp_context context;\n" +" context.call = call;\n" +" context.closure = closure;\n" +"#if defined(_WIN32) || defined(_WIN64)\n" +" // https://learn.microsoft.com/en-us/cpp/c-runtime-" +"library/reference/qsort-s?view=msvc-170\n" +" qsort_s(xs, count, elem_size, (void *)fqc_comp, &context);\n" +"#elif defined(__APPLE__)\n" +" // " +"https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/qsort_r.3.html" +"\n" +" qsort_r(xs, count, elem_size, &context, (void *)fqc_comp);\n" +"#else\n" +" // https://www.man7.org/linux/man-pages/man3/qsort.3.html\n" +" qsort_r(xs, count, elem_size, (void *)fqc_comp, &context);\n" +"#endif\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:99 +#, fuzzy +msgid "Context setup:" +msgstr "目录:" + +#: ../../example/native-ffi/funcref_qsort_closure.md:100 +msgid "Save adapter function pointer" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:101 +msgid "Save closure object reference" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:103 +msgid "Closure vs FuncRef Differences" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:105 +msgid "FuncRef Characteristics:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:106 +msgid "Must be closed functions (don't capture external variables)" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:107 +msgid "Represented as simple function pointers on C side" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:108 +msgid "Lower performance overhead" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:110 +msgid "Closure Characteristics:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:111 +msgid "Can capture external variables" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:112 +msgid "Require additional context data on C side" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:113 +msgid "Need more complex memory management" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:117 +msgid "" +"fn qsort(xs : FixedArray[Point], comp : (Point, Point) -> Int) -> Unit {\n" +" ffi_qsort(xs, fn(f, x, y) { f(x, y) }, comp)\n" +"}\n" +"// end closure qsort wrapper\n" +"\n" +"///|\n" +"test \"qsort_closure functionality\" {\n" +" let xs : FixedArray[Point] = @quickcheck.samples(10) |> " +"FixedArray::from_array\n" +" let ys = xs.copy()\n" +" let mut i = 0\n" +" let comp : (Point, Point) -> Int = fn(x, y) {\n" +" i += 1\n" +" // Note: can't use inspect inside closure due to error handling\n" +" x.compare(y)\n" +" }\n" +" inspect(\n" +" xs,\n" +" content=\"[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}, " +"{x: -2, y: 2}, {x: 0, y: 2}, {x: -5, y: -2}, {x: 2, y: 3}, {x: 3, y: 7}, " +"{x: 1, y: 0}]\",\n" +" )\n" +" inspect(\n" +" ys,\n" +" content=\"[{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: -1}, {x: 2, y: 0}, " +"{x: -2, y: 2}, {x: 0, y: 2}, {x: -5, y: -2}, {x: 2, y: 3}, {x: 3, y: 7}, " +"{x: 1, y: 0}]\",\n" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:122 +msgid "Test highlights:" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:124 +msgid "" +"**Variable capture**: Comparison function captures external `mut i` " +"variable" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:125 +msgid "**State statistics**: Modify `i` to count comparison operations" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:126 +msgid "**Functionality verification**: Ensure sorting results are correct" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:128 +msgid "" +"Note: The comment in the test mentions that `inspect` cannot be used " +"inside closures due to error handling limitations." +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:132 +msgid "" +"**Closure passing pattern**: Understand how to pass closures through " +"adapter functions" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:133 +msgid "" +"**Memory management complexity**: Closures require more careful reference" +" count management" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:134 +msgid "" +"**Performance trade-offs**: Closures provide greater flexibility but have" +" additional runtime overhead" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:135 +msgid "" +"**Type system design**: MoonBit distinguishes between `FuncRef` and " +"closures through the type system" +msgstr "" + +#: ../../example/native-ffi/funcref_qsort_closure.md:136 +msgid "" +"**FFI design patterns**: Adapter pattern is the standard method for " +"handling complex callbacks" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:1 +msgid "Callback Registration Example" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:6 +msgid "" +"This example uses adapter function type `FuncRef[(() -> Unit) -> Unit]`, " +"note that **closure is the first (and only) parameter**." +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:10 +msgid "The example calls three times, so it needs three `moonbit_incref` calls." +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:13 +msgid "" +"This example demonstrates how to implement callback function mechanisms " +"in MoonBit and how to properly manage closure lifetimes." +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:17 +msgid "" +"This example implements a callback registration system that allows " +"MoonBit functions to be called multiple times by C code. It showcases " +"MoonBit closure runtime representation and memory management strategies." +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:19 +msgid "MoonBit Closure Runtime Representation" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:21 +msgid "" +"In the C backend, MoonBit closures are represented as `void*` type " +"pointers:" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:23 +msgid "typedef void* moonbit_closure_t;\n" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:29 +msgid "" +"This type definition illustrates how MoonBit closures are represented on " +"the C side. All closure objects are passed through pointers." +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:33 +msgid "In MoonBit, we declare an external C function:" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:35 +msgid "" +"#borrow(call, closure)\n" +"extern \"c\" fn ffi_register_callback(\n" +" call : FuncRef[(() -> Unit) -> Unit],\n" +" closure : () -> Unit,\n" +") = \"register_callback\"\n" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:41 +msgid "Key features explanation:" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:43 +msgid "" +"**`#borrow` attribute**: Specifies that `call` and `closure` parameters " +"use borrow semantics, avoiding manual reference count management" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:44 +msgid "**⚠️ `FuncRef[(() -> Unit) -> Unit]`**: This is a function reference type" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:45 +msgid "**First parameter**: `() -> Unit` type closure" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:46 +msgid "**Function**: Accepts and calls a closure" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:47 +msgid "" +"**Important**: Closure passed as first parameter, consuming one reference" +" when called" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:48 +msgid "**`() -> Unit`**: Type of callback function to register" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:50 +#, fuzzy +msgid "C Implementation" +msgstr "实现" + +#: ../../example/native-ffi/funcref_register_callback.md:52 +msgid "" +"The C side implementation demonstrates how to properly handle MoonBit " +"closure lifetimes:" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:54 +msgid "" +"//\n" +"// `call` indicates how to consume `closure`\n" +"void register_callback(void (*call)(moonbit_closure_t), moonbit_closure_t" +" closure) {\n" +" // CRITICAL: increment ref count before each call\n" +" // because closure is the first (and only) parameter to the adapter " +"function\n" +" moonbit_incref(closure); \n" +" call(closure); // call closure directly\n" +" \n" +" // CRITICAL: increment again before second call\n" +" moonbit_incref(closure);\n" +" call(closure);\n" +"\n" +" // CRITICAL: increment again before third call \n" +" moonbit_incref(closure);\n" +" call(closure);\n" +"} \n" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:60 +msgid "Memory Management Details" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:62 +msgid "" +"**⚠️ Critical reference counting technique**: Need to call " +"`moonbit_incref(closure)` before each closure call" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:63 +msgid "" +"**Reason**: In `call(closure)`, closure as first parameter will be " +"consumed by adapter function" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:64 +msgid "" +"**Rule**: Must `moonbit_incref` before each call, otherwise closure is " +"freed on second call" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:65 +msgid "**Example**: Three calls in code, so three `moonbit_incref` calls" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:66 +msgid "" +"**Calling convention**: `call(closure)` directly calls the passed " +"function pointer, MoonBit compiler handles closure expansion and calling " +"at compile time" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:67 +msgid "" +"**Multiple calls**: Example demonstrates how to call the same closure " +"multiple times" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:71 +msgid "MoonBit provides a convenient wrapper function:" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:73 +msgid "" +"fn register_callback(closure : () -> Unit) -> Unit {\n" +" ffi_register_callback(\n" +" fn(f) { f() }, // moonc know how to consume `closure`\n" +" closure,\n" +" )\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:81 +msgid "Creates a `FuncRef` type adapter function `fn(f) { f() }`" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:82 +msgid "Passes user-provided closure to C function" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:83 +msgid "Hides underlying FFI complexity" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:87 +msgid "The example includes a complete test case:" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:89 +msgid "" +"test \"register_callback functionality\" {\n" +" let output = StringBuilder::new()\n" +" let s1 = \"moonbit\"\n" +" inspect(s1, content=\"moonbit\") // capture free variables before " +"registering\n" +" register_callback(fn() {\n" +" output.write_string(s1)\n" +" output.write_char('\\n')\n" +" })\n" +" let s2 = \"apple\"\n" +" register_callback(fn() {\n" +" output.write_string(s2)\n" +" output.write_char('\\n')\n" +" })\n" +" inspect(\n" +" output,\n" +" content=(\n" +" #|moonbit\n" +" #|moonbit\n" +" #|moonbit\n" +" #|apple\n" +" #|apple\n" +" #|apple\n" +" #|\n" +" ),\n" +" )\n" +"}\n" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:95 +msgid "Test Description" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:97 +msgid "" +"**Variable capture**: Closures capture external variables `s1` and `s2`, " +"demonstrating closure variable capture capability" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:98 +msgid "**Multiple execution**: Each registered callback is executed 3 times" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:99 +msgid "" +"**State maintenance**: Uses `StringBuilder` to collect output, verifying " +"correct callback execution" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:103 +msgid "" +"**FuncRef vs Closure**: `FuncRef` type is for functions that don't " +"capture variables, while closures can capture external variables" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:104 +msgid "" +"**Lifetime management**: Use `#borrow` attribute to simplify reference " +"count management" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:105 +msgid "" +"**Runtime representation**: Understand MoonBit closure memory layout and " +"representation on C side" +msgstr "" + +#: ../../example/native-ffi/funcref_register_callback.md:106 +msgid "" +"**Calling convention**: Master correct closure calling and memory " +"management patterns" +msgstr "" + +#: ../../example/native-ffi/index.md:1 +msgid "MoonBit Native FFI Examples" +msgstr "" + +#: ../../example/native-ffi/index.md:3 +msgid "" +"This section demonstrates MoonBit's Native FFI (Foreign Function " +"Interface) capabilities through practical examples, focusing on `FuncRef`" +" type usage and C language interoperability." +msgstr "" + +#: ../../example/native-ffi/index.md:7 +msgid "" +"These examples showcase how to use MoonBit's `FuncRef` type for safe and " +"efficient interoperability with C code. Each example demonstrates " +"different patterns for passing MoonBit functions to C libraries." +msgstr "" + #: ../../example/segment-tree/index.md:1 msgid "Segment Tree" msgstr "线段树" diff --git a/next/locales/zh_CN/LC_MESSAGES/language.po b/next/locales/zh_CN/LC_MESSAGES/language.po index a41e4aa0..8d0a287b 100644 --- a/next/locales/zh_CN/LC_MESSAGES/language.po +++ b/next/locales/zh_CN/LC_MESSAGES/language.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: MoonBit Document \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-08-15 18:21+0800\n" +"POT-Creation-Date: 2025-08-21 15:28+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -2020,17 +2020,21 @@ msgstr "" #: ../../language/error_codes/E0031.md:7 ../../language/error_codes/E0032.md:5 #: ../../language/error_codes/E0035.md:8 ../../language/error_codes/E0036.md:13 #: ../../language/error_codes/E0037.md:5 ../../language/error_codes/E0041.md:9 -#: ../../language/error_codes/E0042.md:8 ../../language/error_codes/E0043.md:8 +#: ../../language/error_codes/E0042.md:8 ../../language/error_codes/E0043.md:9 #: ../../language/error_codes/E0044.md:7 ../../language/error_codes/E0045.md:13 #: ../../language/error_codes/E0046.md:10 -#: ../../language/error_codes/E2000.md:17 ../../language/error_codes/E3001.md:5 -#: ../../language/error_codes/E3002.md:5 ../../language/error_codes/E3003.md:5 -#: ../../language/error_codes/E3004.md:6 ../../language/error_codes/E3005.md:11 -#: ../../language/error_codes/E3006.md:7 ../../language/error_codes/E3007.md:5 -#: ../../language/error_codes/E3008.md:5 ../../language/error_codes/E3009.md:5 -#: ../../language/error_codes/E3010.md:5 ../../language/error_codes/E3011.md:6 -#: ../../language/error_codes/E3012.md:6 ../../language/error_codes/E3014.md:8 -#: ../../language/error_codes/E3015.md:25 ../../language/error_codes/E3016.md:5 +#: ../../language/error_codes/E0049.md:10 ../../language/error_codes/E0050.md:9 +#: ../../language/error_codes/E0051.md:8 ../../language/error_codes/E0052.md:8 +#: ../../language/error_codes/E0053.md:9 ../../language/error_codes/E0054.md:11 +#: ../../language/error_codes/E0055.md:10 ../../language/error_codes/E0056.md:9 +#: ../../language/error_codes/E0057.md:8 ../../language/error_codes/E2000.md:17 +#: ../../language/error_codes/E3001.md:5 ../../language/error_codes/E3002.md:5 +#: ../../language/error_codes/E3003.md:10 ../../language/error_codes/E3004.md:6 +#: ../../language/error_codes/E3005.md:11 ../../language/error_codes/E3006.md:7 +#: ../../language/error_codes/E3007.md:5 ../../language/error_codes/E3008.md:5 +#: ../../language/error_codes/E3009.md:5 ../../language/error_codes/E3010.md:5 +#: ../../language/error_codes/E3011.md:6 ../../language/error_codes/E3012.md:6 +#: ../../language/error_codes/E3014.md:8 ../../language/error_codes/E3016.md:5 #: ../../language/error_codes/E3017.md:9 ../../language/error_codes/E3018.md:5 #: ../../language/error_codes/E3019.md:10 ../../language/error_codes/E3020.md:6 #: ../../language/error_codes/E3800.md:10 ../../language/error_codes/E4000.md:5 @@ -2058,7 +2062,6 @@ msgstr "" #: ../../language/error_codes/E4102.md:14 #: ../../language/error_codes/E4103.md:13 #: ../../language/error_codes/E4104.md:25 -#: ../../language/error_codes/E4105.md:23 #: ../../language/error_codes/E4106.md:11 #: ../../language/error_codes/E4107.md:10 #: ../../language/error_codes/E4108.md:25 ../../language/error_codes/E4109.md:8 @@ -2086,7 +2089,12 @@ msgstr "" #: ../../language/error_codes/E4151.md:11 #: ../../language/error_codes/E4153.md:18 #: ../../language/error_codes/E4154.md:18 -#: ../../language/error_codes/E4155.md:10 +#: ../../language/error_codes/E4155.md:10 ../../language/error_codes/E4156.md:8 +#: ../../language/error_codes/E4157.md:7 ../../language/error_codes/E4158.md:8 +#: ../../language/error_codes/E4159.md:10 +#: ../../language/error_codes/E4160.md:10 ../../language/error_codes/E4162.md:8 +#: ../../language/error_codes/E4163.md:8 ../../language/error_codes/E4164.md:10 +#: ../../language/error_codes/E4167.md:5 msgid "Erroneous example" msgstr "错误示例" @@ -2141,12 +2149,22 @@ msgstr "" #: ../../language/error_codes/E0037.md:11 #: ../../language/error_codes/E0041.md:14 #: ../../language/error_codes/E0042.md:13 -#: ../../language/error_codes/E0044.md:12 +#: ../../language/error_codes/E0043.md:15 +#: ../../language/error_codes/E0044.md:13 #: ../../language/error_codes/E0045.md:19 -#: ../../language/error_codes/E2000.md:23 +#: ../../language/error_codes/E0049.md:27 +#: ../../language/error_codes/E0050.md:15 +#: ../../language/error_codes/E0051.md:14 +#: ../../language/error_codes/E0052.md:14 +#: ../../language/error_codes/E0053.md:15 +#: ../../language/error_codes/E0054.md:17 +#: ../../language/error_codes/E0055.md:16 +#: ../../language/error_codes/E0056.md:15 +#: ../../language/error_codes/E0057.md:14 +#: ../../language/error_codes/E2000.md:29 #: ../../language/error_codes/E3001.md:21 #: ../../language/error_codes/E3002.md:19 -#: ../../language/error_codes/E3003.md:11 +#: ../../language/error_codes/E3003.md:16 #: ../../language/error_codes/E3004.md:12 #: ../../language/error_codes/E3005.md:17 #: ../../language/error_codes/E3006.md:13 @@ -2157,7 +2175,6 @@ msgstr "" #: ../../language/error_codes/E3011.md:12 #: ../../language/error_codes/E3012.md:12 #: ../../language/error_codes/E3014.md:14 -#: ../../language/error_codes/E3015.md:31 #: ../../language/error_codes/E3016.md:11 #: ../../language/error_codes/E3017.md:18 #: ../../language/error_codes/E3018.md:11 @@ -2242,7 +2259,6 @@ msgstr "" #: ../../language/error_codes/E4102.md:20 #: ../../language/error_codes/E4103.md:19 #: ../../language/error_codes/E4104.md:31 -#: ../../language/error_codes/E4105.md:29 #: ../../language/error_codes/E4106.md:17 #: ../../language/error_codes/E4107.md:16 #: ../../language/error_codes/E4108.md:31 @@ -2285,12 +2301,23 @@ msgstr "" #: ../../language/error_codes/E4148.md:15 #: ../../language/error_codes/E4149.md:13 #: ../../language/error_codes/E4151.md:16 +#: ../../language/error_codes/E4156.md:14 +#: ../../language/error_codes/E4157.md:13 +#: ../../language/error_codes/E4158.md:14 +#: ../../language/error_codes/E4159.md:22 +#: ../../language/error_codes/E4160.md:22 +#: ../../language/error_codes/E4162.md:14 +#: ../../language/error_codes/E4163.md:14 +#: ../../language/error_codes/E4164.md:22 +#: ../../language/error_codes/E4167.md:11 msgid "Suggestion" msgstr "建议" #: ../../language/error_codes/E0001.md:20 #: ../../language/error_codes/E0002.md:23 #: ../../language/error_codes/E0003.md:25 +#: ../../language/error_codes/E0052.md:16 +#: ../../language/error_codes/E0053.md:17 msgid "There are multiple ways to fix this warning:" msgstr "有几种方式可以修复这个警告:" @@ -4144,7 +4171,10 @@ msgstr "" #: ../../language/error_codes/E0029.md:28 ../../language/error_codes/E0030.md:7 #: ../../language/error_codes/E0030.md:15 #: ../../language/error_codes/E0031.md:12 ../../language/error_codes/E0032.md:9 -#: ../../language/introduction.md:154 +#: ../../language/error_codes/E0044.md:19 +#: ../../language/error_codes/E0049.md:12 +#: ../../language/error_codes/E2000.md:40 +#: ../../language/error_codes/E4156.md:21 ../../language/introduction.md:154 msgid "moon.pkg.json" msgstr "" @@ -4158,6 +4188,13 @@ msgid "" msgstr "" #: ../../language/error_codes/E0029.md:19 +#: ../../language/error_codes/E0049.md:22 +#: ../../language/error_codes/E2000.md:24 +#: ../../language/error_codes/E2000.md:33 +#: ../../language/error_codes/E4156.md:24 +#: ../../language/error_codes/E4159.md:17 +#: ../../language/error_codes/E4160.md:17 +#: ../../language/error_codes/E4164.md:17 msgid "top.mbt" msgstr "" @@ -4355,7 +4392,8 @@ msgstr "" #: ../../language/error_codes/E0033.md:3 ../../language/error_codes/E0034.md:3 #: ../../language/error_codes/E0038.md:3 ../../language/error_codes/E0039.md:3 -#: ../../language/error_codes/E0040.md:3 +#: ../../language/error_codes/E0040.md:3 ../../language/error_codes/E3015.md:3 +#: ../../language/error_codes/E4105.md:3 msgid "No longer emitted." msgstr "MoonBit 已不再使用此错误码。" @@ -4658,21 +4696,55 @@ msgstr "无用的属性标注。" #: ../../language/error_codes/E0043.md:5 msgid "" -"An attribute is marked on an entity that does not support this attribute," -" so the attribute will not take effect." -msgstr "某个属性标注被标记在了不支持该属性的顶层定义上,因此这个属性标注不会有任何作用。" +"An attribute will not take effect due to reasons such as being duplicated" +" while it should be unique, being applied to an entity that it has no " +"effect, or being misused" +msgstr "" -#: ../../language/error_codes/E0043.md:9 +#: ../../language/error_codes/E0043.md:11 msgid "" -"// the attribute is unused and has no effect\n" -"#deprecated\n" -"fn main {\n" +"///|\n" +"/// This is an invalid usage as the deprecation warning should be unique\n" +"#deprecated(\"\")\n" +"#deprecated(\"The attribute is unused because it's duplicated\")\n" +"pub fn f() -> Unit {\n" +"\n" +"}\n" +"\n" +"///|\n" +"/// This is an invalid usage as struct can't be external\n" +"#external\n" +"pub struct T {}\n" +"\n" +"///|\n" +"/// This is an invalid usage as it expects a string\n" +"#deprecated(asdfasdf)\n" +"pub fn g() -> Unit {\n" +"\n" "}\n" msgstr "" -"// 这个属性标注没有效果,是无用的\n" -"#deprecated\n" -"fn main {\n" + +#: ../../language/error_codes/E0043.md:17 +msgid "Apply the fix according to the specific warning message." +msgstr "" + +#: ../../language/error_codes/E0043.md:19 +msgid "" +"///|\n" +"#deprecated(\"\")\n" +"pub fn f() -> Unit {\n" +"\n" +"}\n" +"\n" +"///|\n" +"pub struct T {}\n" +"\n" +"///|\n" +"#deprecated(\"asdfasdf\")\n" +"pub fn g() -> Unit {\n" +"\n" "}\n" +msgstr "" #: ../../language/error_codes/E0044.md:1 msgid "E0044" @@ -4683,17 +4755,14 @@ msgid "Inline wasm code is invalid." msgstr "内联 wasm 代码不合法" #: ../../language/error_codes/E0044.md:5 -msgid "" -"Either the inline wasm code has incorrect syntax, or it refers to unbound" -" function." +#, fuzzy +msgid "The inline wasm code refers to unbound function." msgstr "内联 wasm 的语法不正确,或使用了未定义的函数。" -#: ../../language/error_codes/E0044.md:8 +#: ../../language/error_codes/E0044.md:9 +#, fuzzy msgid "" -"// unmatched parenthesis\n" -"extern \"wasm\" fn f() =\n" -" #| (func $f\n" -"\n" +"///|\n" "extern \"wasm\" fn g() =\n" " #| (func $g (call $does_not_exist))\n" msgstr "" @@ -4704,13 +4773,16 @@ msgstr "" "extern \"wasm\" fn g() =\n" " #| (func $g (call $does_not_exist))\n" -#: ../../language/error_codes/E0044.md:13 -msgid "Here are some pitfalls when writing inline wasm:" -msgstr "下面是写内联 wasm 代码时一些常见的问题:" - #: ../../language/error_codes/E0044.md:15 -msgid "all variables and functions must start with `$`" -msgstr "内联 wasm 中的所有变量名和函数名必须以 `$` 开头" +msgid "" +"If you know that such a function does exist, manually override suppress " +"the warning. Notice that the compilation error will result in an " +"[internal compiler error](./E1001.md)" +msgstr "" + +#: ../../language/error_codes/E0044.md:19 +msgid "{\"warn-list\": \"-44\"}\n" +msgstr "" #: ../../language/error_codes/E0045.md:1 msgid "E0045" @@ -4739,13 +4811,17 @@ msgstr "" #: ../../language/error_codes/E0045.md:15 msgid "" +"///|\n" "pub(open) trait Foo {\n" " foo(Self) -> Unit = _\n" "}\n" "\n" -"impl Foo with foo(_) {\n" +"///|\n" +"impl Foo with foo(_) {\n" +"\n" "}\n" "\n" +"///|\n" "test {\n" " let x : Int = 0\n" " Foo::foo(x)\n" @@ -4759,7 +4835,10 @@ msgid "" msgstr "为想要实现对应特征的类型添加显式的 `impl` 声明。" #: ../../language/error_codes/E0045.md:24 -msgid "impl Foo for Int\n" +msgid "" +"\n" +"///|\n" +"impl Foo for Int\n" msgstr "" #: ../../language/error_codes/E0046.md:1 @@ -4781,225 +4860,670 @@ msgstr "" "可以用来忽略结构体中未被匹配的字段,或是枚举构造器中未被匹配的带标签的参数。但如果所有字段/带标签的参数都已经被显式地匹配到了,那么 `..` " "就是无用的,此时编译器会产生一个警告。" -#: ../../language/error_codes/E0046.md:11 +#: ../../language/error_codes/E0046.md:12 msgid "" +"///|\n" "struct Point {\n" " x : Int\n" " y : Int\n" "}\n" "\n" +"///|\n" "fn f(p : Point) -> Unit {\n" " let { x, y, .. } = p\n" " println(x + y)\n" "}\n" "\n" +"///|\n" "test {\n" " f({ x: 1, y: 2 })\n" "}\n" msgstr "" -#: ../../language/error_codes/E1001.md:1 -msgid "E1001" +#: ../../language/error_codes/E0049.md:1 +msgid "E0049" msgstr "" -#: ../../language/error_codes/E1001.md:3 +#: ../../language/error_codes/E0049.md:3 +msgid "Unused pub definition because it does not exist in mbti file." +msgstr "" + +#: ../../language/error_codes/E0049.md:5 msgid "" -"There is an internal error occurred to the compiler. Usually this means " -"you have discovered a bug in the compiler." +"A `.mbti` file contains the public interface of a package. When a package" +" implements a [virtual package](/toolchain/moon/package.md#virtual-" +"package), it is checked against the interface of that virtual package, " +"and this warning is emitted if extra public declarations are found." msgstr "" -#: ../../language/error_codes/E1001.md:6 +#: ../../language/error_codes/E0049.md:12 ../../language/packages.md:227 msgid "" -"A bug report containing the error description and relevant code would be " -"greatly appreciated. You can submit the bug report here:" +"{\n" +" \"virtual\": {\n" +" \"has-default\": true\n" +" }\n" +"}" msgstr "" -#: ../../language/error_codes/E1001.md:9 ../../language/error_codes/E4048.md:9 -#: ../../language/error_codes/E4049.md:11 -msgid "" +#: ../../language/error_codes/E0049.md:17 +msgid "pkg.mbti" msgstr "" -#: ../../language/error_codes/E2000.md:1 -msgid "E2000" +#: ../../language/error_codes/E0049.md:17 +msgid "package \"moonbit-community/E0049\"\n" msgstr "" -#: ../../language/error_codes/E2000.md:3 +#: ../../language/error_codes/E0049.md:22 +#: ../../language/error_codes/E4160.md:27 msgid "" -"The usage of function (type, trait, etc.) is flagged with alert. Usually," -" alert message comes with a alert kind and a detailed description of the " -"alert. If you are using the function from a library, these alerts are set" -" by the library author to provide some more information on the usage of " -"the function" -msgstr "函数(类型、特征等)的使用被标记为警告。通常,警告消息会带有警告类型和警告的详细描述。如果你正在使用来自库的函数,这些警告是由库作者设置的,以提供有关函数使用的更多信息。" +"///|\n" +"pub fn f() -> Unit {\n" +"\n" +"}\n" +msgstr "" -#: ../../language/error_codes/E2000.md:8 -msgid "There are some common alerts that you may encounter:" -msgstr "以下是一些常见的警告:" +#: ../../language/error_codes/E0049.md:29 +msgid "Remove the public declarations that does not appear in the interface." +msgstr "" -#: ../../language/error_codes/E2000.md:10 -msgid "" -"`deprecated`: indicates the function (or type, trait, etc.) is deprecated" -" and should not be used. You should migrate to new APIs." -msgstr "`deprecated`: 表示函数(类型、特征等)已被弃用,不应该使用。你应迁移到新的 API。" +#: ../../language/error_codes/E0050.md:1 +msgid "E0050" +msgstr "" -#: ../../language/error_codes/E2000.md:12 +#: ../../language/error_codes/E0050.md:3 +msgid "Local method shadows upstream method." +msgstr "" + +#: ../../language/error_codes/E0050.md:5 msgid "" -"`unsafe`: indicates this API may panic, have internal invariants, or have" -" undefined behavior under some circumstances. The concrete semantics of " -"this kind of alerts may be different across packages, and please consult " -"the documentation or the author of these packages for further details." +"Methods can be defined for types that does not belong to the current " +"package. When having the same name as the existing ones, it can lead to " +"confusion about which method is being referenced." msgstr "" -"`unsafe`: 表示该 API 可能会导致 " -"panic、具有内部不变式,或在某些情况下具有未定义的行为。对于这类警告的具体语义可能会因软件包而异,请咨询相关文档或软件包的作者以获得更多详细信息。" -#: ../../language/error_codes/E2000.md:19 +#: ../../language/error_codes/E0050.md:11 msgid "" -"/// @alert deprecated \"Use `greet` instead\"\n" -"fn greeting() -> String {\n" -" \"Hello!\"\n" +"///|\n" +"fn Int::abs(i : Int) -> Int {\n" +" if i > 0 {\n" +" i\n" +" } else {\n" +" -i\n" +" }\n" "}\n" "\n" -"fn greet(name~ : String = \"\") -> String {\n" -" if name != \"\" {\n" -" \"Hello!\"\n" +"///|\n" +"test {\n" +" inspect((-1).abs(), content=\"1\")\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E0050.md:17 +#, fuzzy +msgid "Use distince names for local methods to make the code's intent clear." +msgstr "为不同的循环使用不同的、描述性的标签名称,以使代码的意图清晰。" + +#: ../../language/error_codes/E0050.md:19 +msgid "" +"///|\n" +"fn Int::local_abs(i : Int) -> Int {\n" +" if i > 0 {\n" +" i\n" " } else {\n" -" \"Hello, \\{name}!\"\n" +" -i\n" " }\n" "}\n" "\n" -"fn main {\n" -" println(greeting())\n" -" // ^~~~~~~~ Warning (Alert deprecated): Use `greet` instead(2000)\n" -"}" +"///|\n" +"test {\n" +" inspect((-1).local_abs(), content=\"1\")\n" +"}\n" msgstr "" -#: ../../language/error_codes/E2000.md:25 -msgid "" -"One way to fix the alert, is to change your code as suggested by the " -"message (like `deprecated`):" -msgstr "修复警告的一种方法是按照消息中的建议更改代码(如 `deprecated`):" +#: ../../language/error_codes/E0051.md:1 +msgid "E0051" +msgstr "" -#: ../../language/error_codes/E2000.md:27 -msgid "" -"// ... code in the example above ...\n" -"fn main {\n" -" println(greet(name=\"world\"))\n" -"}" +#: ../../language/error_codes/E0051.md:3 +msgid "Ambiguous operator precedence." msgstr "" -"// ... 上方例子中的代码 ...\n" -"fn main {\n" -" println(greet(name=\"world\"))\n" -"}" -#: ../../language/error_codes/E2000.md:31 +#: ../../language/error_codes/E0051.md:5 msgid "" -"If you clearly know what you are doing and would like to suppress the " -"alert, you can change the `moon.pkg.json` file for packages where you " -"would like to disable **this kind of alert**. For example:" -msgstr "如果你清楚知道自己在做什么,并且想要抑制警告,你可以更改 `moon.pkg.json` 文件,以禁用**这种类型的警告**。例如:" +"Some operators have non-intuitive precedence and can lead to confusion. " +"Always use parentheses to make the intent clearer in these cases." +msgstr "" -#: ../../language/error_codes/E2000.md:33 +#: ../../language/error_codes/E0051.md:10 msgid "" -"{\n" -" // ... other fields in the file\n" -" \"alert-list\": \"-deprecated\"\n" -"}" +"///|\n" +"pub fn f() -> Int {\n" +" 1 + 2 << 3\n" +"}\n" msgstr "" -"{\n" -" // ... 文件中的其他字段\n" -" \"alert-list\": \"-deprecated\"\n" -"}" -#: ../../language/error_codes/E2000.md:38 -msgid "There is no way to disable alerts for a line/file." -msgstr "无法为一行/文件禁用警告。" - -#: ../../language/error_codes/E3001.md:1 -msgid "E3001" +#: ../../language/error_codes/E0051.md:16 +msgid "Add parentheses to make the intent clearer." msgstr "" -#: ../../language/error_codes/E3001.md:3 -msgid "This source files contains invalid or incomplete tokens." -msgstr "源文件包含无效或不完整的记号。" - -#: ../../language/error_codes/E3001.md:7 +#: ../../language/error_codes/E0051.md:18 msgid "" -"fn main {\n" -" println('3)\n" -"}" +"///|\n" +"pub fn f() -> Int {\n" +" (1 + 2) << 3\n" +"}\n" msgstr "" -#: ../../language/error_codes/E3001.md:11 -msgid "This example gives the following error on line 2:" -msgstr "这个例子在第 2 行给出了以下错误:" +#: ../../language/error_codes/E0052.md:1 +msgid "E0052" +msgstr "" -#: ../../language/error_codes/E3001.md:13 -msgid "Lexing error: unrecognized character u32:0x27\n" +#: ../../language/error_codes/E0052.md:3 +#, fuzzy +msgid "A loop variable is not updated in loop." +msgstr "变量并非在所有模式中都是绑定的。" + +#: ../../language/error_codes/E0052.md:5 +msgid "" +"When a loop variable is not updated, this could be a potential bug that " +"you have forgotten to update it, leading to an infinite loop." msgstr "" -#: ../../language/error_codes/E3001.md:17 +#: ../../language/error_codes/E0052.md:10 msgid "" -"... which indicates that the compiler don't know how to interpret the " -"dangling character `'` (ASCII 0x27) on that line as a part of a MoonBit " -"token." -msgstr "这表明编译器不知道如何将该行上的悬空字符 `'`(ASCII 0x27)解释为 MoonBit 记号的一部分。" +"///|\n" +"pub fn f() -> Unit {\n" +" for i = 0, radix = 10; i < 10; {\n" +" println(i.to_string(radix~))\n" +" }\n" +"}\n" +msgstr "" -#: ../../language/error_codes/E3001.md:23 +#: ../../language/error_codes/E0052.md:18 +#, fuzzy msgid "" -"Change your code to strictly follow the MoonBit syntax rules, so that it " -"only contains valid MoonBit tokens." -msgstr "更改你的代码,严格遵循 MoonBit 语法规则,确保它仅包含有效的 MoonBit 记号。" +"If this variable is indeed constant during the loop, you can remove it " +"from the initialization and make it constant" +msgstr "如果这个变量确实没有用,你可以移除变量的定义。" -#: ../../language/error_codes/E3001.md:26 -msgid "In the above example, the missing closing apostrophe should be added:" -msgstr "在上面的例子中,应该添加缺失的闭合撇号:" +#: ../../language/error_codes/E0052.md:20 +msgid "" +"If your code depends on change of the variable, you should update it " +"somewhere in the loop." +msgstr "" -#: ../../language/error_codes/E3001.md:28 +#: ../../language/error_codes/E0052.md:23 msgid "" -"fn main {\n" -" println('3')\n" -"}" +"///|\n" +"pub fn f() -> Unit {\n" +" let radix = 10\n" +" for i = 0; i < 10; i = i + 1 {\n" +" println(i.to_string(radix~))\n" +" }\n" +"}\n" msgstr "" -#: ../../language/error_codes/E3002.md:1 -msgid "E3002" +#: ../../language/error_codes/E0053.md:1 +msgid "E0053" msgstr "" -#: ../../language/error_codes/E3002.md:3 -msgid "This source files contains errors in the syntax of the code." -msgstr "这个源文件包含代码语法错误。" +#: ../../language/error_codes/E0053.md:3 +#, fuzzy +msgid "Unused trait bound." +msgstr "无用的属性标注。" -#: ../../language/error_codes/E3002.md:7 +#: ../../language/error_codes/E0053.md:5 msgid "" -"fn main() -> Unit {\n" -" println(\"Hello, world!\"\n" -"}" +"The polymorphic function or method has a trait bound that is not used. " +"This could be a potential bug that you have forgotten to apply the " +"methods from the trait." msgstr "" -#: ../../language/error_codes/E3002.md:11 -msgid "This example gives the following error on line 3:" -msgstr "这个例子在第 3 行给出了以下错误:" +#: ../../language/error_codes/E0053.md:11 +msgid "" +"///|\n" +"trait Any {}\n" +"\n" +"///|\n" +"pub fn[T : Any] check(_ : T) -> Unit {\n" +" println(\"Hello\")\n" +"}\n" +"\n" +"///|\n" +"pub fn[T : Compare] shortlex(a : Array[T], b : Array[T]) -> Int {\n" +" Int::compare(a.length(), b.length())\n" +"}\n" +msgstr "" -#: ../../language/error_codes/E3002.md:13 -msgid "Parse error, unexpected token `}`, you may expect `,` or `)`.\n" +#: ../../language/error_codes/E0053.md:19 +msgid "If this trait bound is unnecessary, you can remove it" msgstr "" -#: ../../language/error_codes/E3002.md:17 +#: ../../language/error_codes/E0053.md:20 msgid "" -"... which indicates a missing closing parenthesis (`)`) in the `println` " -"function call." -msgstr "这表明 `println` 函数调用中缺少闭合括号(`)`)。" - -#: ../../language/error_codes/E3002.md:21 -msgid "Change your code to strictly follow the MoonBit syntax rules." -msgstr "更改你的代码,严格遵循 MoonBit 语法规则。" - -#: ../../language/error_codes/E3002.md:23 -msgid "In the above example, the missing closing parenthesis should be added:" +"\n" +"///|\n" +"pub fn[T] check(_ : T) -> Unit {\n" +" println(\"Hello\")\n" +"}\n" +"\n" msgstr "" -#: ../../language/error_codes/E3002.md:25 -#: ../../language/error_codes/E3003.md:15 +#: ../../language/error_codes/E0053.md:25 +#, fuzzy +msgid "You can cast the variable to a trait object" +msgstr "你可以将变量 `a` 改为一个常量:" + +#: ../../language/error_codes/E0053.md:26 +msgid "" +"\n" +"///|\n" +"pub fn[T : Any] check_any(t : T) -> Unit {\n" +" let _ = t as &Any\n" +" println(\"Hello\")\n" +"}\n" +"\n" +msgstr "" + +#: ../../language/error_codes/E0053.md:31 +msgid "You can use the methods defined in the Trait" +msgstr "" + +#: ../../language/error_codes/E0053.md:32 +msgid "" +"\n" +"///|\n" +"pub fn[T : Compare] shortlex(a : Array[T], b : Array[T]) -> Int {\n" +" match Int::compare(a.length(), b.length()) {\n" +" _..<0 => -1\n" +" 1..<_ => 1\n" +" 0 =>\n" +" for i = 0; i < a.length(); i = i + 1 {\n" +" match T::compare(a[i], b[i]) {\n" +" _..<0 => return -1\n" +" 1..<_ => return 1\n" +" 0 => ()\n" +" }\n" +" } else {\n" +" return 0\n" +" }\n" +" }\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E0054.md:1 +msgid "E0054" +msgstr "" + +#: ../../language/error_codes/E0054.md:3 +msgid "Async function or method is missing the error annotation." +msgstr "" + +#: ../../language/error_codes/E0054.md:5 +msgid "" +"Asynchronous functions and methods are expected to specify the errors " +"they can raise.If an async function or method is guaranteed **not** to " +"raise any errors, it must be explicitly marked with the " +"[`noraise`](/language/error-handling.md#throwing-errors) annotation. This" +" clarifies the function's behavior for anyone using it." +msgstr "" + +#: ../../language/error_codes/E0054.md:13 +msgid "" +"///|\n" +"pub async fn println(str : String) -> Unit {\n" +" ...\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E0054.md:19 +#, fuzzy +msgid "Add `noraise` or `raise E` to the function signature." +msgstr "在函数名后添加 `()`。" + +#: ../../language/error_codes/E0054.md:21 +msgid "" +"///|\n" +"pub async fn println(str : String) -> Unit noraise {\n" +" ...\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E0055.md:1 +msgid "E0055" +msgstr "" + +#: ../../language/error_codes/E0055.md:3 +msgid "Unannotated FFI param type." +msgstr "" + +#: ../../language/error_codes/E0055.md:5 +msgid "" +"The FFI parameter of pointer type should be annotated with either " +"`#borrow` or\\ `#owned`, the default calling convention is currently " +"`#owned` and it will be\\ changed in the future. For the detailed " +"meaning, checkout [FFI documentation](/language/ffi.md#the-borrow-" +"attribute)." +msgstr "" + +#: ../../language/error_codes/E0055.md:12 +msgid "" +"///|\n" +"extern \"c\" fn _f(p : Bytes) -> Unit = \"free\"\n" +msgstr "" + +#: ../../language/error_codes/E0055.md:18 +msgid "Add the missing `#borrow` or `#owned` annotation." +msgstr "" + +#: ../../language/error_codes/E0055.md:20 +msgid "" +"///|\n" +"#borrow(p)\n" +"extern \"c\" fn _f(p : Bytes) -> Unit = \"free\"\n" +msgstr "" + +#: ../../language/error_codes/E0056.md:1 +msgid "E0056" +msgstr "" + +#: ../../language/error_codes/E0056.md:3 +#, fuzzy +msgid "Missing field in struct pattern." +msgstr "将缺少的字段添加到构造函数中" + +#: ../../language/error_codes/E0056.md:5 +msgid "" +"The warning is emitted when pattern matching on a [struct " +"pattern](/language/fundamentals.md#simple-patterns) and having missing " +"fields." +msgstr "" + +#: ../../language/error_codes/E0056.md:11 +msgid "" +"///|\n" +"struct Point {\n" +" x : Int\n" +" y : Int\n" +"}\n" +"\n" +"///|\n" +"pub fn quadrant(p : Point) -> String {\n" +" match p {\n" +" { x: _..<0 } => \"Third or Fourth Quadrant\"\n" +" { x: 0..<_ } => \"First or Second Quadrant\"\n" +" }\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E0056.md:17 +msgid "Add `..` if you want to omit the other fields, or use them." +msgstr "" + +#: ../../language/error_codes/E0056.md:19 +msgid "" +"///|\n" +"struct Point {\n" +" x : Int\n" +" y : Int\n" +"}\n" +"\n" +"///|\n" +"pub fn quadrant(p : Point) -> String {\n" +" match p {\n" +" { x: _..<0, .. } => \"Third or Fourth Quadrant\"\n" +" { x: 0..<_, y: 0..<_ } => \"First Quadrant\"\n" +" { x: 0..<_, y: _..<0 } => \"Second Quadrant\"\n" +" }\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E0057.md:1 +msgid "E0057" +msgstr "" + +#: ../../language/error_codes/E0057.md:3 +msgid "Constructor pattern expect payload." +msgstr "" + +#: ../../language/error_codes/E0057.md:5 +msgid "" +"The warning is emitted when the payload part is missing from the " +"constructor pattern." +msgstr "" + +#: ../../language/error_codes/E0057.md:10 +msgid "" +"///|\n" +"pub fn[T] is_some(s : T?) -> Bool {\n" +" match s {\n" +" Some => true\n" +" None => false\n" +" }\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E0057.md:16 +msgid "Use `(_)` to ignore all the payloads." +msgstr "" + +#: ../../language/error_codes/E0057.md:18 +msgid "" +"///|\n" +"pub fn[T] is_some(s : T?) -> Bool {\n" +" match s {\n" +" Some(_) => true\n" +" None => false\n" +" }\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E1001.md:1 +msgid "E1001" +msgstr "" + +#: ../../language/error_codes/E1001.md:3 +msgid "" +"There is an internal error occurred to the compiler. Usually this means " +"you have discovered a bug in the compiler." +msgstr "" + +#: ../../language/error_codes/E1001.md:6 +msgid "" +"A bug report containing the error description and relevant code would be " +"greatly appreciated. You can submit the bug report here:" +msgstr "" + +#: ../../language/error_codes/E1001.md:9 ../../language/error_codes/E4048.md:9 +#: ../../language/error_codes/E4049.md:11 +msgid "" +msgstr "" + +#: ../../language/error_codes/E2000.md:1 +msgid "E2000" +msgstr "" + +#: ../../language/error_codes/E2000.md:3 +msgid "" +"The usage of function (type, trait, etc.) is flagged with alert. Usually," +" alert message comes with a alert kind and a detailed description of the " +"alert. If you are using the function from a library, these alerts are set" +" by the library author to provide some more information on the usage of " +"the function" +msgstr "函数(类型、特征等)的使用被标记为警告。通常,警告消息会带有警告类型和警告的详细描述。如果你正在使用来自库的函数,这些警告是由库作者设置的,以提供有关函数使用的更多信息。" + +#: ../../language/error_codes/E2000.md:8 +msgid "There are some common alerts that you may encounter:" +msgstr "以下是一些常见的警告:" + +#: ../../language/error_codes/E2000.md:10 +msgid "" +"`deprecated`: indicates the function (or type, trait, etc.) is deprecated" +" and should not be used. You should migrate to new APIs." +msgstr "`deprecated`: 表示函数(类型、特征等)已被弃用,不应该使用。你应迁移到新的 API。" + +#: ../../language/error_codes/E2000.md:12 +msgid "" +"`unsafe`: indicates this API may panic, have internal invariants, or have" +" undefined behavior under some circumstances. The concrete semantics of " +"this kind of alerts may be different across packages, and please consult " +"the documentation or the author of these packages for further details." +msgstr "" +"`unsafe`: 表示该 API 可能会导致 " +"panic、具有内部不变式,或在某些情况下具有未定义的行为。对于这类警告的具体语义可能会因软件包而异,请咨询相关文档或软件包的作者以获得更多详细信息。" + +#: ../../language/error_codes/E2000.md:19 +msgid "lib/top.mbt" +msgstr "" + +#: ../../language/error_codes/E2000.md:19 +msgid "" +"///| \n" +"#deprecated(\"Use `greet` instead\")\n" +"pub fn greeting() -> String {\n" +" \"Hello!\"\n" +"}\n" +"\n" +"///|\n" +"pub fn greet(name~ : String = \"\") -> String {\n" +" if name != \"\" {\n" +" \"Hello!\"\n" +" } else {\n" +" \"Hello, \\{name}!\"\n" +" }\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E2000.md:24 +msgid "" +"///|\n" +"fn main {\n" +" println(@lib.greeting())\n" +" // ^~~~~~~~ Warning (Alert deprecated): Use `greet` instead(2000)\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E2000.md:31 +msgid "" +"One way to fix the alert, is to change your code as suggested by the " +"message (like `deprecated`):" +msgstr "修复警告的一种方法是按照消息中的建议更改代码(如 `deprecated`):" + +#: ../../language/error_codes/E2000.md:33 +msgid "" +"///|\n" +"fn main {\n" +" println(@lib.greet())\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E2000.md:38 +msgid "" +"If you clearly know what you are doing and would like to suppress the " +"alert, you can change the `moon.pkg.json` file for packages where you " +"would like to disable **this kind of alert**. For example:" +msgstr "如果你清楚知道自己在做什么,并且想要抑制警告,你可以更改 `moon.pkg.json` 文件,以禁用**这种类型的警告**。例如:" + +#: ../../language/error_codes/E2000.md:40 +msgid "" +"{\n" +" \"is-main\": true,\n" +" \"import\": [\n" +" \"moonbit-community/E2000-fixed/lib\"\n" +" ],\n" +" \"alert-list\": \"-deprecated\"\n" +"}" +msgstr "" + +#: ../../language/error_codes/E2000.md:47 +msgid "There is no way to disable alerts for a line/file." +msgstr "无法为一行/文件禁用警告。" + +#: ../../language/error_codes/E3001.md:1 +msgid "E3001" +msgstr "" + +#: ../../language/error_codes/E3001.md:3 +msgid "This source files contains invalid or incomplete tokens." +msgstr "源文件包含无效或不完整的记号。" + +#: ../../language/error_codes/E3001.md:7 +msgid "" +"fn main {\n" +" println('3)\n" +"}" +msgstr "" + +#: ../../language/error_codes/E3001.md:11 +msgid "This example gives the following error on line 2:" +msgstr "这个例子在第 2 行给出了以下错误:" + +#: ../../language/error_codes/E3001.md:13 +msgid "Lexing error: unrecognized character u32:0x27\n" +msgstr "" + +#: ../../language/error_codes/E3001.md:17 +msgid "" +"... which indicates that the compiler don't know how to interpret the " +"dangling character `'` (ASCII 0x27) on that line as a part of a MoonBit " +"token." +msgstr "这表明编译器不知道如何将该行上的悬空字符 `'`(ASCII 0x27)解释为 MoonBit 记号的一部分。" + +#: ../../language/error_codes/E3001.md:23 +msgid "" +"Change your code to strictly follow the MoonBit syntax rules, so that it " +"only contains valid MoonBit tokens." +msgstr "更改你的代码,严格遵循 MoonBit 语法规则,确保它仅包含有效的 MoonBit 记号。" + +#: ../../language/error_codes/E3001.md:26 +msgid "In the above example, the missing closing apostrophe should be added:" +msgstr "在上面的例子中,应该添加缺失的闭合撇号:" + +#: ../../language/error_codes/E3001.md:28 +msgid "" +"fn main {\n" +" println('3')\n" +"}" +msgstr "" + +#: ../../language/error_codes/E3002.md:1 +msgid "E3002" +msgstr "" + +#: ../../language/error_codes/E3002.md:3 +msgid "This source files contains errors in the syntax of the code." +msgstr "这个源文件包含代码语法错误。" + +#: ../../language/error_codes/E3002.md:7 +msgid "" +"fn main() -> Unit {\n" +" println(\"Hello, world!\"\n" +"}" +msgstr "" + +#: ../../language/error_codes/E3002.md:11 +msgid "This example gives the following error on line 3:" +msgstr "这个例子在第 3 行给出了以下错误:" + +#: ../../language/error_codes/E3002.md:13 +msgid "Parse error, unexpected token `}`, you may expect `,` or `)`.\n" +msgstr "" + +#: ../../language/error_codes/E3002.md:17 +msgid "" +"... which indicates a missing closing parenthesis (`)`) in the `println` " +"function call." +msgstr "这表明 `println` 函数调用中缺少闭合括号(`)`)。" + +#: ../../language/error_codes/E3002.md:21 +msgid "Change your code to strictly follow the MoonBit syntax rules." +msgstr "更改你的代码,严格遵循 MoonBit 语法规则。" + +#: ../../language/error_codes/E3002.md:23 +msgid "In the above example, the missing closing parenthesis should be added:" +msgstr "" + +#: ../../language/error_codes/E3002.md:25 #: ../../language/error_codes/E4069.md:62 msgid "" "fn main {\n" @@ -5015,18 +5539,44 @@ msgstr "" msgid "`init` and `main` function must have no arguments and no return value." msgstr "`init` 与 `main` 函数不得有参数列表或返回类型。" -#: ../../language/error_codes/E3003.md:7 +#: ../../language/error_codes/E3003.md:6 +msgid "" +"The case of `fn main() -> Unit` is exceptionally accepted and can be " +"corrected by the formatter." +msgstr "" + +#: ../../language/error_codes/E3003.md:12 msgid "" -"fn main() -> Unit { // Error: Main function must have no arguments and no" -" return value.\n" +"///|\n" +"/// `init` function must have no arguments and no return value.\n" +"fn init() -> Unit {\n" +" \n" +"}\n" +"\n" +"///|\n" +"/// Error: Unused parameter list for the main function.\n" +"fn main() {\n" " println(\"Hello, world!\")\n" -"}" +"}\n" msgstr "" -#: ../../language/error_codes/E3003.md:13 +#: ../../language/error_codes/E3003.md:18 msgid "Remove the argument list and return type annotation, as:" msgstr "删除参数列表和返回类型注释,如:" +#: ../../language/error_codes/E3003.md:20 +msgid "" +"///|\n" +"fn init {\n" +"\n" +"}\n" +"\n" +"///|\n" +"fn main {\n" +" println(\"Hello, world!\")\n" +"}\n" +msgstr "" + #: ../../language/error_codes/E3004.md:1 msgid "E3004" msgstr "" @@ -5039,10 +5589,12 @@ msgstr "缺少参数列表。如果函数不接受参数,在函数名后添加 #: ../../language/error_codes/E3004.md:8 msgid "" -"fn greet { // Error: Missing parameters list. Add `()` if function " -"`greet` has 0 parameter.\n" +"///|\n" +"/// Error: Missing parameters list. Add `()` if function `greet` has 0 " +"parameter.\n" +"pub fn greet -> Unit {\n" " println(\"Hello, world!\")\n" -"}" +"}\n" msgstr "" #: ../../language/error_codes/E3004.md:14 @@ -5051,9 +5603,10 @@ msgstr "在函数名后添加 `()`。" #: ../../language/error_codes/E3004.md:16 msgid "" -"fn greet() {\n" +"///|\n" +"pub fn greet() -> Unit {\n" " println(\"Hello, world!\")\n" -"}" +"}\n" msgstr "" #: ../../language/error_codes/E3005.md:1 @@ -5261,38 +5814,25 @@ msgstr "只有带标签参数才可以有默认值。" #: ../../language/error_codes/E3010.md:7 msgid "" -"fn greet(name : String = \"World\") -> Unit {\n" -" // ^ Error: Only labelled arguments can have default " -"value.\n" +"pub fn greet(name : String = \"World\") -> Unit {\n" +" // ^ Error: Only labelled arguments can have " +"default value.\n" " println(\"Hello, \" + name + \"!\")\n" -"}" +"}\n" msgstr "" #: ../../language/error_codes/E3010.md:13 -msgid "Use a labelled argument with `~` if you want to provide a default value:" +#, fuzzy +msgid "Use an optional argument with `?` if you want to provide a default value:" msgstr "如果你想提供默认值,用 `~` 定义一个带标签的参数。" #: ../../language/error_codes/E3010.md:15 msgid "" -"fn greet(name~ : String = \"World\") -> Unit {\n" +"///|\n" +"pub fn greet(name? : String = \"World\") -> Unit {\n" " println(\"Hello, \" + name + \"!\")\n" "}\n" -"\n" -"fn main {\n" -" // Can be called as:\n" -" greet() // Uses default value \"World\"\n" -" greet(name=\"Alice\") // Uses provided value \"Alice\"\n" -"}" msgstr "" -"fn greet(name~ : String = \"World\") -> Unit {\n" -" println(\"Hello, \" + name + \"!\")\n" -"}\n" -"\n" -"fn main {\n" -" // 可以这样调用:\n" -" greet() // 使用默认值 \"World\"\n" -" greet(name=\"Alice\") // 使用提供值 \"Alice\"\n" -"}" #: ../../language/error_codes/E3010.md:19 msgid "" @@ -5302,9 +5842,10 @@ msgstr "或者如果你想保持它为一个位置参数,移除默认值:" #: ../../language/error_codes/E3010.md:21 msgid "" -"fn greet(name: String) -> Unit {\n" +"///|\n" +"pub fn greet_without_default(name : String) -> Unit {\n" " println(\"Hello, \" + name + \"!\")\n" -"}" +"}\n" msgstr "" #: ../../language/error_codes/E3011.md:1 @@ -5442,66 +5983,6 @@ msgstr "" msgid "E3015" msgstr "" -#: ../../language/error_codes/E3015.md:3 -msgid "The parameter already has default value `None`." -msgstr "参数已经有默认值 `None`。" - -#: ../../language/error_codes/E3015.md:5 -msgid "In MoonBit, the optional parameter has one of the two following forms:" -msgstr "在 MoonBit 中,可选参数有如下两种形式:" - -#: ../../language/error_codes/E3015.md:7 -msgid "Optional parameter with default value:" -msgstr "有参数的可选值:" - -#: ../../language/error_codes/E3015.md:9 -msgid "" -"fn f(a~ : Int = 0) -> Unit {\n" -" // ...\n" -"}\n" -msgstr "" - -#: ../../language/error_codes/E3015.md:15 -msgid "" -"Optional parameter with no default value. In this case, when the " -"parameter is not provided, it is `None` by default." -msgstr "无参数的可选值。在这种情况下,如果参数没有提供,则默认为 `None`。" - -#: ../../language/error_codes/E3015.md:17 -msgid "" -"fn f(a? : Int) -> Unit { // a has type Int?\n" -" // ...\n" -"}\n" -msgstr "" -"fn f(a? : Int) -> Unit { // a 的类型为 Int?\n" -" // ...\n" -"}\n" - -#: ../../language/error_codes/E3015.md:23 -msgid "" -"Therefore, if the optional parameter has a default value of `None`, it is" -" redundant and should be removed." -msgstr "因此,如果可选参数的默认值为 `None`,提供默认值就是多余的,应该删除。" - -#: ../../language/error_codes/E3015.md:27 -msgid "" -"fn f(a? : Int = None) -> Unit { // Error: The parameter a? already has " -"default value `None`.\n" -" println(a)\n" -"}" -msgstr "" - -#: ../../language/error_codes/E3015.md:33 -msgid "Remove the `= None` part from the optional parameter." -msgstr "从可选参数中移除 `= None` 部分" - -#: ../../language/error_codes/E3015.md:35 -msgid "" -"fn f(a? : Int) -> Unit {\n" -" println(a)\n" -"}" -msgstr "" - #: ../../language/error_codes/E3016.md:1 msgid "E3016" msgstr "" @@ -5770,20 +6251,23 @@ msgstr "" #: ../../language/error_codes/E3800.md:12 msgid "" +"///|\n" "enum V {\n" -" A, // Error: Expecting a newline or `;` here, but encountered another " -"delimiter `,`.\n" +" // Error: Expecting a newline or `;` here, but encountered `,`.\n" +" A,\n" "}\n" "\n" +"///|\n" "struct S {\n" -" a : Int, // Error: Expecting a newline or `;` here, but encountered " -"another delimiter `,`.\n" +" // Error: Expecting a newline or `;` here, but encountered `,`.\n" +" a : Int,\n" "}\n" "\n" -"type! E {\n" -" A, // Error: Expecting a newline or `;` here, but encountered another " -"delimiter `,`.\n" -"}" +"///|\n" +"suberror E {\n" +" // Error: Expecting a newline or `;` here, but encountered `,`.\n" +" A,\n" +"}\n" msgstr "" #: ../../language/error_codes/E3800.md:18 @@ -5795,17 +6279,20 @@ msgstr "将 `,` 替换为适当的换行符或 `;`。我们建议使用换行符 #: ../../language/error_codes/E3800.md:21 msgid "" +"///|\n" "enum V {\n" " A\n" "}\n" "\n" +"///|\n" "struct S {\n" " a : Int\n" "}\n" "\n" -"type! E {\n" +"///|\n" +"suberror E {\n" " A\n" -"}" +"}\n" msgstr "" #: ../../language/error_codes/E4000.md:1 @@ -10295,107 +10782,6 @@ msgstr "" msgid "E4105" msgstr "" -#: ../../language/error_codes/E4105.md:3 -msgid "Current loop has result type mismatch with `break` argument." -msgstr "当前循环的结果类型与 `break` 参数的类型不匹配。" - -#: ../../language/error_codes/E4105.md:5 -msgid "" -"This error occurs when the type of the argument provided to a `break` " -"statement does not match the expected result type of the loop. In " -"MoonBit, loops can have result types, and when using `break` with an " -"argument, that argument's type must match the loop's result type. When an" -" argument is not provided, the loop's result type must be `Unit`." -msgstr "" -"当提供给 `break` 语句的参数类型与循环的预期结果类型不匹配时,会发生此错误。在 MoonBit 中,循环可以有结果类型,当使用带有参数的 " -"`break` 时,该参数的类型必须与循环的结果类型匹配。当没有提供参数时,循环的结果类型必须是 `Unit`。" - -#: ../../language/error_codes/E4105.md:11 -msgid "This mismatch can happen in two ways:" -msgstr "此不匹配可能发生在两种方式中:" - -#: ../../language/error_codes/E4105.md:13 -msgid "" -"The loop expects a value of a certain type, but `break` is called with no" -" argument" -msgstr "循环期望一个特定类型的值,但 `break` 没有提供参数" - -#: ../../language/error_codes/E4105.md:15 -msgid "" -"The loop expects a value of type A, but `break` is called with an " -"argument of type B" -msgstr "循环期望一个类型为 A 的值,但 `break` 提供了类型为 B 的参数" - -#: ../../language/error_codes/E4105.md:18 -msgid "For loops with result types, you must ensure that:" -msgstr "对于具有结果类型的循环,您必须确保:" - -#: ../../language/error_codes/E4105.md:20 -msgid "All `break` statements provide an argument of the correct type" -msgstr "所有 `break` 语句都提供正确类型的参数" - -#: ../../language/error_codes/E4105.md:21 -msgid "The `else` branch (if present) returns a value of the correct type" -msgstr "`else` 分支(如果存在)返回正确类型的值" - -#: ../../language/error_codes/E4105.md:25 -msgid "" -"pub fn g(x: Int) -> Int {\n" -" for i in 0..=x {\n" -" if i == 42 {\n" -" break\n" -"// ^^^^^ Error: Current loop has result type Int, but `break` is " -"supplied\n" -"// with no arguments.\n" -" }\n" -" } else {\n" -" 0\n" -" }\n" -"}" -msgstr "" - -#: ../../language/error_codes/E4105.md:31 -#: ../../language/error_codes/E4108.md:33 -#: ../../language/error_codes/E4110.md:29 -msgid "To fix this error, you can:" -msgstr "要修复此错误,您可以:" - -#: ../../language/error_codes/E4105.md:33 -msgid "" -"Add an argument to the `break` statement that matches the loop's result " -"type. For example," -msgstr "向 `break` 语句添加一个与循环结果类型匹配的参数。例如:" - -#: ../../language/error_codes/E4105.md:36 -msgid "" -"pub fn g(x: Int) -> Int {\n" -" for i in 0..=x {\n" -" if i == 42 {\n" -" break i\n" -" }\n" -" } else {\n" -" 0\n" -" }\n" -"}" -msgstr "" - -#: ../../language/error_codes/E4105.md:40 -msgid "" -"Remove the `else` branch if you don't need to return a value from the " -"loop." -msgstr "如果不需要从循环中返回值,请删除 `else` 分支。" - -#: ../../language/error_codes/E4105.md:42 -msgid "" -"pub fn g(x: Int) -> Unit {\n" -" for i in 0..=x {\n" -" if i == 42 {\n" -" break\n" -" }\n" -" }\n" -"}" -msgstr "" - #: ../../language/error_codes/E4106.md:1 msgid "E4106" msgstr "" @@ -10586,6 +10972,11 @@ msgid "" "}" msgstr "" +#: ../../language/error_codes/E4108.md:33 +#: ../../language/error_codes/E4110.md:29 +msgid "To fix this error, you can:" +msgstr "要修复此错误,您可以:" + #: ../../language/error_codes/E4108.md:35 msgid "add an `else` branch to the for-loop:" msgstr "添加一个 `else` 分支到 for 循环:" @@ -12139,15 +12530,18 @@ msgstr "当您尝试将可选值转发给函数的参数时,会发生此错误 #: ../../language/error_codes/E4141.md:13 msgid "" -"fn f(opt~ : Int = 4) -> Unit {\n" +"///|\n" +"fn f(opt~ : Int) -> Unit {\n" " println(\"opt: \\{opt}\")\n" "}\n" "\n" +"///|\n" "fn main {\n" " let opt = Some(42)\n" -" f(opt?) // Error: This form of application is invalid for argument " -"opt~, because it is not declared with opt? : _.\n" -"}" +" // Error: This form of application is invalid for argument opt~, " +"because it is not declared with opt? : _.\n" +" f(opt?)\n" +"}\n" msgstr "" #: ../../language/error_codes/E4141.md:19 @@ -12158,13 +12552,14 @@ msgstr "如果您有权控制要调用的函数,您可以将参数更改为可 #: ../../language/error_codes/E4141.md:22 msgid "" +"///|\n" "fn f(opt? : Int) -> Unit {\n" " let opt = match opt {\n" " Some(opt) => opt\n" " None => 4\n" " }\n" " println(\"opt: \\{opt}\")\n" -"}" +"}\n" msgstr "" #: ../../language/error_codes/E4141.md:26 @@ -12175,14 +12570,11 @@ msgstr "但是,如果您没有控制权,您可以在将其传递给函数之 #: ../../language/error_codes/E4141.md:29 msgid "" -"fn main {\n" -" let opt = Some(42)\n" -" let opt = match opt {\n" -" Some(opt) => opt\n" -" None => 4\n" -" }\n" +"///|\n" +"fn main {\n" +" let opt = Some(42).unwrap_or(4)\n" " f(opt~)\n" -"}" +"}\n" msgstr "" #: ../../language/error_codes/E4142.md:1 @@ -12672,58 +13064,465 @@ msgstr "" msgid "Non-constant `enum` with custom tag value." msgstr "自定义标记值的非常量枚举 `enum`。" -#: ../../language/error_codes/E4154.md:5 -msgid "MoonBit supports customizing the integer representation of constructors:" -msgstr "MoonBit 支持自定义枚举构造器的整数表示:" +#: ../../language/error_codes/E4154.md:5 +msgid "MoonBit supports customizing the integer representation of constructors:" +msgstr "MoonBit 支持自定义枚举构造器的整数表示:" + +#: ../../language/error_codes/E4154.md:15 +msgid "" +"However, only constant `enum` (all constructors have not payload) can " +"have custom tag. Otherwise this error will be reported." +msgstr "但是,只有常量枚举(所有构造器都梅雨参数的枚举)才能有自定义整数值。否则编译器会产生本错误。" + +#: ../../language/error_codes/E4154.md:19 +msgid "" +"enum Bad {\n" +" A = 1\n" +" B = 2\n" +" C(Int)\n" +"}" +msgstr "" + +#: ../../language/error_codes/E4155.md:1 +msgid "E4155" +msgstr "" + +#: ../../language/error_codes/E4155.md:3 +msgid "Cycle in `const`, `fnalias`, `typealias` or `traitalias` declaration." +msgstr "`const`,`fnalias`,`typealias` 或 `traitalias` 声明里有循环定义。" + +#: ../../language/error_codes/E4155.md:5 +msgid "" +"`const` declaration can refer to other constants defined in the same " +"package, and `fnalias` can alias other function alias in the same " +"package, too. `typealias` and `traitalias` can also refer to other " +"`typealias`/`traitalias` in current package. But these definitions must " +"not form cycle, otherwise this error will be reported." +msgstr "" +"`const` 声明中可以使用同一个包内定义的其他常量。`fnalias` 也可以指代同一个包内的其他函数别名。`typealias` 和 " +"`traitalias` 也可以指代同一个包内的其他 " +"`typealias`/`traitalias`。但如果这些声明中有循环定义,编译器就会产生本错误。" + +#: ../../language/error_codes/E4155.md:11 +msgid "" +"///|\n" +"const A : Int = B + 1\n" +"\n" +"///|\n" +"const B : Int = A + 1\n" +"\n" +"///|\n" +"fnalias f as g\n" +"\n" +"///|\n" +"fnalias g as f\n" +"\n" +"///|\n" +"typealias T1 as T2\n" +"\n" +"///|\n" +"typealias T2 as T1\n" +"\n" +"///|\n" +"traitalias I1 as I2\n" +"\n" +"///|\n" +"traitalias I2 as I1\n" +msgstr "" + +#: ../../language/error_codes/E4156.md:1 +msgid "E4156" +msgstr "" + +#: ../../language/error_codes/E4156.md:3 +msgid "extern \"A\" is unsupported in B backend." +msgstr "" + +#: ../../language/error_codes/E4156.md:5 +msgid "" +"This error happens when an FFI function written for a specific backend is" +" discovered during the compilation of a different backend." +msgstr "" + +#: ../../language/error_codes/E4156.md:10 +#: ../../language/error_codes/E4156.md:24 +msgid "" +"///|\n" +"pub extern \"C\" fn getchar() -> Int = \"getchar\"\n" +msgstr "" + +#: ../../language/error_codes/E4156.md:16 +msgid "" +"You can use conditional compilation to control when the function is " +"available." +msgstr "" + +#: ../../language/error_codes/E4156.md:18 +msgid "" +"If you want a file level conditional compilation, configure the " +"[targets](/toolchain/moon/package.md#conditional-compilation) field." +msgstr "" + +#: ../../language/error_codes/E4156.md:21 +msgid "" +"{\n" +" \"targets\": {\n" +" \"top.mbt\": [\"native\"]\n" +" }\n" +"}" +msgstr "" + +#: ../../language/error_codes/E4156.md:29 +msgid "" +"If you want a function level conditional compilation, add the cfg " +"attribute." +msgstr "" + +#: ../../language/error_codes/E4156.md:31 +msgid "other.mbt" +msgstr "" + +#: ../../language/error_codes/E4156.md:31 +msgid "" +"///|\n" +"#cfg(target=\"native\")\n" +"pub extern \"C\" fn getchar2() -> Int = \"getchar\"\n" +msgstr "" + +#: ../../language/error_codes/E4157.md:1 +msgid "E4157" +msgstr "" + +#: ../../language/error_codes/E4157.md:3 +msgid "Unsupported signature in mbti file." +msgstr "" + +#: ../../language/error_codes/E4157.md:5 +msgid "" +"Currently, only abstract type, functions and methods are supported in " +"mbti file." +msgstr "" + +#: ../../language/error_codes/E4157.md:9 +msgid "" +"package \"moonbit-community/E4157\"\n" +"\n" +"// Non abstract type is not supported\n" +"enum A {\n" +" B\n" +" C\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4157.md:15 +#, fuzzy +msgid "Use abstract type instead." +msgstr "抽象类型(`type T`)" + +#: ../../language/error_codes/E4157.md:17 +msgid "" +"package \"moonbit-community/E4157-fixed\"\n" +"\n" +"type A\n" +msgstr "" + +#: ../../language/error_codes/E4158.md:1 +msgid "E4158" +msgstr "" + +#: ../../language/error_codes/E4158.md:3 +msgid "Default implementation is required but not found." +msgstr "" + +#: ../../language/error_codes/E4158.md:5 +msgid "" +"When a trait declares that it has a default implementation, the " +"implementation should exist." +msgstr "" + +#: ../../language/error_codes/E4158.md:10 +msgid "" +"///|\n" +"pub(open) trait Close {\n" +" // A default implementation is required but not found.\n" +" close(Self) -> Unit raise = _\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4158.md:16 +#, fuzzy +msgid "Implement the default implementation." +msgstr "从默认实现中移除类型参数:" + +#: ../../language/error_codes/E4158.md:18 +msgid "" +"///|\n" +"impl Close with close(_) {\n" +" ()\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4159.md:1 +msgid "E4159" +msgstr "" + +#: ../../language/error_codes/E4159.md:3 +#, fuzzy +msgid "Implementations are missing." +msgstr "实现细节" + +#: ../../language/error_codes/E4159.md:5 +msgid "" +"When a package implements a [virtual package](/toolchain/moon/package.md" +"#virtual-package), it is checked against the interface of that virtual " +"package, and this error is emitted if some of the interface is missing." +msgstr "" + +#: ../../language/error_codes/E4159.md:12 +msgid "E4159.mbti" +msgstr "" + +#: ../../language/error_codes/E4159.md:12 +msgid "" +"package \"moonbit-community/E4159\";\n" +"\n" +"fn f() -> Unit\n" +"\n" +"fn g() -> Unit\n" +msgstr "" + +#: ../../language/error_codes/E4159.md:17 +msgid "" +"///|\n" +"fn f() -> Unit {\n" +"\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4159.md:24 +msgid "" +"Implement the missing implementations and fulfill the interface. Make " +"sure that the expected definitions are indeed public." +msgstr "" + +#: ../../language/error_codes/E4159.md:27 +msgid "" +"///|\n" +"pub fn f() -> Unit {\n" +"\n" +"}\n" +"\n" +"///|\n" +"pub fn g() -> Unit {\n" +"\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4160.md:1 +msgid "E4160" +msgstr "" + +#: ../../language/error_codes/E4160.md:3 +#, fuzzy +msgid "Type mismatch with mbti." +msgstr "类型不匹配。" + +#: ../../language/error_codes/E4160.md:5 +msgid "" +"When a package implements a [virtual package](/toolchain/moon/package.md" +"#virtual-package), it is checked against the interface of that virtual " +"package, and this error is emitted if some of the interface has different" +" types." +msgstr "" + +#: ../../language/error_codes/E4160.md:12 +#: ../../language/error_codes/E4164.md:12 +msgid "E4160.mbti" +msgstr "" + +#: ../../language/error_codes/E4160.md:12 +msgid "" +"package \"moonbit-community/E4160\";\n" +"\n" +"fn f() -> Unit\n" +msgstr "" + +#: ../../language/error_codes/E4160.md:17 +msgid "" +"///|\n" +"pub fn f() -> Int {\n" +" 42\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4160.md:24 +msgid "" +"Modify the implementation such that it has the exact signature as the " +"virtual package it declared to implement." +msgstr "" + +#: ../../language/error_codes/E4162.md:1 +msgid "E4162" +msgstr "" + +#: ../../language/error_codes/E4162.md:3 +msgid "Local parameter is not function." +msgstr "" + +#: ../../language/error_codes/E4162.md:5 +msgid "" +"`#locals` is an attribute that aims to inline the given function " +"parameter. This error is raised when the given parameter is not a " +"function." +msgstr "" + +#: ../../language/error_codes/E4162.md:10 +msgid "" +"///|\n" +"#locals(init_)\n" +"pub fn[A, B] fold(a : Array[A], init_~ : B, f : (B, A) -> B) -> B {\n" +" // ^\n" +" // This parameter is expected to be a function, but it is not.\n" +" let mut acc = init_\n" +" for x in a {\n" +" acc = f(acc, x)\n" +" }\n" +" acc\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4162.md:16 +#: ../../language/error_codes/E4163.md:16 +msgid "Apply `locals` to local functions only." +msgstr "" + +#: ../../language/error_codes/E4162.md:18 +msgid "" +"///|\n" +"#locals(f)\n" +"pub fn[A, B] fold(a : Array[A], init_~ : B, f : (B, A) -> B) -> B {\n" +" let mut acc = init_\n" +" for x in a {\n" +" acc = f(acc, x)\n" +" }\n" +" acc\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4163.md:1 +msgid "E4163" +msgstr "" + +#: ../../language/error_codes/E4163.md:3 +msgid "Local parameters are not local." +msgstr "" + +#: ../../language/error_codes/E4163.md:5 +msgid "" +"`#locals` is an attribute that aims to inline the given function " +"parameter. This error is raised when the given parameter is not a 'local'" +" one." +msgstr "" + +#: ../../language/error_codes/E4163.md:10 +msgid "" +"///|\n" +"#locals(f)\n" +"pub fn[A] map_inline(arr : ArrayView[A], f : (A) -> A) -> Unit {\n" +" match arr {\n" +" [hd, .. tl] => {\n" +" arr[0] = f(hd)\n" +" map_inline(tl, f) // The parameter is not local: it escapes.\n" +" }\n" +" [] => ()\n" +" }\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4163.md:18 +msgid "" +"///|\n" +"#locals(f)\n" +"pub fn[A] map_inline(arr : ArrayView[A], f : (A) -> A) -> Unit {\n" +" for i = 0; i < arr.length(); i = i + 1 {\n" +" arr[i] = f(arr[i])\n" +" }\n" +"}\n" +msgstr "" + +#: ../../language/error_codes/E4164.md:1 +msgid "E4164" +msgstr "" + +#: ../../language/error_codes/E4164.md:3 +msgid "Type declaration mismatch with mbti." +msgstr "" + +#: ../../language/error_codes/E4164.md:5 +msgid "" +"When a package implements a [virtual package](/toolchain/moon/package.md" +"#virtual-package), it is checked against the interface of that virtual " +"package, and this error is emitted if some of the type declarations have " +"different arities." +msgstr "" + +#: ../../language/error_codes/E4164.md:12 +msgid "" +"package \"moonbit-community/E4164\";\n" +"\n" +"type Foo[_]\n" +msgstr "" + +#: ../../language/error_codes/E4164.md:17 +msgid "" +"///|\n" +"pub enum Foo {}\n" +msgstr "" -#: ../../language/error_codes/E4154.md:15 +#: ../../language/error_codes/E4164.md:24 msgid "" -"However, only constant `enum` (all constructors have not payload) can " -"have custom tag. Otherwise this error will be reported." -msgstr "但是,只有常量枚举(所有构造器都梅雨参数的枚举)才能有自定义整数值。否则编译器会产生本错误。" +"Modify the implementation such that it has the compatible signature as " +"the virtual package it declared to implement." +msgstr "" -#: ../../language/error_codes/E4154.md:19 +#: ../../language/error_codes/E4164.md:27 msgid "" -"enum Bad {\n" -" A = 1\n" -" B = 2\n" -" C(Int)\n" -"}" +"///|\n" +"pub enum Foo[_] {}\n" msgstr "" -#: ../../language/error_codes/E4155.md:1 -msgid "E4155" +#: ../../language/error_codes/E4167.md:1 +msgid "E4167" msgstr "" -#: ../../language/error_codes/E4155.md:3 -msgid "Cycle in `const`, `fnalias`, `typealias` or `traitalias` declaration." -msgstr "`const`,`fnalias`,`typealias` 或 `traitalias` 声明里有循环定义。" +#: ../../language/error_codes/E4167.md:3 +msgid "Default implementation is not marked with `= _`." +msgstr "" -#: ../../language/error_codes/E4155.md:5 +#: ../../language/error_codes/E4167.md:7 msgid "" -"`const` declaration can refer to other constants defined in the same " -"package, and `fnalias` can alias other function alias in the same " -"package, too. `typealias` and `traitalias` can also refer to other " -"`typealias`/`traitalias` in current package. But these definitions must " -"not form cycle, otherwise this error will be reported." +"///|\n" +"pub(open) trait HasDefaultImpl {\n" +" foo() -> Unit // It has default implementation but is not marked\n" +"}\n" +"\n" +"///|\n" +"impl HasDefaultImpl with foo() {\n" +" println(\"OK\")\n" +"}\n" msgstr "" -"`const` 声明中可以使用同一个包内定义的其他常量。`fnalias` 也可以指代同一个包内的其他函数别名。`typealias` 和 " -"`traitalias` 也可以指代同一个包内的其他 " -"`typealias`/`traitalias`。但如果这些声明中有循环定义,编译器就会产生本错误。" -#: ../../language/error_codes/E4155.md:11 +#: ../../language/error_codes/E4167.md:13 +#, fuzzy +msgid "Add `= _` to the methods that have default implementations." +msgstr "从默认实现中移除类型参数:" + +#: ../../language/error_codes/E4167.md:15 msgid "" -"const A : Int = B + 1\n" -"const B : Int = A + 1\n" -"\n" -"fnalias f = g\n" -"fnalias g = f\n" -"\n" -"typealias T1 as T2\n" -"typealias T2 as T1\n" -"\n" -"traitalias I1 as I2\n" -"traitalias I2 as I1" +"///|\n" +"pub(open) trait HasDefaultImpl {\n" +" foo() -> Unit = _\n" +"}\n" msgstr "" #: ../../language/error_codes/index.md:1 @@ -19449,15 +20248,6 @@ msgstr "" "在 `moon.pkg.json` 中,你需要添加字段 " "[`virtual`](/toolchain/moon/package.md#declarations) :" -#: ../../language/packages.md:227 -msgid "" -"{\n" -" \"virtual\": {\n" -" \"has-default\": true\n" -" }\n" -"}" -msgstr "" - #: ../../language/packages.md:231 msgid "" "The `has-default` indicates whether the virtual package has a default " @@ -20748,3 +21538,391 @@ msgstr "" #~ "}\n" #~ msgstr "" +#~ msgid "" +#~ "An attribute is marked on an " +#~ "entity that does not support this " +#~ "attribute, so the attribute will not " +#~ "take effect." +#~ msgstr "某个属性标注被标记在了不支持该属性的顶层定义上,因此这个属性标注不会有任何作用。" + +#~ msgid "" +#~ "// the attribute is unused and has no effect\n" +#~ "#deprecated\n" +#~ "fn main {\n" +#~ "}\n" +#~ msgstr "" +#~ "// 这个属性标注没有效果,是无用的\n" +#~ "#deprecated\n" +#~ "fn main {\n" +#~ "}\n" + +#~ msgid "Here are some pitfalls when writing inline wasm:" +#~ msgstr "下面是写内联 wasm 代码时一些常见的问题:" + +#~ msgid "all variables and functions must start with `$`" +#~ msgstr "内联 wasm 中的所有变量名和函数名必须以 `$` 开头" + +#~ msgid "" +#~ "pub(open) trait Foo {\n" +#~ " foo(Self) -> Unit = _\n" +#~ "}\n" +#~ "\n" +#~ "impl Foo with foo(_) {\n" +#~ "}\n" +#~ "\n" +#~ "test {\n" +#~ " let x : Int = 0\n" +#~ " Foo::foo(x)\n" +#~ "}\n" +#~ msgstr "" + +#~ msgid "impl Foo for Int\n" +#~ msgstr "" + +#~ msgid "" +#~ "struct Point {\n" +#~ " x : Int\n" +#~ " y : Int\n" +#~ "}\n" +#~ "\n" +#~ "fn f(p : Point) -> Unit {\n" +#~ " let { x, y, .. } = p\n" +#~ " println(x + y)\n" +#~ "}\n" +#~ "\n" +#~ "test {\n" +#~ " f({ x: 1, y: 2 })\n" +#~ "}\n" +#~ msgstr "" + +#~ msgid "" +#~ "/// @alert deprecated \"Use `greet` instead\"\n" +#~ "fn greeting() -> String {\n" +#~ " \"Hello!\"\n" +#~ "}\n" +#~ "\n" +#~ "fn greet(name~ : String = \"\") -> String {\n" +#~ " if name != \"\" {\n" +#~ " \"Hello!\"\n" +#~ " } else {\n" +#~ " \"Hello, \\{name}!\"\n" +#~ " }\n" +#~ "}\n" +#~ "\n" +#~ "fn main {\n" +#~ " println(greeting())\n" +#~ " // ^~~~~~~~ Warning (Alert " +#~ "deprecated): Use `greet` instead(2000)\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "// ... code in the example above ...\n" +#~ "fn main {\n" +#~ " println(greet(name=\"world\"))\n" +#~ "}" +#~ msgstr "" +#~ "// ... 上方例子中的代码 ...\n" +#~ "fn main {\n" +#~ " println(greet(name=\"world\"))\n" +#~ "}" + +#~ msgid "" +#~ "{\n" +#~ " // ... other fields in the file\n" +#~ " \"alert-list\": \"-deprecated\"\n" +#~ "}" +#~ msgstr "" +#~ "{\n" +#~ " // ... 文件中的其他字段\n" +#~ " \"alert-list\": \"-deprecated\"\n" +#~ "}" + +#~ msgid "" +#~ "fn main() -> Unit { // Error: " +#~ "Main function must have no arguments " +#~ "and no return value.\n" +#~ " println(\"Hello, world!\")\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "fn greet { // Error: Missing " +#~ "parameters list. Add `()` if function" +#~ " `greet` has 0 parameter.\n" +#~ " println(\"Hello, world!\")\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "fn greet() {\n" +#~ " println(\"Hello, world!\")\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "fn greet(name : String = \"World\") -> Unit {\n" +#~ " // ^ Error: Only " +#~ "labelled arguments can have default " +#~ "value.\n" +#~ " println(\"Hello, \" + name + \"!\")\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "fn greet(name~ : String = \"World\") -> Unit {\n" +#~ " println(\"Hello, \" + name + \"!\")\n" +#~ "}\n" +#~ "\n" +#~ "fn main {\n" +#~ " // Can be called as:\n" +#~ " greet() // Uses default value \"World\"\n" +#~ " greet(name=\"Alice\") // Uses provided value \"Alice\"\n" +#~ "}" +#~ msgstr "" +#~ "fn greet(name~ : String = \"World\") -> Unit {\n" +#~ " println(\"Hello, \" + name + \"!\")\n" +#~ "}\n" +#~ "\n" +#~ "fn main {\n" +#~ " // 可以这样调用:\n" +#~ " greet() // 使用默认值 \"World\"\n" +#~ " greet(name=\"Alice\") // 使用提供值 \"Alice\"\n" +#~ "}" + +#~ msgid "" +#~ "fn greet(name: String) -> Unit {\n" +#~ " println(\"Hello, \" + name + \"!\")\n" +#~ "}" +#~ msgstr "" + +#~ msgid "The parameter already has default value `None`." +#~ msgstr "参数已经有默认值 `None`。" + +#~ msgid "In MoonBit, the optional parameter has one of the two following forms:" +#~ msgstr "在 MoonBit 中,可选参数有如下两种形式:" + +#~ msgid "Optional parameter with default value:" +#~ msgstr "有参数的可选值:" + +#~ msgid "" +#~ "fn f(a~ : Int = 0) -> Unit {\n" +#~ " // ...\n" +#~ "}\n" +#~ msgstr "" + +#~ msgid "" +#~ "Optional parameter with no default " +#~ "value. In this case, when the " +#~ "parameter is not provided, it is " +#~ "`None` by default." +#~ msgstr "无参数的可选值。在这种情况下,如果参数没有提供,则默认为 `None`。" + +#~ msgid "" +#~ "fn f(a? : Int) -> Unit { // a has type Int?\n" +#~ " // ...\n" +#~ "}\n" +#~ msgstr "" +#~ "fn f(a? : Int) -> Unit { // a 的类型为 Int?\n" +#~ " // ...\n" +#~ "}\n" + +#~ msgid "" +#~ "Therefore, if the optional parameter has" +#~ " a default value of `None`, it " +#~ "is redundant and should be removed." +#~ msgstr "因此,如果可选参数的默认值为 `None`,提供默认值就是多余的,应该删除。" + +#~ msgid "" +#~ "fn f(a? : Int = None) -> " +#~ "Unit { // Error: The parameter a?" +#~ " already has default value `None`.\n" +#~ " println(a)\n" +#~ "}" +#~ msgstr "" + +#~ msgid "Remove the `= None` part from the optional parameter." +#~ msgstr "从可选参数中移除 `= None` 部分" + +#~ msgid "" +#~ "fn f(a? : Int) -> Unit {\n" +#~ " println(a)\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "enum V {\n" +#~ " A, // Error: Expecting a newline" +#~ " or `;` here, but encountered another" +#~ " delimiter `,`.\n" +#~ "}\n" +#~ "\n" +#~ "struct S {\n" +#~ " a : Int, // Error: Expecting " +#~ "a newline or `;` here, but " +#~ "encountered another delimiter `,`.\n" +#~ "}\n" +#~ "\n" +#~ "type! E {\n" +#~ " A, // Error: Expecting a newline" +#~ " or `;` here, but encountered another" +#~ " delimiter `,`.\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "enum V {\n" +#~ " A\n" +#~ "}\n" +#~ "\n" +#~ "struct S {\n" +#~ " a : Int\n" +#~ "}\n" +#~ "\n" +#~ "type! E {\n" +#~ " A\n" +#~ "}" +#~ msgstr "" + +#~ msgid "Current loop has result type mismatch with `break` argument." +#~ msgstr "当前循环的结果类型与 `break` 参数的类型不匹配。" + +#~ msgid "" +#~ "This error occurs when the type of" +#~ " the argument provided to a `break`" +#~ " statement does not match the " +#~ "expected result type of the loop. " +#~ "In MoonBit, loops can have result " +#~ "types, and when using `break` with " +#~ "an argument, that argument's type must" +#~ " match the loop's result type. When" +#~ " an argument is not provided, the " +#~ "loop's result type must be `Unit`." +#~ msgstr "" +#~ "当提供给 `break` 语句的参数类型与循环的预期结果类型不匹配时,会发生此错误。在 MoonBit" +#~ " 中,循环可以有结果类型,当使用带有参数的 `break` " +#~ "时,该参数的类型必须与循环的结果类型匹配。当没有提供参数时,循环的结果类型必须是 `Unit`。" + +#~ msgid "This mismatch can happen in two ways:" +#~ msgstr "此不匹配可能发生在两种方式中:" + +#~ msgid "" +#~ "The loop expects a value of a " +#~ "certain type, but `break` is called " +#~ "with no argument" +#~ msgstr "循环期望一个特定类型的值,但 `break` 没有提供参数" + +#~ msgid "" +#~ "The loop expects a value of type" +#~ " A, but `break` is called with " +#~ "an argument of type B" +#~ msgstr "循环期望一个类型为 A 的值,但 `break` 提供了类型为 B 的参数" + +#~ msgid "For loops with result types, you must ensure that:" +#~ msgstr "对于具有结果类型的循环,您必须确保:" + +#~ msgid "All `break` statements provide an argument of the correct type" +#~ msgstr "所有 `break` 语句都提供正确类型的参数" + +#~ msgid "The `else` branch (if present) returns a value of the correct type" +#~ msgstr "`else` 分支(如果存在)返回正确类型的值" + +#~ msgid "" +#~ "pub fn g(x: Int) -> Int {\n" +#~ " for i in 0..=x {\n" +#~ " if i == 42 {\n" +#~ " break\n" +#~ "// ^^^^^ Error: Current loop has " +#~ "result type Int, but `break` is " +#~ "supplied\n" +#~ "// with no arguments.\n" +#~ " }\n" +#~ " } else {\n" +#~ " 0\n" +#~ " }\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "Add an argument to the `break` " +#~ "statement that matches the loop's result" +#~ " type. For example," +#~ msgstr "向 `break` 语句添加一个与循环结果类型匹配的参数。例如:" + +#~ msgid "" +#~ "pub fn g(x: Int) -> Int {\n" +#~ " for i in 0..=x {\n" +#~ " if i == 42 {\n" +#~ " break i\n" +#~ " }\n" +#~ " } else {\n" +#~ " 0\n" +#~ " }\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "Remove the `else` branch if you " +#~ "don't need to return a value from" +#~ " the loop." +#~ msgstr "如果不需要从循环中返回值,请删除 `else` 分支。" + +#~ msgid "" +#~ "pub fn g(x: Int) -> Unit {\n" +#~ " for i in 0..=x {\n" +#~ " if i == 42 {\n" +#~ " break\n" +#~ " }\n" +#~ " }\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "fn f(opt~ : Int = 4) -> Unit {\n" +#~ " println(\"opt: \\{opt}\")\n" +#~ "}\n" +#~ "\n" +#~ "fn main {\n" +#~ " let opt = Some(42)\n" +#~ " f(opt?) // Error: This form of" +#~ " application is invalid for argument " +#~ "opt~, because it is not declared " +#~ "with opt? : _.\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "fn f(opt? : Int) -> Unit {\n" +#~ " let opt = match opt {\n" +#~ " Some(opt) => opt\n" +#~ " None => 4\n" +#~ " }\n" +#~ " println(\"opt: \\{opt}\")\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "fn main {\n" +#~ " let opt = Some(42)\n" +#~ " let opt = match opt {\n" +#~ " Some(opt) => opt\n" +#~ " None => 4\n" +#~ " }\n" +#~ " f(opt~)\n" +#~ "}" +#~ msgstr "" + +#~ msgid "" +#~ "const A : Int = B + 1\n" +#~ "const B : Int = A + 1\n" +#~ "\n" +#~ "fnalias f = g\n" +#~ "fnalias g = f\n" +#~ "\n" +#~ "typealias T1 as T2\n" +#~ "typealias T2 as T1\n" +#~ "\n" +#~ "traitalias I1 as I2\n" +#~ "traitalias I2 as I1" +#~ msgstr "" +