On Fri, 2025-06-13 at 09:59 -0700, Andrii Nakryiko wrote: > On Fri, Jun 13, 2025 at 9:48 AM Eduard Zingerman <eddyz87@xxxxxxxxx> wrote: > > > > On Fri, 2025-06-13 at 09:34 -0700, Andrii Nakryiko wrote: > > > On Wed, Jun 11, 2025 at 5:21 AM Eduard Zingerman <eddyz87@xxxxxxxxx> wrote: > > > > > > > > What do you think about a more recursive representation for presets? > > > > E.g. as follows: > > > > > > > > struct rvalue { > > > > long long i; /* use find_enum_value() at parse time to avoid union */ > > > > }; > > > > > > > > struct lvalue { > > > > enum { VAR, FIELD, ARRAY } type; > > > > union { > > > > struct { > > > > char *name; > > > > } var; > > > > struct { > > > > struct lvalue *base; > > > > char *name; > > > > } field; > > > > struct { > > > > struct lvalue *base; > > > > struct rvalue index; > > > > } array; > > > > }; > > > > }; > > > > > > > > struct preset { > > > > struct lvalue *lv; > > > > struct rvalue rv; > > > > }; > > > > > > > > It can handle matrices ("a[2][3]") and offset/type computation would > > > > be a simple recursive function. > > > > > > > > > > Why do we need recursion, though? All we should need is an array specs > > > of one of the following types: > > > > > > a) field access by name > > > a.1) we might want to distinguish array field vs non-array field > > > to better catch unintended user errors > > > b) indexing by immediate integer > > > c) indexing by symbolic enum name (or we can combine b and c, > > > whatever works better). > > > > > > And that's all. And it will support multi-dimensional arrays. > > > > > > We then process this array one at a time. Each *step* itself might be > > > recursive: finding a field by name in C struct is necessarily > > > recursive due to anonymous embedded struct/union fields. But other > > > than that, it's a simple sequential operation. > > > > > > So unless I'm missing something, let's not add data recursion if it's > > > not needed. > > > > Recursive representation I simpler in a sense that you need only one > > data type. W/o recursion you need to distinguish between container > > data type that links to each constituent. > > So you have this tagged union of three different types some of which > are self-referential (struct lvalue *). Is that what is simpler than > an array of a similarly tagged union, but with no `struct lvalue *` > recursive data pointers? How so? The following: struct rvalue { long long i; const char *enum; }; struct field_access { enum { FIELD, ARRAY } type; union { struct { char *name; } field; struct { struct rvalue index; } array; }; }; struct preset { struct field_access *atoms; int atoms_cnt; const char *var; struct rvalue rv; }; Is logically more complex data structure, because it has two levels for expression computation: to compute single offset and to drive a loop for offset accumulation. > > Plus in a computation function you need to distinguish first step from > > all others. Recursive organization simplifies both data types and > > computation function. > > Not sure I follow. You have two situations, and it doesn't matter > whether it's a first or not first element. It's either lookup by field > name or indexing using integer or enum. In the latter case we should > have an active "current type" of array kind we are working with (so > yes, we need error checking, but just like with a recursive approach). > > Maybe I'm slow, but I don't see how recursivity is making anything > simpler, sorry.