Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method syntax #60

Open
darrylabbate opened this issue Dec 24, 2022 · 3 comments
Open

Method syntax #60

darrylabbate opened this issue Dec 24, 2022 · 3 comments
Labels
experimental Purely experimental ideas (for now) feature New feature or request language Language features/requests
Milestone

Comments

@darrylabbate
Copy link
Member

darrylabbate commented Dec 24, 2022

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 darrylabbate added feature New feature or request language Language features/requests experimental Purely experimental ideas (for now) labels Dec 24, 2022
@darrylabbate darrylabbate added this to the Riff 0.5 milestone Dec 25, 2022
@darrylabbate
Copy link
Member Author

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
Copy link
Member Author

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

'string'.num(36)

@darrylabbate darrylabbate pinned this issue Dec 26, 2022
@darrylabbate
Copy link
Member Author

an implicit self or this 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
experimental Purely experimental ideas (for now) feature New feature or request language Language features/requests
Projects
None yet
Development

No branches or pull requests

1 participant