var arr2 = arr[2:0:2, 3:0:1, 2:0:2]
I can get this to work if I pass the argument as a string, i.e. var arr2 = arr["2:0:2, 3:0:1, 2:0:2"] by using the following macro (simplified)
macro `[]`[T](arr: ArrayView[T], e: string): expr =
var args = split(e.strVal, ",")
var code = $arr & "["
for i in 0.. <len(args):
var ixs = split(args[i], ":")
for j in 0.. <len(ixs):
if j != len(ixs)-1:
code = code & ixs[j] & ".. "
else:
code = code & ixs[j]
if i != len(args)-1:
code = code & ","
code = code & "]"
parseExpr(code)
However, is there a way to remove the quotes from the call? In other words, I don't want to call using a string "2:0:2, 3:0:1, 2:0:2", but instead I want to call using 2:0:2, 3:0:1, 2:0:2.
I realize that the latter is not a valid expression. However, I'm hoping that there's something in the macro system that can be called when parsing fails (so that I can parse it myself) or when the parsed expression does not match the signature of any known proc.
: is a special token in Nim, so you can't use it there. With another symbol it should work. You'll end up parsing this AST using the macros module:
import macros
dumpTree:
var arr2 = arr[2!0!2, 3!0!1, 2!0!2]
StmtList
VarSection
IdentDefs
Ident !"arr2"
Empty
BracketExpr
Ident !"arr"
Infix
Ident !"!"
Infix
Ident !"!"
IntLit 2
IntLit 0
IntLit 2
Infix
Ident !"!"
Infix
Ident !"!"
IntLit 3
IntLit 0
IntLit 1
Infix
Ident !"!"
Infix
Ident !"!"
IntLit 2
IntLit 0
IntLit 2
x[0..1|2, 3..4|4]
x[0..1|+2, 3..4|-4]
x[0\0\2]
x[0~0~2, 0~3~4]
#var revarr = arr[2|0|-1, 3|0|-1, 2|0|-1] # compiler yells that |- is not an operator!
var revarr = arr[2|0| -1, 3|0| -1, 2|0| -1]
var revarr = arr[2..0| -1, 3..0| -1, 2..0| -1]
var revarr = arr[2..0.. -1, 3..0.. -1, 2..0.. -1]
var revarr = arr[(2,0,-1), (3,0,-1), (2,0,-1)]
Minus signs makes things particularly ugly because I need to separate them with a space. I guess I could always explicitly define a separate operator, e.g. |-.
More importantly, I want more syntactic sugar like we see in numpy:
var revarr = arr[2|0| -1, |, 2|0| -1]
var revarr = arr[..., 2|0| -1]
It doesn't seem to be possible to define an operator | that takes zero args, and likewise for .... Any suggestions?
Well yes, I would introduce |+ and |- for positive and negative steps (as well as ..|+ and ..|- for nicer composition). IMHO it's more beautiful than Python's ':'. ;-)
It doesn't seem to be possible to define an operator | that takes zero args, and likewise for .... Any suggestions?
I would use const all = 0..high(int):
arr[all, 2..|-1]
(Or maybe the underscore: arr[_, 2..|-1])