vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.67k stars 2.15k forks source link

bug: closure mapping #17526

Open kendfss opened 1 year ago

kendfss commented 1 year ago

Describe the bug

array mappings with a single argument that is a closure are not correctly transpiled.

Expected Behavior

v run closure_mapping.v
hello, world

Current Behavior

v run closure_mapping.v
==================
/tmp/v_1000/closure_mapping.14895787168227109320.tmp.c:13506: error: '{' expected (got ";")
...
==================
(Use `v -cg` to print the entire error message)

builder error:
==================
C error. This should never happen.

This is a compiler bug, please report it using `v bug file.v`.

https://github.com/vlang/v/issues/new/choose

You can also use #help on Discord: https://discord.gg/vlang

Reproduction Steps

// closure_mapping.v
import gx

fn main() {
  println('hello, world')
}

struct Theme {
    bg_color        gx.Color
    padding_color   gx.Color
    text_color      gx.Color
    game_over_color gx.Color
    victory_color   gx.Color
    tile_colors     []gx.Color
}

fn whitener(d u8) fn (gx.Color) gx.Color {
    return fn [d] (c gx.Color) gx.Color {
        return gx.Color{
            r: c.r + d
            g: c.g + d
            b: c.b + d
            a: c.a
        }
    }
}

const (
    themes                = [
        &Theme{
            bg_color: gx.rgb(55, 55, 55)
            padding_color: gx.rgb(68, 60, 59)
            victory_color: gx.rgb(100, 160, 100)
            game_over_color: gx.rgb(190, 50, 50)
            text_color: gx.white
            tile_colors: ([
                gx.rgb(123, 115, 108),
                gx.rgb(142, 136, 130),
                gx.rgb(142, 134, 120),
                gx.rgb(145, 106, 72),
                gx.rgb(147, 89, 59),
                gx.rgb(147, 74, 57),
                gx.rgb(147, 56, 35),
                gx.rgb(142, 124, 68),
                gx.rgb(142, 122, 58),
                gx.rgb(142, 120, 48),
                gx.rgb(142, 118, 37),
                gx.rgb(142, 116, 27),
            ]).map(whitener(10))
        },
    ]
)
v run closure_mapping.v

Possible Solution

Well the reason is the handling of closure mappings. I don't know enough about C to understand why { is expected where ; is found but the line array_push_noscan((array*)&_t1, &ti); should be something like array_push_noscan((array*)&_t1, &(ti(it)));

Additional Information/Context

I was tinkering with v/examples/2048/2048.v

V version

V 0.3.3 d7a418f

Environment details (OS name and version, etc.)

OS: linux, Linux Mint 20.3 Processor: 4 cpus, 64bit, little endian, Intel(R) Core(TM) i5-5350U CPU @ 1.80GHz CC version: cc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

getwd: /home/kendfss/gitclone/clones/kendfss/vbugs vmodules: /home/kendfss/.vmodules vroot: /home/kendfss/gitclone/clones/vlang/v vexe: /home/kendfss/gitclone/clones/vlang/v/v vexe mtime: 2023-03-06 18:58:06 is vroot writable: true is vmodules writable: true V full version: V 0.3.3 d7a418f

Git version: git version 2.25.1 Git vroot status: weekly.2023.10-dirty .git/config present: true thirdparty/tcc status: thirdparty-linux-amd64 12f392c3

kendfss commented 1 year ago

Apparently this is an advancement from https://github.com/vlang/v/issues/12906

Given that, perhaps more for my use case than the above or https://github.com/vlang/v/issues/14416, this can be circumvented by changing map(whitener(10)) to map(whitener(10)(it)) it may be worth adding a type/syntax error. That would mean that array.map(my_func) would be invalidated in favour of array.map(my_func(it)). Due to backward compatibility violation this should probably be handled by v fmt.

Tagging @medvednikov for a decision. Happy to learn what's necessary to make the changes.