gnolang / gno

Gno: An interpreted, stack-based Go virtual machine to build succinct and composable apps + Gno.land: a blockchain for timeless code and fair open-source
https://gno.land/
Other
839 stars 342 forks source link

feat: named and unnamed type assignment 3 of 3 #2367

Open piux2 opened 1 week ago

piux2 commented 1 week ago

This is the last part of the solution for issue #1141. The 1 of 3 of the solution can be found in PR #1143. The 2 of 3 of the solution can be found in PR #1246

It decomposes function calls that return multiple values in the preprocess.

Here is the problem to solve:

u1, n2 = x()

How do we ensure that the returned multiple values from a function call adhere to named and unnamed type assignment specifications? Additionally, we want to solve this problem during preprocessing instead of at runtime to minimize the impact on runtime performance.

The main ideas:

u1, n2 = x()  << decompose the statement to the following two lines 
// .tmp_1, .tmp_2 := x() 
// u1, n2 = .tmp_1, .tmp_2

then we can apply name and unname type conversion specs to the second line. 
u1, n2 = _tmp_1, _tmp_2

Here are the example code and the explanation

// decompose_filetest.gno
package main

  type nat []int

  func x() (nat, []int) {
    a := nat{1}
    b := []int{2}
    return a, b
  }

  func main() {
    var u1 []int
    var n2 nat

    u1, n2 = x() 
    // .tmp_1, .tmp_2 := x() 
    // u1, n2 = .tmp_1, .tmp_2

    println(u1)
    println(n2)

  }

  // Output:
  // slice[(1 int)]
  // (slice[(2 int)] main.nat)

Here is the simplified recursive tree of the transformation in the preprocess

image

Here are the major steps involved in this decomposition during preprocessing:

 .tmp1, .tmp2 := x() 
 u1, n2 = .tmp_1, .tmp_2

Here are two additional changes to facilitate above.

Contributors' checklist... - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [ ] Updated the official documentation or not needed - [x] No breaking changes were made - [x] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
codecov[bot] commented 1 week ago

Codecov Report

Attention: Patch coverage is 27.58621% with 42 lines in your changes missing coverage. Please review.

Project coverage is 54.61%. Comparing base (e7e47d2) to head (429ddb6).

Files Patch % Lines
gnovm/pkg/gnolang/preprocess.go 10.00% 25 Missing and 2 partials :warning:
gnovm/pkg/gnolang/nodes.go 23.07% 10 Missing :warning:
gnovm/pkg/gnolang/values.go 33.33% 3 Missing and 1 partial :warning:
gnovm/pkg/gnolang/transcribe.go 88.88% 1 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #2367 +/- ## ========================================== - Coverage 54.63% 54.61% -0.03% ========================================== Files 581 581 Lines 77967 78016 +49 ========================================== + Hits 42598 42606 +8 - Misses 32190 32228 +38 - Partials 3179 3182 +3 ``` | [Flag](https://app.codecov.io/gh/gnolang/gno/pull/2367/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gnolang) | Coverage Δ | | |---|---|---| | [gnovm](https://app.codecov.io/gh/gnolang/gno/pull/2367/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gnolang) | `59.97% <27.58%> (-0.09%)` | :arrow_down: | Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=gnolang#carryforward-flags-in-the-pull-request-comment) to find out more.

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.