|
Jay Carlson <nop@nop.com> wrote: > [An ongoing series of "don't repeat yourself" peeves.] > > On Mar 23, 2014 9:50 AM, "Roberto Ierusalimschy" > <roberto@inf.puc-rio.br> wrote: > > > The traditional method is this: > > > >  local buffer = {}  -- create a buffer > > > >  buffer[#buffer + 1] = x   -- add values > > LambdaMOO[1] has sugar for this: > > buffer[# + 1] = x > > in which # is shorthand for length() of the innermost subscripted > _expression_. Since MOO lists are immutable and length() cannot be > overriden, the semantics can be fuzzy. For Lua it would be something > like > > local tmp = buffer > tmp[#tmp + 1] = x > > and in general calling apply('#', tmp) every place a 0-ary # is > encountered. We already evaluated the object to be indexed, so tmp is > on the stack I think. Anyway > > buffer[#] = nil > > is the other idiom. More generally, this allows addressing from the end > of the array, filling the same niche negative index values do in the > stack API. > > I note with some amusement that #-1 is stack -2 and #-0 is stack -1. > > Jay > > [1]: It's actually buffer[$] in MOO. The syntax "#1234" is a literal > for an objnum, a reference to an object. The system object, #0, has a > bunch of special functions; one is as a registry of public identifiers. > "$foo" is sugar for "#0.foo". > > ---------------------------------------------------- > Alternatives: > > ---------------------------------------------------- Here's an outline of an implementation of this using a token filter (untested): __call = function(t,kf) return kf(t) end Scan token stream until '[' found, then: While scanning TOKENS={ [ exp ] } until matching closing bracket found: . . Replace occurences of { '#' TOK }, where TOK~={ Name | '(' }, . . . . with { '#' __t TOK }. . . If any occurences were found, then replace TOKENS . . . . with { '(' function '(' __t ')' return TOKENS end ')' } sometableexpr[ # + 1 ] --becomes sometableexpr(function (__t) return #__t + 1 end) |