Based on a recent discussion on Slack, and on some related slight terminological
changes in the documentation of the Aleo instructions, this commit similarly
improves the Leo nomenclature for expressions involving the logical operators.
The attribute 'bitwise' for `&` and `|` and `^` has been dropped, since the
operations also operate on booleans besides integers.
Given that the operation and method names `or` and `xor` for inclusive and
exclusive disjunctions (as opposed to `ior` and `xor`), the unqualified
'disjunction' now refers to the inclusive one.
The non-strict `&&` and `||` are now called 'conditional' (as done in other
languages), and thus the ternary one has been expanded to 'conditional ternary'.
This does not change the Leo language; it just improves the nomenclature derived
from the grammar.
These are for the recently added shift and bitwise logical operators. They
should have been also included in the rule `symbol` for symbol tokens. This
commit remedies that.
These would flatten to nothing, component-wise.
This requirement actually slighly simplifies the grammar, avoiding the `[ ... ]`
around the circuit component declarations (in a circuit declaration) or the
circuit component initializers (in a circuit expression).
Also renames pre-existing (generic) function calls to 'free function calls', now
that we are effectively introducing a new kind of functions, namely (associated)
static functions, distinguished from free (i.e. non-associated) functions.
Also introduces notion of named type, as a type that has a name, which may be
either a keyword (e.g. `u8`, `address`) or an identifier (e.g. `Pedersen64`).
Introduce the notion of postfix expression in the grammar, which will also go
well with some expected upcoming extensions to Leo.
This does not change the Leo language. It does not necessarily involve modifying
the parser. It merely reorganizes some rules slightly.
This adds shift (`<<` `>>`) and bitwise logical (`&` `|` `^`) operators.
Their precedence is between the additive and ordering operations, in this order
(higher to lower):
- ... others, to additive
- `<<` and `>>`
- `&`
- `|`
- `^`
- ... others, from ordering
This is consistent with Rust, but not with C and Java, both of which make the
bitwise logical operators lower-precedence than equalities.
The previous ABNF rule names for `conjunctive-expression` and
`disjunctive-expression` have been renamed to be more consistent with the newly
added ones. Also, the rule names "abbreviate" 'conjunctive' and 'disjunctive'
with 'and' and 'or', otherwise the names were a bit too long.
Since these are a method-like syntax for unary and binary operators (as in fact
these are represented as operators in the AST), the nomenclature 'operator call'
seems appropriate, at least for now. There is no need yet to introduce notions
of associated functions (and constants).
The rules explicitly distinguish between unary and binary ones, corresponding to
unary and binary operators. This lets us exclude right away calls with too many
arguments, and gives us a way to distinguish the two kinds.
A trailing comma is allowed at the end of the one argument of binary operator
calls, if one is really inclined to use it, just for syntactic consistency with
other calls (namely, function calls).
Prohibit line terminators inside string literals. (This does not prohibit
escapes for line feed and/or carriage return; it prohibits actual line feeds and
carriage returns, which would break the string literal across lines.)
Explicate line terminators in block comments, so that an accurate line count can
be obtained more readily from the CSTs. (This is more relevant to the ACL2
formal development than to the Rust implementation, which does not have explicit
CSTs.)
Also reorder slightly some rules within the file.
In input and output files, literals are actually insufficient to represent the
most negative values of the signed integer types.
Given that we are likely to need richer forms of input and output expressions
anyways, at this point it seems best to allow any expression at the grammatical
level, and add static semantic requirements on the allowed expressions. As done
with all the other requirements, these will be stated in the Leo Reference,
formalized in ACL2, and enforced in the Leo compiler.
This is for the current simplified version of Leo. When the main function is
executed, it returns a value. According to this grammar, the output (i.e.
`.out`) file contains a single literal, which describes the output value,
preceded by an `[output]` title. This may be extended in the future.
Since we only allow four kinds of input section titles, corresponding to the
public/private/constant/const characterization of function inputs, it seems
beneficial to put this into the grammar, where it is easily captured.
Note that the previous version of the rule, which uses `identifier`, is not
quite right, because, for example, `public` is not an identiifer (it is a
keyword). So the rule would have to be modified anyways.
Given that the Leo Reference explains well that the format string grammar
applies to the character sequence after processing escapes, we do not need to
say this here. Instead, we just explain the rule similarly to what we do for
others.
This mentions embeddings and isolates besides overrides, in accordance with the
official terminology at https://www.unicode.org/reports/tr9/.
This update was discussed and agreed with @bendyarm.
Note: The Leo Reference includes text explaining these exclusions, with links to
the document above as well to the web site and paper about Trojan source
exploits.
This is the (sub)grammar for input files. It is an initial draft, written based
on the Notion page 'Leo Input File Doc/Spec'. This should be compared with the
currently implemented parser of input (i.e. .in) files.
As the Leo Reference will describe (that part has not been written yet), the
input grammar is based on the lexical grammar, i.e. an input file consists of
tokens, comments, and whitespace. However, only some tokens (compared to the
syntactic grammar for Leo code files) are used, namely the ones reachable from
the `input-file` nonterminal.
Currently (i.e. im this initial version of Leo) `input-type` is (any) `type` and
`input-expression` is just a `literal`, but these may evolve as we extend the
language (e.g. we'll probably disallow circuit types and allow tuple and array
constructions). The intent is that `input-type` will be a subset of `type` and
that `input-expression` will be a subset of `expression`.
This does not change the language. It just adds a rule to name binary
expressions explicitly. This makes the relation with ternary expressions
clearer, and as usual it explicates more terminology.
* [ABNF] Add a rule for function calls.
This does not change the language. It just slightly reformulates the grammar for
greater clarity and to help establish a nomenclature for constructs.
Also remove a trailing space.
* [ABNF] Re-generate markdown.
Co-authored-by: collin <16715212+collinc97@users.noreply.github.com>
This mirrors the structure of the rules for types, where there is an
`integer-type` consisting of `unsigned-type` and `signed-type`.
There is no change to the language.
In the currently restricted version of Leo, this is necessary for the numerals
in affine group literals to be tokens.
No change necessary to the lexer/parser, which already handle this properly.
Expression statements were removed from the rule for statements, but the rule
for expression statements itself had not been removed. This commit fixes that.
Since we do not have tuple in this version of Leo, we cannot have expression
statements, because normally expressions used as statements would have to return
the empty tuple, since we disallow throwing away values in Leo.
Since this pre-testnet3 version of Leo does not support tuple types, and since a
missing function type is meant to be interpreted as the empty tuple type `()` in
future versions of Leo, it seems appropriate to require a function output type
in this version of Leo. We could instead default to a different type
(e.g. bool), but it seems cleaner to require it for now, and make it optional
later.
This mirrors, in pre-testnet3, the change in PR #1699 in testnet3.
Since in pre-testnet3 we have fewer kinds expressions, the category of postfix
expressions disappears altogether with this re-classification.
This does not change the language. It only renames two related rule names:
function-input => named-parameter
function-inputs => named-parameters
According to the new nomenclature, there are function parameters, which are self
parameters and named parameters: the nomenclature is clear and "symmetric".
The problem with the previous nomenclature is that both self and named
parameters are inputs, not just the named ones.
These are needed to make parsing unambiguous. They require the test of a
conditional statement and the ending bound of a loop statement to not be or
start with a circuit expression.
This is obtained by removing features from the grammar currently in the testnet3
branch.
The documentation comments have been removed to keep the file smaller and
simpler to read, as readers of this file should be already familiar with Leo.
Furthermore, that documentation material is being moved to the Leo Language
Reference.
This commit also folds the format string grammar (for console print strings)
into (a separate section of) the same file, again for simplicity. The previous
separate small file (and generated markdown) for format strings has thus been
removed.
Given that arithmetic literals are now all typed in the grammar, we need
numerals to be listed as tokens. Otherwise, array dimensions and tuple indices
would not be tokens, but they must be.
This applies both to the rule name and to the terminology used for that, namely
for a non-empty sequence of decimal digits.
While 'natural' was meant to describe a natural number (i.e. a non-negative
integer: 0, 1, 2, ...), it is perhaps not a familiar term to many users.
On the other hand, 'integer', while often used in programming languages for this
kind of thing, is not ideal as integers may be negative.
Also, assuming type inference, a lone numeral like `17` may actually not denote
an integer number at all, because it may actually denote a group element if type
inference turns it into `17group`, and group elements are not integers.
All in all, 'numeral' seems like a good term, also according to its dictionary
definition. It is used in the Java grammar to denote this kind of thing, for
instance.
If, in the future, we want to allow hexadecimal, octal, or binary notation, we
could rename this to `decimal-numeral`, introduce `hexadecimal-numeral`,
`octal-numeral`, and `binary-numeral`, and `numeral` as the union of these.
This does not change the grammar. It merely updates some text in the comments,
which shows a rule that was changed at some point but its copy in the comments
was not properly updated.
Thanks to @bendyarm for noticing this.
This removes the rule for `integer` and uses `natural` for all numeric literals.
Otherwise, lexing would be context-dependent for no good reason.
This is consistent with the lexer and parser of the Leo compiler.
Note that, for instance, `-1field` is not a literal, but rather a unary
expression where `-` is applied to the literal `1field`. This is consistent with
other languages too.
Types are now required in variable and constant declarations (including for loop
variables), and for literals (i.e. there are no longer untyped literals).
This "merges" the two previous slightly different notions of array type
dimensions and array expression dimension(s) into one notion of array
dimensions, in which the dimensions have to be natural numbers. (Previously,
array type dimensions were allowed to be unspecified (via underscores), while
array expression dimensions had to be specified.)