For my multidimensional array library, I'm providing syntactic sugar (_, ^, not declaring stepping with |) to allow constructs like these to slice the array:
echo foo[1..3, 2..4] echo foo[2.._, 3] echo foo[^2..0|-2, 3] echo foo[^2..0|-2, _]
From an array foo
Tensor of shape 5x5 of type "int" on backend "Cpu"
|1 1 1 1 1|
|2 4 8 16 32|
|3 9 27 81 243|
|4 16 64 256 1024|
|5 25 125 625 3125|
Results are
echo foo[1..3, 2..4]
Tensor of shape 3x3 of type "int" on backend "Cpu"
|8 16 32|
|27 81 243|
|64 256 1024|
echo foo[2.._, 3]
Tensor of shape 3x1 of type "int" on backend "Cpu"
81|
256|
625|
echo foo[^2..0|-2, 3]
Tensor of shape 2x1 of type "int" on backend "Cpu"
256|
16|
echo foo[^2..0|-2, _]
Tensor of shape 2x5 of type "int" on backend "Cpu"
|4 16 64 256 1024|
|2 4 8 16 32|
This is working fine, however my macro is a huge spaghetti monster (120 lines) of if, elif, else with lots of repetition to handle all the cases. Incriminated code is here
What approach can I use to make this easier on the eyes and maintainable?
There are some nesting levels I could probably do without as I'm calling elif nnk[1].kind == nnkPrefix: or elif nnk[2].kind == nnkInfix: just to check if I can then call nnk[1][0] and nnk[2][0]
I'm reading on Finite State Machine, Component-Entity-System, Chain-of-responsibility pattern, Functional/Declarative DOM/XML tree manipulation to get some inspirations. But apart from Finite State Machine, the last 3 seems like very complicated beasts wrt to my "only" 4 deep nesting.
And wrt to FSM, I don't think I can use that in a macro/AST context, can I?
I would suggest to pre-create trees of NimNodes and then compare them to encountered ones. It may slow down the compilation process but will definitely reduce the cyclomatic complexity of the code.
Another way is to make the syntax rules of the sugar more strict to prevent infixes like this "..|-" and to separate parts of the expression in more obvious way.
It's a bit longer than before (more documentation) but code is flatter, no redundant branches and much more readable in my opinion. End code here.