riff
riff copied to clipboard
Method syntax
Placeholder, but also an initial idea:
Instead of adding a dedicated token to emulate method syntax (e.g. Lua's f:read()
== read(f)
), overload .
without removing the syntactic sugar for table lookups with string keys.
For example, in the expression x.y(...)
:
- If
x
is a table, attempt the lookup ofy
in tablex
a. Ify
exists and is a function, invoke the function with the arguments untouched b. Ify
does not exist (or is not a function?), goto step 2. - If
x
is not a table, attempt a local/global lookup for the variabley
a. Ify
exists in scope and is a function, invokey(x, ...)
Unknown: emitting code to handle local scope, i.e. x.y()
and y
exists in a local lexical scope. This is an issue at runtime since local identifiers are essentially thrown away after compilation. Perhaps SIDX[AV]
can be compiled with an optional stack slot if the identifier exists in a local scope. Or a new opcode that falls back to a local vs a global.
This is definitely a lazy way to implement this kind of syntax, but it doesn't require the full implementation of objects or defining "metamethods" for various data types. The obvious motivation here is to allow the ability to clean up nested function calls with chained method-style calls. E.g. split(read(f, 'a'), /\n/)
-> f.read('a').split(/\n/)
.
A note on Lua's syntax for comparison (ref):
A call
v:name(args)
is syntactic sugar forv.name(v,args)
This is in slight contrast to the idea posted above, where v
would only be passed into the function name
if name
didn't exist in table v
(or v
is not a table).
I think I'd prefer to support an implicit self
or this
inside functions; maybe conditionally passing a pointer to a table when invoking functions using a method call syntax for self
/this
to access.
Another thought: Calling methods on literals should also be supported. Ex:
'string'.num(36)
an implicit
self
orthis
inside functions
This would require:
- Dedicated opcodes for
self
lookups, e.g.OP_SELFIDX[AV]
- Some mechanism to pass
self
when invoking a user function- Something other than simply passing as an argument to the interpreter loop