mirror of
https://github.com/luau-lang/rfcs.git
synced 2025-05-04 10:43:48 +01:00
Improve presentation, fix ebnf syntax, and address comments.
This commit is contained in:
parent
b93837e544
commit
f8d047f294
1 changed files with 43 additions and 25 deletions
|
@ -6,51 +6,69 @@ This RFC proposes a syntax for function attribute parameters. This is a follow u
|
|||
|
||||
## Motivation
|
||||
|
||||
The [Attributes](./syntax-attributes-functions.md) RFC provides a syntax for parameterless function attributes. This suffices for some potential use cases, such as `@native`, and `@inline`. However, other potential cases such as `@deprecated` will benefit from an expressive attribute syntax that allows parameters to be supplied. We can use the parameters to provide the name of the function to be used in place of the deprecated function, and the reason for deprecation. This information can be used to generate informative deprecation warning messages. Another potential use case could be an `@unroll` attribute for loop unrolling which could use a numeric parameter for specifying the number of iterations to be unrolled. This would also require supporting attributes on loops, which would be a topic of discussion for a separate RFC. It might be desirable to allow these attributes to assume a default value for parameters not provided explicitly.
|
||||
The [Attributes](./syntax-attributes-functions.md) RFC provides a syntax for parameterless function attributes. This suffices for some potential use cases, such as `@native`, and `@inline`. However, other potential cases such as `@deprecated` will benefit from an expressive attribute syntax that allows parameters to be supplied. We can use the parameters to provide the name of the function to be used in place of the deprecated function, and the reason for deprecation. This information can be used to generate informative deprecation warning messages. Another potential use case could be an `@unroll` attribute for loop unrolling which could use a numeric parameter for specifying the number of iterations to be unrolled. This would also require supporting attributes on loops, which would be a topic of discussion for a separate RFC.
|
||||
|
||||
## Design
|
||||
|
||||
The following syntax is proposed for attributes:
|
||||
|
||||
```ebnf
|
||||
parameter-table = '{' '}'
|
||||
| '{' parameter (sep parameter)* '}'
|
||||
table ::= '{' [fieldlist] '}'
|
||||
fieldlist ::= field {fieldsep field} [fieldsep]
|
||||
field ::= Name '=' literal | literal
|
||||
fieldsep ::= ',' | ';'
|
||||
|
||||
sep = ',' | ';'
|
||||
literal ::= 'nil' | 'false' | 'true' | Number | String | table
|
||||
|
||||
parameter = literal
|
||||
| NAME '=' literal
|
||||
parattr ::= NAME [literal]
|
||||
|
||||
literal = BOOLEAN | NUMBER | STRING | NIL | parameter-table
|
||||
attribute ::= '@' NAME | '@[' parattr {',' parattr} ']'
|
||||
|
||||
list-attribute = NAME parameter-table
|
||||
| NAME
|
||||
|
||||
attribute = '@' NAME
|
||||
| '@[' list-attribute (',' list-attribute)* ']'
|
||||
attributes ::= {attribute}
|
||||
```
|
||||
|
||||
In Luau scripts, attributes are specified before the `function` keyword in function definitions. In declaration files, attributes are specified in function type declarations, before the `function` keyword in `declare function (type, ...) : type` syntax, and before the `(` in the `name: (type, ...) : type` syntax. The primary extension proposed to the [Attributes](./syntax-attributes-functions.md) RFC is a new delimited syntax `@[]` for specifying multiple comma-separated attributes with parameters supplied through an optional Luau table. The important features are:
|
||||
Attributes can appear before `function` and `local function` statements, augmenting the allowed statement syntax as follows:
|
||||
|
||||
1. Inside the attribute list, `@[]`, attribute names are not allowed to have a leading `@`.
|
||||
2. Attribute lists cannot be nested. Attributes cannot be specified on attribute parameters.
|
||||
3. Attributes inside `@[]` are separated by a `,`.
|
||||
4. Attributes inside `@[]` are allowed to take an optional table of parameters.
|
||||
5. The "parameter table" is a Luau table whose entries specify attribute parameters, with or without names, separated by commas or semicolons.
|
||||
6. A parameter can be any literal value: `BOOLEAN`, `NUMBER`, `STRING`, `NIL`, or a `parameter-table`. Attributes can be seen as a way of providing tagged metadata with no evaluation semantics of their own. With that in mind, we only allow these syntactic categories because they evaluate to themselves. This is also the reason we disallow entries of the form `[exp1] = [exp2]` in parameter table, since this would require evaluating `exp1` at construction time. `nil` is allowed for the sake of generality and completeness.
|
||||
7. Attributes can be specified before function declarations in multiple ways: `@attr1 @[attr2, attr3{2, "hi"}]`, `@attr1 @attr2 @[attr3{2, "hi"}]`, `@attr1 @[attr3{2, "hi"}] @attr2`, and `@[attr1, attr2, attr3{2, "hi"}]` are all equivalent.
|
||||
8. An attribute with an empty parameter list can be equivalently specified without one, i.e., `@[attr{}]` is same as `@attr`.
|
||||
```ebnf
|
||||
stat ::= attributes 'function' funcname funcbody
|
||||
stat ::= attributes 'local' 'function' Name funcbody
|
||||
```
|
||||
|
||||
The parser is responsible for for enforcing the syntax specified by this RFC and ensuring that attributes are not repeated on a definition or a declaration. The number and type of parameters accepted by a particular attribute will be specified by its own RFC, and enforced by the relevant component of the implementation (typechecker, compiler, etc.), after parsing.
|
||||
Attributes can also used in declaration files with the following syntax:
|
||||
|
||||
We currently have an ad-hoc implementation of `@checked` attribute, used in declaration files. It is specified in two ways:
|
||||
```ebnf
|
||||
type ::= Type | Name ':' Type
|
||||
decl ::= attributes 'declare' 'function' '(' {type} ')' : Type
|
||||
decl ::= 'declare' Name ':' '{' {Name ':' attributes '(' {type} ')' '->' Type} '}'
|
||||
```
|
||||
|
||||
The primary extension proposed to the [Attributes](./syntax-attributes-functions.md) RFC is an attribute list, `@[]`, for specifying multiple comma-separated attributes with an optional literal parameter, and, an attribute syntax for declaration files.
|
||||
|
||||
The important syntactic features are:
|
||||
|
||||
1. Attribute lists cannot be empty; they should have at least one attribute.
|
||||
2. Attributes inside attribute lists are separated by a `,`.
|
||||
3. Attribute names cannot have a leading `@` inside attribute list.
|
||||
4. Attribute lists cannot be nested.
|
||||
5. Attributes cannot be used inside an attribute parameter.
|
||||
6. Only attributes inside attribute lists can take a parameter, standalone attributes cannot.
|
||||
7. An attribute parameter is a Luau literal: `true`, `false`, `nil`, `Number`, `String`, or a `table` composed of these literals with optional names. A trailing field separator is allowed.
|
||||
8. Standalone and list style attributes can be mixed arbitrarily: `@attr1 @[attr2, attr3{2, "hi"}]`, `@attr1 @attr2 @[attr3{2, "hi"}]`, `@attr1 @[attr3{2, "hi"}] @attr2`, and `@[attr1, attr2, attr3{2, "hi"}]` are all legal and equivalent.
|
||||
|
||||
Currently there is an ad-hoc implementation of `@checked` attribute, used in declaration files. It is specified in two ways:
|
||||
|
||||
1. `declare function @checked abs(n: number): number`
|
||||
2. `writef64: @checked (b: buffer, offset: number, value: number) -> ()`
|
||||
|
||||
To ensure uniformity with the specification of this RFC, declarations using the first style will be modified to use `@checked` attribute before the `function` keyword. Declarations using the second style will remain unchanged.
|
||||
According to the syntax proposed in this RFC, the declarations using the first style will be modified to use `@checked` attribute before `declare` keyword. Declarations in the second style will remain unchanged.
|
||||
|
||||
An alternative parameter syntax would be to implement function-style attribute syntax of the form `@attr(parameters, ...)`, but that would not allow specifying parameter names. Attribute syntax of the form `@attr {...}` will create ambiguity when attributes without parameters are used on tables, should we decide to allow attributes on them in the future. An advantage of the `@[]` syntax is that it provides the `]` delimiter which marks the end of attribute, leaving open the possibility of syntax evolution without introducing parsing ambiguity.
|
||||
Few important factors went in the design of this syntax:
|
||||
|
||||
1. Attributes are a mechanism for providing tagged metadata to the implementation. They are not user-extensible and have no evaluation semantics of their own. Hence, an attribute parameter can only be a literal, i.e., a value that evaluates to itself. This is also the reason we disallow entries of the form `[exp1] = [exp2]` in parameter table, since it would require evaluating `exp1` at construction time.
|
||||
2. Function-style attribute syntax of the form `@attr({parameters})` were initially considered, but dropped becuase they do not allow us to specify parameter names. The optional table parameter proposed in the current syntax lets use specify multiple parameters as table entries, with and without names.
|
||||
3. Using attributes with a table parameter outside attribute list, `@attr {...}`, will create ambiguity when used on tables, should we decide to allow attributes on arbitrary expressions in the future. Hence, the `@[]` delimited syntax was chosen to provide a `]` delimiter which marks the end of attributes, leaving open the possibility of syntax evolution without introducing parsing ambiguity.
|
||||
|
||||
The parser is responsible for for enforcing the syntax specified by this RFC and ensuring that attributes are not repeated on a definition or a declaration. The number and type of parameters accepted by a particular attribute will be specified by its own RFC, and enforced by the relevant component of the implementation (typechecker, compiler, etc.), after parsing.
|
||||
|
||||
## Drawbacks
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue