riff-lang / riff

The Riff programming language
https://riff.cx
BSD Zero Clause License
23 stars 1 forks source link

Method syntax #60

Open darrylabbate opened 1 year ago

darrylabbate commented 1 year ago

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(...):

  1. If x is a table, attempt the lookup of y in table x a. If y exists and is a function, invoke the function with the arguments untouched b. If y does not exist (or is not a function?), goto step 2.
  2. If x is not a table, attempt a local/global lookup for the variable y a. If y exists in scope and is a function, invoke y(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/).

darrylabbate commented 1 year ago

A note on Lua's syntax for comparison (ref):

A call v:name(args) is syntactic sugar for v.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.

darrylabbate commented 1 year ago

Another thought: Calling methods on literals should also be supported. Ex:

'string'.num(36)
darrylabbate commented 1 year ago

an implicit self or this inside functions

This would require: