Closed letmaik closed 9 years ago
Hi!
this function already exists its called list_select(<list ref> <callable>)-> <any...>
though I have to say that the lambda ()-> ...
syntax would ordinarily be used will be reworked because it does not work too well in more complex cases. therefore I suggest you just write plain cmake functions as a string even if the escaped syntax is cumbersome....
set(files filea fileb)
assign(sources = list_select(files "function(_ el)\nreturn(\"\${el}.c\")\nendfunction()"))
assign(headers = list_select(files "function(_ el)\nreturn(\"\${el}.h\")\nendfunction()"))
What's the assign(var = ..)
syntax? Haven't seen that before.
Can you write an example how the lambda syntax would look like with list_select?
Excerpt from the not yet comitted README.md:
Using the map and list functions can be cumbersome. Therefore I have added a universal function called assign()
It allows you to use statements known from other programming languages.
The easiest way to illustrate the usefullness is by example:
Examples
## assign the string value 3 to x - single quotes indicate a value
assign(x = '3')
assert("${x}" EQUAL 3)
## assign a string containing spaces to x (notice the double quoted single quoted string)
assign(x = "'hello there!'")
assert("${x}" STREQUAL "hello there!" )
## assign the result of a function call to x
assign(x = string_length("abcde"))
assert("${x}" EQUAL 5)
## assign x the result of an expression
assign(x = "{id:1}") # the string {id:1} is parsed into a map because is enclosed by {} or []
assertf("{x.id}" EQUAL 1)
## append a value to x
set(x)
assign(x[] = '1')
assign(x[] = '2')
assign(x[] = '3')
assign(x[] = '4')
assert(${x} EQUALS 1 2 3 4)
## reverse x
set(x 1 2 3 4)
assign(x = x[$:0:-1]) # read: assign from x at end to 0 in -1 increments to x
assert(${x} EQUALS 4 3 2 1)
## replace a range of x
set(x 1 2 3 4)
assign(x[1:2] = '5')
assert(${x} EQUALS 1 5 4)
## create a object path if it does not exist by prepending '!'
set(x)
assign(!x.y.z = '3')
assert_matches("{y:{z:3}}" "${x}")
... more examples coming soon
instead of the cmake function in a string I wrote above you could write
(el)-> string_combine('' $el '.c')
## lambda syntax transforms into
function(_ el)
string_combine("" "${el}" ".c")
return_ans()
endfunction()
I do not want you to use it currently because it is really broken and I plan to fix it - so you can be sure that anything you write now will probably not work in the future. However if your willing to update your code in future iterations then go ahead ;)
Thanks, nice work! So only thing I don't like is the double-single
quotes in assign(x = "'hello there!'")
.
yeah I don't like it either however its necessary because of the way cmake works (I can't parse the double quotes).
an alternative would be to only use double quoted strings but that would be ambiguous because "value"
could mean both a variable called value or a "value" as a value itself ;)
so i chose the unambiguous syntax over ease of use.
I thought about it a little to find a way how to not use single quotes. my solution is now that if you want to assign a literal value you can just omit the =
sign. The previous behaviour = 'value'
still works.
example:
assign(!result.a "abc def ghi" "123 432 987")
assertf({result.a} EQUALS "abc def ghi" "123 432 987")
Well, I think this will lead to confusion. What about having two, like assign(!result.a = "abc def ghi" "123 432 987")
for literal things, and eval(!result.a = str_length(foo))
for function evaluation?
I have a list of filenames without file extensions, and now I want to create two new derived lists which each add different file extensions to each list entry. E.g. in pseudocode:
set(files filea fileb) set(sources lists_map(${files}, function(el) {return el ++ ".c"})) set(headers lists_map(${files}, function(el) {return el ++ ".h"}))