mirror of
https://github.com/AleoHQ/leo.git
synced 2025-01-02 23:04:12 +03:00
Merge.
This commit is contained in:
commit
4fb3d9cac8
@ -172,6 +172,16 @@ impl AsgConvertError {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn invalid_const_assign(name: &str, span: &Span) -> Self {
|
||||
Self::new_from_span(
|
||||
format!(
|
||||
"failed to create const variable(s) '{}' with non constant values.",
|
||||
name
|
||||
),
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn duplicate_function_definition(name: &str, span: &Span) -> Self {
|
||||
Self::new_from_span(
|
||||
format!("a function named \"{}\" already exists in this scope", name),
|
||||
|
@ -75,6 +75,17 @@ impl<'a> FromAst<'a, leo_ast::DefinitionStatement> for &'a Statement<'a> {
|
||||
|
||||
let value = <&Expression<'a>>::from_ast(scope, &statement.value, type_.clone().map(Into::into))?;
|
||||
|
||||
if matches!(statement.declaration_type, leo_ast::Declare::Const) && !value.is_consty() {
|
||||
let var_names = statement
|
||||
.variable_names
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ,");
|
||||
|
||||
return Err(AsgConvertError::invalid_const_assign(&var_names, &statement.span));
|
||||
}
|
||||
|
||||
let type_ = type_.or_else(|| value.get_type());
|
||||
|
||||
let mut output_types = vec![];
|
||||
|
@ -2,7 +2,7 @@ function main(s: bool, c: address) {
|
||||
const a = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
|
||||
const b = aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r;
|
||||
|
||||
const r = s? a: b;
|
||||
let r = s ? a: b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
function main () {
|
||||
let b = false;
|
||||
const b = false;
|
||||
const a = !b;
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
circuit PedersenHash {
|
||||
parameters: [u32; 512]
|
||||
|
||||
function new(parameters: [u32; 512]) -> Self {
|
||||
function new(const parameters: [u32; 512]) -> Self {
|
||||
return Self { parameters: parameters };
|
||||
}
|
||||
|
||||
function hash(self, bits: [bool; 512]) -> u32 {
|
||||
function hash(self, const bits: [bool; 512]) -> u32 {
|
||||
let digest: u32 = 0;
|
||||
for i in 0..512 {
|
||||
const base = bits[i] ? self.parameters[i] : 0u32;
|
||||
let base = bits[i] ? self.parameters[i] : 0u32;
|
||||
digest += base;
|
||||
}
|
||||
return digest;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import core.unstable.blake2s.Blake2s;
|
||||
|
||||
function main(seed: [u8; 32], message: [u8; 32], expected: [u8; 32]) {
|
||||
const actual = Blake2s::hash(seed, message);
|
||||
let actual = Blake2s::hash(seed, message);
|
||||
|
||||
console.assert(expected == actual);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: field, b: field, c: field) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
function main(a: group) {
|
||||
const b = a;
|
||||
let b = a;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: group, b: group, c: group) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i128, b: i128, c: i128) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i16, b: i16, c: i16) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i32, b: i32, c: i32) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i64, b: i64, c: i64) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i8, b: i8, c: i8) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u128, b: u128, c: u128) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u16, b: u16, c: u16) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u32, b: u32, c: u32) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u64, b: u64, c: u64) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u8, b: u8, c: u8) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main () {
|
||||
let x = 2u8;
|
||||
let y = x;
|
||||
const z = y / 2u8;
|
||||
let z = y / 2u8;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
// Swap two elements of an array.
|
||||
function swap(a: [u32; 2], const i: u32, const j: u32) -> [u32; 2] {
|
||||
const t = a[i];
|
||||
let t = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = t;
|
||||
return a;
|
||||
@ -11,7 +11,7 @@ function main() {
|
||||
const expected: [u32; 2] = [1, 0];
|
||||
|
||||
// Do swap.
|
||||
const actual = swap(arr, 0, 1);
|
||||
let actual = swap(arr, 0, 1);
|
||||
|
||||
// Check result.
|
||||
for i in 0..2 {
|
||||
|
@ -7,7 +7,7 @@ function main(a: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
const r: u32 = a ? 6 : 0;
|
||||
let r: u32 = a ? 6 : 0;
|
||||
|
||||
console.assert(r == b);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
function main(a: bool, b: bool) {
|
||||
const c = a ? true : false;
|
||||
let c = a ? true : false;
|
||||
|
||||
const d = c == b;
|
||||
let d = c == b;
|
||||
}
|
@ -2,7 +2,7 @@ function main(s: bool, c: address) {
|
||||
const a = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
|
||||
const b = aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r;
|
||||
|
||||
const r = s? a: b;
|
||||
let r = s ? a: b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
function main () {
|
||||
let b = false;
|
||||
const b = false;
|
||||
const a = !b;
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
circuit PedersenHash {
|
||||
parameters: [u32; 512]
|
||||
|
||||
function new(parameters: [u32; 512]) -> Self {
|
||||
function new(const parameters: [u32; 512]) -> Self {
|
||||
return Self { parameters: parameters };
|
||||
}
|
||||
|
||||
function hash(self, bits: [bool; 512]) -> u32 {
|
||||
function hash(self, const bits: [bool; 512]) -> u32 {
|
||||
let digest: u32 = 0;
|
||||
for i in 0..512 {
|
||||
const base = bits[i] ? self.parameters[i] : 0u32;
|
||||
let base = bits[i] ? self.parameters[i] : 0u32;
|
||||
digest += base;
|
||||
}
|
||||
return digest;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import core.unstable.blake2s.Blake2s;
|
||||
|
||||
function main(seed: [u8; 32], message: [u8; 32], expected: [u8; 32]) {
|
||||
const actual = Blake2s::hash(seed, message);
|
||||
let actual = Blake2s::hash(seed, message);
|
||||
|
||||
console.assert(expected == actual);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i128, b: i128, c: i128) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i16, b: i16, c: i16) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i32, b: i32, c: i32) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i64, b: i64, c: i64) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: i8, b: i8, c: i8) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u128, b: u128, c: u128) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u16, b: u16, c: u16) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u32, b: u32, c: u32) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u64, b: u64, c: u64) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main(s: bool, a: u8, b: u8, c: u8) {
|
||||
const r = s ? a : b;
|
||||
let r = s ? a : b;
|
||||
|
||||
console.assert(r == c);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
function main () {
|
||||
let x = 2u8;
|
||||
let y = x;
|
||||
const z = y / 2u8;
|
||||
let z = y / 2u8;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
// Swap two elements of an array.
|
||||
function swap(a: [u32; 2], const i: u32, const j: u32) -> [u32; 2] {
|
||||
const t = a[i];
|
||||
let t = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = t;
|
||||
return a;
|
||||
@ -11,7 +11,7 @@ function main() {
|
||||
const expected: [u32; 2] = [1, 0];
|
||||
|
||||
// Do swap.
|
||||
const actual = swap(arr, 0, 1);
|
||||
let actual = swap(arr, 0, 1);
|
||||
|
||||
// Check result.
|
||||
for i in 0..2 {
|
||||
|
@ -7,7 +7,7 @@ function main(a: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
const r: u32 = a ? 6 : 0;
|
||||
let r: u32 = a ? 6 : 0;
|
||||
|
||||
console.assert(r == b);
|
||||
}
|
||||
|
@ -47,6 +47,14 @@ fn test_ternary_basic() {
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ternary_non_const_conditional_fail() {
|
||||
let program_string = include_str!("ternary_non_const_conditional_fail.leo");
|
||||
let error = parse_program(program_string).err().unwrap();
|
||||
|
||||
expect_asg_error(error);
|
||||
}
|
||||
|
||||
// Iteration for i {start}..{stop} { statements }
|
||||
|
||||
#[test]
|
||||
|
@ -1,5 +1,5 @@
|
||||
function main(a: bool, b: bool) {
|
||||
const c = a ? true : false;
|
||||
let c = a ? true : false;
|
||||
|
||||
const d = c == b;
|
||||
let d = c == b;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
function main() {
|
||||
let x = 3u8;
|
||||
const y = x > 2u8? 1u8 : 2u8;
|
||||
}
|
@ -21,7 +21,7 @@ DRAFT
|
||||
The purpose of this proposal is to provide initial support for strings in Leo.
|
||||
Since strings are sequences of characters,
|
||||
the proposal inextricably also involves characters.
|
||||
This proposal is described as 'initial'
|
||||
This proposal is described as 'initial,'
|
||||
because it provides some basic features that we may extend in the future;
|
||||
the initial features should be sufficiently simple and conservative
|
||||
that they should not limit the design of the future features.
|
||||
@ -61,7 +61,7 @@ with a discussion of possible future extensions.
|
||||
|
||||
## Characters
|
||||
|
||||
We add a new scalar type `char` for characters.
|
||||
We add a new scalar type, `char` for characters.
|
||||
In accord with Leo's strong typing,
|
||||
this new type is separate from all the other scalar types.
|
||||
|
||||
@ -76,19 +76,26 @@ there is no notion of Unicode encoding (e.g. UTF-8) that applies here.
|
||||
We add a new kind of literals for characters,
|
||||
consisting of single characters or escapes,
|
||||
surrounded by single quotes.
|
||||
Any single Unicode character except single quote is allowed,
|
||||
Any single Unicode character except a single quote is allowed,
|
||||
e.g. `'a'`, `'*'`, and `'"'`.
|
||||
Single quotes must be escaped with backslash, i.e. `'\''`;
|
||||
Single quotes must be escaped with a backslash, i.e. `'\''`;
|
||||
backslashes must be escaped as well, i.e. `'\\'`
|
||||
We allow other backslash escapes
|
||||
for commonly used characters that are not otherwise easily denoted,
|
||||
namely _[TODO: Decide which other escapes we want to allow, e.g. `'\n'`.]_
|
||||
* `\n`
|
||||
* `\r`
|
||||
* `\t`
|
||||
* `\0`
|
||||
* `\'`
|
||||
* `\"`
|
||||
|
||||
We also allow Unicode escapes of the form `'\u{X}'`,
|
||||
where `X` is a sequence of one to six hex digits
|
||||
(both uppercase and lowercase letters are allowed)
|
||||
whose value must be between 0 and 10FFFF, inclusive.
|
||||
Note that the literal character is assembled by the compiler---for
|
||||
creating literals there is no need for the circuit to know
|
||||
creating literals, there is no need for the circuit to know
|
||||
which codepoints are disallowed.
|
||||
_[TODO: Do we want a different notation for Unicode escapes?
|
||||
Note that the `{` `}` delimiters are motivated by the fact that
|
||||
@ -97,11 +104,20 @@ This notation is supported by both Javascript and Rust.
|
||||
|
||||
_[TODO: Which (initial) built-in or library operations
|
||||
do we want to provide for `char` values?]_
|
||||
- [ ] is_alphabetic - Returns `true` if the `char` has the `Alphabetic` property.
|
||||
- [ ] is_ascii - Returns `true` if the `char` is in the `ASCII` range.
|
||||
- [ ] is_ascii_alphabetic - Returns `true` if the `char` is in the `ASCII Alphabetic` range.
|
||||
- [ ] is_lowercase - Returns `true` if the `char` has the `Lowercase` property.
|
||||
- [ ] is_numeric - Returns `true` if the `char` has one of the general categories for numbers.
|
||||
- [ ] is_uppercase - Returns `true` if the `char` has the `Uppercase` property.
|
||||
- [ ] is_whitespace - Returns `true` if the `char` has the `White_Space` property.
|
||||
- [ ] to_digit - Converts the `char` to the given `radix` format.
|
||||
|
||||
|
||||
## Strings
|
||||
|
||||
In this initial design proposal, we do not introduce any new type for strings.
|
||||
Instead, we rely on the fact that Leo already has arrays,
|
||||
Instead, we rely on the fact that Leo already has arrays
|
||||
and that arrays of characters can be regarded as strings.
|
||||
Existing array operations, such as element and range access,
|
||||
apply to these strings without the need of language extensions.
|
||||
@ -113,7 +129,7 @@ surrounded by double quotes;
|
||||
this is just syntactic sugar.
|
||||
Any single Unicode character except double quote is allowed,
|
||||
e.g. `""`, `"Aleo"`, `"it's"`, and `"x + y"`.
|
||||
Double quotes must be escaped with backslash, e.g. `"say \"hi\""`;
|
||||
Double quotes must be escaped with a backslash, e.g. `"say \"hi\""`;
|
||||
backslashes must be escaped as well, e.g. `"c:\\dir"`.
|
||||
We allow the same backslash escapes allowed for character literals
|
||||
(see the section on characters above).
|
||||
@ -121,9 +137,9 @@ _[TODO: There is a difference in the treatment of single and double quotes:
|
||||
the former are allowed in string literals but not character literals,
|
||||
while the latter are allowed in character literals but not string literals;
|
||||
this asymmetry is also present in Java.
|
||||
However, for simplicity we may want to symmetrically disallow
|
||||
However, for simplicity, we may want to symmetrically disallow
|
||||
both single and double quotes in both character and string literals.]_
|
||||
We also allow the same Unicode escapes allowed in character literals,
|
||||
We also allow the same Unicode escapes allowed in character literals
|
||||
(described in the section on characters above).
|
||||
In any case, the type of a string literal is `[char; N]`,
|
||||
where `N` is the length of the string measured in characters,
|
||||
@ -132,7 +148,7 @@ Note that there is no notion of Unicode encoding (e.g. UTF-8)
|
||||
that applies to string literals.
|
||||
|
||||
The rationale for not introducing a new type for strings initially,
|
||||
and instead piggyback on the existing array types and operations,
|
||||
and instead, piggyback on the existing array types and operations,
|
||||
is twofold.
|
||||
First, it is an economical design
|
||||
that lets us reuse the existing array machinery,
|
||||
@ -142,21 +158,27 @@ and at the R1CS compilation level
|
||||
Second, it leaves the door open to providing,
|
||||
in a future design iteration,
|
||||
a richer type for strings,
|
||||
as disccused in the section about future extensions below.
|
||||
as discussed in the section about future extensions below.
|
||||
|
||||
_[TODO: Which (initial) built-in or library operations
|
||||
do we want to provide for `[char; N]` values that are not already
|
||||
available with the existing array operations?]_
|
||||
* `u8` to `[char; 2]` hexstring, .., `u128` to `[char; 32]` hexstring
|
||||
* field element to `[char; 64]` hexstring. (Application can test leading zeros and slice them out if it needs to return, say, a 40-hex-digit string)
|
||||
* _[TODO: more?]_
|
||||
- [ ] `u8` to `[char; 2]` hexstring, .., `u128` to `[char; 32]` hexstring
|
||||
- [ ] field element to `[char; 64]` hexstring. (Application can test leading zeros and slice them out if it needs to return, say, a 40-hex-digit string)
|
||||
- [ ] len - Returns the length of the `string`.
|
||||
- [ ] is_empty - Returns `true` if the `string` is empty.
|
||||
- [ ] pop - Pops a `char` to the `string`.
|
||||
- [ ] push - Pushes a `char` to the `string`.
|
||||
- [ ] append - Appends a `string` to the `string`.
|
||||
- [ ] clear - Empties the `string`.
|
||||
- [ ] _[TODO: more?]_
|
||||
|
||||
## Input and Output of Literal Characters and Strings
|
||||
|
||||
Since UTF-8 is a standard encoding, it would make sense for
|
||||
the literal characters and strings in the `.in` file
|
||||
to be automatically converted to UTF-32 by the Leo compiler.
|
||||
However, the size of a string can be confusing, since multiple
|
||||
However, the size of a string can be confusing since multiple
|
||||
Unicode code points can be composed into a single glyph which
|
||||
then appears to be a single character. If a parameter of type `[char; 10]`
|
||||
[if that is the syntax we decide on] is passed a literal string
|
||||
@ -170,16 +192,16 @@ usable exclusively as first arguments of console print calls.
|
||||
This proposal eliminates this very specific notion,
|
||||
which is subsumed by the string literals described above.
|
||||
In other words, a console print call
|
||||
will simply take a string literal as first argument,
|
||||
will take a string literal as the first argument,
|
||||
which will be interpreted as a format string
|
||||
according to the semantics of console print calls.
|
||||
The internal UTF-32 string will be translated to UTF-8 for output.
|
||||
|
||||
## Compilation to R1CS
|
||||
|
||||
So far the discussion has been independent from R1CS
|
||||
So far, the discussion has been independent from R1CS
|
||||
(except for a brief reference when discussing the rationale behind the design).
|
||||
This is intentional, because the syntax and semantics of Leo
|
||||
This is intentional because the syntax and semantics of Leo
|
||||
should be understandable independently from the compilation of Leo to R1CS.
|
||||
However, compilation to R1CS is a critical consideration
|
||||
that affects the design of Leo.
|
||||
@ -207,10 +229,10 @@ suitable array inline construction expressions.
|
||||
## Future Extensions
|
||||
|
||||
As alluded to in the section about design above,
|
||||
for now we are avoiding the introduction of a string type,
|
||||
for now, we are avoiding the introduction of a string type,
|
||||
isomorphic to but separate from character arrays,
|
||||
because we may want to introduce later a more flexible type of strings,
|
||||
in particular one that supports resizing.
|
||||
in particular, one that supports resizing.
|
||||
This may be realized via a built-in or library circuit type
|
||||
that includes a character array and a fill index.
|
||||
This may be a special case of a built-in or library circuit type
|
||||
@ -241,7 +263,7 @@ to/from common formats, e.g. UTF-8.
|
||||
# Alternatives
|
||||
|
||||
We could avoid the new `char` type altogether,
|
||||
and instead rely on the existing `u32` to represent Unicode code points,
|
||||
and instead, rely on the existing `u32` to represent Unicode code points,
|
||||
and provide character-oriented operations on `u32` values.
|
||||
(Note that both `u8` and `u16` are too small for 10FFFFh,
|
||||
and that signed integer types include negative integers
|
||||
@ -255,7 +277,7 @@ All in all, introducing a new type for characters
|
||||
is consistent with Leo's strong typing approach.
|
||||
Furthermore, for compilation to R1CS, `u32`,
|
||||
even if restricted to the number of bits needed for Unicode code points,
|
||||
is less efficient than the field representation described earlier,
|
||||
is less efficient than the field representation described earlier
|
||||
because `u32` requires a field element for each bit.
|
||||
|
||||
Instead of representing strings as character arrays,
|
||||
@ -265,9 +287,9 @@ These strings would be isomorphic to, but distinct form, character arrays.
|
||||
However, for compilation to R1CS, it would be necessary to
|
||||
perform the same kind of known-size analysis on strings
|
||||
that is already performed on arrays,
|
||||
possibly necessitating to include a size as part of the type, i.e. `string(N)`,
|
||||
possibly necessitating to include size as part of the type, i.e. `string(N)`,
|
||||
which is obviously isomorphic to `[char; N]`.
|
||||
Thus, using character arrays avoids the duplication.
|
||||
Thus, using character arrays avoids duplication.
|
||||
Furthermore, as noted in the section on future extensions,
|
||||
this leaves the door open to
|
||||
introducing a future type `string` for resizable strings.
|
||||
|
@ -511,7 +511,7 @@ rest-of-block-comment = "*" rest-of-block-comment-after-star
|
||||
/ not-star rest-of-block-comment
|
||||
```
|
||||
|
||||
Go to: _[not-star](#user-content-not-star), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment)_;
|
||||
Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star](#user-content-not-star)_;
|
||||
|
||||
|
||||
<a name="rest-of-block-comment-after-star"></a>
|
||||
@ -521,7 +521,7 @@ rest-of-block-comment-after-star = "/"
|
||||
/ not-star-or-slash rest-of-block-comment
|
||||
```
|
||||
|
||||
Go to: _[not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star)_;
|
||||
Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star)_;
|
||||
|
||||
|
||||
<a name="end-of-line-comment"></a>
|
||||
@ -596,16 +596,19 @@ lowercase-letter = %x61-7A ; a-z
|
||||
letter = uppercase-letter / lowercase-letter
|
||||
```
|
||||
|
||||
Go to: _[uppercase-letter](#user-content-uppercase-letter), [lowercase-letter](#user-content-lowercase-letter)_;
|
||||
Go to: _[lowercase-letter](#user-content-lowercase-letter), [uppercase-letter](#user-content-uppercase-letter)_;
|
||||
|
||||
|
||||
An identifier is a non-empty sequence of letters, digits, and underscores,
|
||||
starting with a letter.
|
||||
It must not be a keyword: this is an extra-grammatical constraint.
|
||||
It must not be a keyword: this is an extra-grammatical requirement.
|
||||
It must also not be or start with `aleo1`,
|
||||
because that is used for address literals:
|
||||
this is another extra-grammatical requirement.
|
||||
|
||||
<a name="identifier"></a>
|
||||
```abnf
|
||||
identifier = letter *( letter / digit / "_" ) ; but not a keyword
|
||||
identifier = letter *( letter / digit / "_" ) ; but not a keyword or aleo1...
|
||||
```
|
||||
|
||||
Go to: _[letter](#user-content-letter)_;
|
||||
@ -639,7 +642,7 @@ format-string-element = not-double-quote-or-open-brace
|
||||
/ format-string-container
|
||||
```
|
||||
|
||||
Go to: _[not-double-quote-or-open-brace](#user-content-not-double-quote-or-open-brace), [format-string-container](#user-content-format-string-container), [not-double-quote-or-close-brace](#user-content-not-double-quote-or-close-brace)_;
|
||||
Go to: _[format-string-container](#user-content-format-string-container), [not-double-quote-or-open-brace](#user-content-not-double-quote-or-open-brace), [not-double-quote-or-close-brace](#user-content-not-double-quote-or-close-brace)_;
|
||||
|
||||
|
||||
<a name="format-string"></a>
|
||||
@ -764,7 +767,7 @@ atomic-literal = untyped-literal
|
||||
/ address-literal
|
||||
```
|
||||
|
||||
Go to: _[product-group-literal](#user-content-product-group-literal), [unsigned-literal](#user-content-unsigned-literal), [signed-literal](#user-content-signed-literal), [untyped-literal](#user-content-untyped-literal), [field-literal](#user-content-field-literal), [boolean-literal](#user-content-boolean-literal), [address-literal](#user-content-address-literal)_;
|
||||
Go to: _[product-group-literal](#user-content-product-group-literal), [signed-literal](#user-content-signed-literal), [unsigned-literal](#user-content-unsigned-literal), [field-literal](#user-content-field-literal), [boolean-literal](#user-content-boolean-literal), [untyped-literal](#user-content-untyped-literal), [address-literal](#user-content-address-literal)_;
|
||||
|
||||
|
||||
After defining the (mostly) alphanumeric tokens above,
|
||||
@ -809,7 +812,7 @@ token = keyword
|
||||
/ symbol
|
||||
```
|
||||
|
||||
Go to: _[symbol](#user-content-symbol), [format-string](#user-content-format-string), [package-name](#user-content-package-name), [identifier](#user-content-identifier), [keyword](#user-content-keyword), [atomic-literal](#user-content-atomic-literal), [annotation-name](#user-content-annotation-name)_;
|
||||
Go to: _[package-name](#user-content-package-name), [annotation-name](#user-content-annotation-name), [format-string](#user-content-format-string), [keyword](#user-content-keyword), [atomic-literal](#user-content-atomic-literal), [identifier](#user-content-identifier), [symbol](#user-content-symbol)_;
|
||||
|
||||
|
||||
|
||||
@ -845,7 +848,7 @@ signed-type = %s"i8" / %s"i16" / %s"i32" / %s"i64" / %s"i128"
|
||||
integer-type = unsigned-type / signed-type
|
||||
```
|
||||
|
||||
Go to: _[unsigned-type](#user-content-unsigned-type), [signed-type](#user-content-signed-type)_;
|
||||
Go to: _[signed-type](#user-content-signed-type), [unsigned-type](#user-content-unsigned-type)_;
|
||||
|
||||
|
||||
The integer types, along with the field and group types,
|
||||
@ -866,7 +869,7 @@ group-type = %s"group"
|
||||
arithmetic-type = integer-type / field-type / group-type
|
||||
```
|
||||
|
||||
Go to: _[integer-type](#user-content-integer-type), [group-type](#user-content-group-type), [field-type](#user-content-field-type)_;
|
||||
Go to: _[integer-type](#user-content-integer-type), [field-type](#user-content-field-type), [group-type](#user-content-group-type)_;
|
||||
|
||||
|
||||
The arithmetic types, along with the boolean and address types,
|
||||
@ -887,7 +890,7 @@ address-type = %s"address"
|
||||
scalar-type = boolean-type / arithmetic-type / address-type
|
||||
```
|
||||
|
||||
Go to: _[boolean-type](#user-content-boolean-type), [address-type](#user-content-address-type), [arithmetic-type](#user-content-arithmetic-type)_;
|
||||
Go to: _[arithmetic-type](#user-content-arithmetic-type), [address-type](#user-content-address-type), [boolean-type](#user-content-boolean-type)_;
|
||||
|
||||
|
||||
Circuit types are denoted by identifiers and the keyword `Self`.
|
||||
@ -948,7 +951,7 @@ i.e. types whose values contain (sub-)values
|
||||
aggregate-type = tuple-type / array-type / circuit-type
|
||||
```
|
||||
|
||||
Go to: _[circuit-type](#user-content-circuit-type), [tuple-type](#user-content-tuple-type), [array-type](#user-content-array-type)_;
|
||||
Go to: _[tuple-type](#user-content-tuple-type), [array-type](#user-content-array-type), [circuit-type](#user-content-circuit-type)_;
|
||||
|
||||
|
||||
Scalar and aggregate types form all the types.
|
||||
@ -1036,7 +1039,7 @@ primary-expression = identifier
|
||||
/ circuit-expression
|
||||
```
|
||||
|
||||
Go to: _[expression](#user-content-expression), [array-expression](#user-content-array-expression), [identifier](#user-content-identifier), [literal](#user-content-literal), [tuple-expression](#user-content-tuple-expression), [circuit-expression](#user-content-circuit-expression)_;
|
||||
Go to: _[tuple-expression](#user-content-tuple-expression), [identifier](#user-content-identifier), [expression](#user-content-expression), [array-expression](#user-content-array-expression), [circuit-expression](#user-content-circuit-expression), [literal](#user-content-literal)_;
|
||||
|
||||
|
||||
Tuple expressions construct tuples.
|
||||
@ -1097,7 +1100,7 @@ Go to: _[expression](#user-content-expression), [array-dimensions](#user-content
|
||||
array-construction = array-inline-construction / array-repeat-construction
|
||||
```
|
||||
|
||||
Go to: _[array-inline-construction](#user-content-array-inline-construction), [array-repeat-construction](#user-content-array-repeat-construction)_;
|
||||
Go to: _[array-repeat-construction](#user-content-array-repeat-construction), [array-inline-construction](#user-content-array-inline-construction)_;
|
||||
|
||||
|
||||
<a name="array-expression"></a>
|
||||
@ -1125,7 +1128,7 @@ circuit-construction = circuit-type "{"
|
||||
"}"
|
||||
```
|
||||
|
||||
Go to: _[circuit-type](#user-content-circuit-type), [circuit-inline-element](#user-content-circuit-inline-element)_;
|
||||
Go to: _[circuit-inline-element](#user-content-circuit-inline-element), [circuit-type](#user-content-circuit-type)_;
|
||||
|
||||
|
||||
<a name="circuit-inline-element"></a>
|
||||
@ -1133,7 +1136,7 @@ Go to: _[circuit-type](#user-content-circuit-type), [circuit-inline-element](#us
|
||||
circuit-inline-element = identifier ":" expression / identifier
|
||||
```
|
||||
|
||||
Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression)_;
|
||||
Go to: _[expression](#user-content-expression), [identifier](#user-content-identifier)_;
|
||||
|
||||
|
||||
<a name="circuit-expression"></a>
|
||||
@ -1212,7 +1215,7 @@ exponential-expression = unary-expression
|
||||
/ unary-expression "**" exponential-expression
|
||||
```
|
||||
|
||||
Go to: _[exponential-expression](#user-content-exponential-expression), [unary-expression](#user-content-unary-expression)_;
|
||||
Go to: _[unary-expression](#user-content-unary-expression), [exponential-expression](#user-content-exponential-expression)_;
|
||||
|
||||
|
||||
Next in precedence come multiplication and division, both left-associative.
|
||||
@ -1224,7 +1227,7 @@ multiplicative-expression = exponential-expression
|
||||
/ multiplicative-expression "/" exponential-expression
|
||||
```
|
||||
|
||||
Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [exponential-expression](#user-content-exponential-expression)_;
|
||||
Go to: _[exponential-expression](#user-content-exponential-expression), [multiplicative-expression](#user-content-multiplicative-expression)_;
|
||||
|
||||
|
||||
Then there are addition and subtraction, both left-assocative.
|
||||
@ -1236,7 +1239,7 @@ additive-expression = multiplicative-expression
|
||||
/ additive-expression "-" multiplicative-expression
|
||||
```
|
||||
|
||||
Go to: _[additive-expression](#user-content-additive-expression), [multiplicative-expression](#user-content-multiplicative-expression)_;
|
||||
Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [additive-expression](#user-content-additive-expression)_;
|
||||
|
||||
|
||||
Next in the precedence order are ordering relations.
|
||||
@ -1275,7 +1278,7 @@ conjunctive-expression = equality-expression
|
||||
/ conjunctive-expression "&&" equality-expression
|
||||
```
|
||||
|
||||
Go to: _[conjunctive-expression](#user-content-conjunctive-expression), [equality-expression](#user-content-equality-expression)_;
|
||||
Go to: _[equality-expression](#user-content-equality-expression), [conjunctive-expression](#user-content-conjunctive-expression)_;
|
||||
|
||||
|
||||
Next come disjunctive expressions, left-associative.
|
||||
@ -1286,7 +1289,7 @@ disjunctive-expression = conjunctive-expression
|
||||
/ disjunctive-expression "||" conjunctive-expression
|
||||
```
|
||||
|
||||
Go to: _[conjunctive-expression](#user-content-conjunctive-expression), [disjunctive-expression](#user-content-disjunctive-expression)_;
|
||||
Go to: _[disjunctive-expression](#user-content-disjunctive-expression), [conjunctive-expression](#user-content-conjunctive-expression)_;
|
||||
|
||||
|
||||
Finally we have conditional expressions.
|
||||
@ -1299,7 +1302,7 @@ conditional-expression = disjunctive-expression
|
||||
":" conditional-expression
|
||||
```
|
||||
|
||||
Go to: _[expression](#user-content-expression), [disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression)_;
|
||||
Go to: _[expression](#user-content-expression), [conditional-expression](#user-content-conditional-expression), [disjunctive-expression](#user-content-disjunctive-expression)_;
|
||||
|
||||
|
||||
Those above are all the expressions.
|
||||
@ -1332,7 +1335,7 @@ statement = expression-statement
|
||||
/ block
|
||||
```
|
||||
|
||||
Go to: _[return-statement](#user-content-return-statement), [assignment-statement](#user-content-assignment-statement), [conditional-statement](#user-content-conditional-statement), [variable-declaration](#user-content-variable-declaration), [constant-declaration](#user-content-constant-declaration), [expression-statement](#user-content-expression-statement), [loop-statement](#user-content-loop-statement), [console-statement](#user-content-console-statement), [block](#user-content-block)_;
|
||||
Go to: _[expression-statement](#user-content-expression-statement), [return-statement](#user-content-return-statement), [assignment-statement](#user-content-assignment-statement), [block](#user-content-block), [loop-statement](#user-content-loop-statement), [constant-declaration](#user-content-constant-declaration), [conditional-statement](#user-content-conditional-statement), [console-statement](#user-content-console-statement), [variable-declaration](#user-content-variable-declaration)_;
|
||||
|
||||
|
||||
<a name="block"></a>
|
||||
@ -1375,7 +1378,7 @@ variable-declaration = %s"let" identifier-or-identifiers [ ":" type ]
|
||||
"=" expression ";"
|
||||
```
|
||||
|
||||
Go to: _[identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type), [expression](#user-content-expression)_;
|
||||
Go to: _[type](#user-content-type), [identifier-or-identifiers](#user-content-identifier-or-identifiers), [expression](#user-content-expression)_;
|
||||
|
||||
|
||||
<a name="constant-declaration"></a>
|
||||
@ -1384,7 +1387,7 @@ constant-declaration = %s"const" identifier-or-identifiers [ ":" type ]
|
||||
"=" expression ";"
|
||||
```
|
||||
|
||||
Go to: _[expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type)_;
|
||||
Go to: _[expression](#user-content-expression), [type](#user-content-type), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_;
|
||||
|
||||
|
||||
<a name="identifier-or-identifiers"></a>
|
||||
@ -1407,7 +1410,7 @@ Note that blocks are required in all branches, not merely statements.
|
||||
branch = %s"if" expression block
|
||||
```
|
||||
|
||||
Go to: _[expression](#user-content-expression), [block](#user-content-block)_;
|
||||
Go to: _[block](#user-content-block), [expression](#user-content-expression)_;
|
||||
|
||||
|
||||
<a name="conditional-statement"></a>
|
||||
@ -1417,7 +1420,7 @@ conditional-statement = branch
|
||||
/ branch %s"else" conditional-statement
|
||||
```
|
||||
|
||||
Go to: _[branch](#user-content-branch), [conditional-statement](#user-content-conditional-statement), [block](#user-content-block)_;
|
||||
Go to: _[block](#user-content-block), [branch](#user-content-branch), [conditional-statement](#user-content-conditional-statement)_;
|
||||
|
||||
|
||||
A loop statement implicitly defines a loop variable
|
||||
@ -1429,7 +1432,7 @@ The body is a block.
|
||||
loop-statement = %s"for" identifier %s"in" expression ".." expression block
|
||||
```
|
||||
|
||||
Go to: _[expression](#user-content-expression), [identifier](#user-content-identifier), [block](#user-content-block)_;
|
||||
Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression), [block](#user-content-block)_;
|
||||
|
||||
|
||||
An assignment statement is straightforward.
|
||||
@ -1446,7 +1449,7 @@ assignment-operator = "=" / "+=" / "-=" / "*=" / "/=" / "**="
|
||||
assignment-statement = expression assignment-operator expression ";"
|
||||
```
|
||||
|
||||
Go to: _[assignment-operator](#user-content-assignment-operator), [expression](#user-content-expression)_;
|
||||
Go to: _[expression](#user-content-expression), [assignment-operator](#user-content-assignment-operator)_;
|
||||
|
||||
|
||||
Console statements start with the `console` keyword,
|
||||
@ -1532,7 +1535,7 @@ function-declaration = *annotation %s"function" identifier
|
||||
block
|
||||
```
|
||||
|
||||
Go to: _[block](#user-content-block), [function-parameters](#user-content-function-parameters), [type](#user-content-type), [identifier](#user-content-identifier)_;
|
||||
Go to: _[block](#user-content-block), [identifier](#user-content-identifier), [function-parameters](#user-content-function-parameters), [type](#user-content-type)_;
|
||||
|
||||
|
||||
<a name="function-parameters"></a>
|
||||
@ -1542,7 +1545,7 @@ function-parameters = self-parameter
|
||||
/ function-inputs
|
||||
```
|
||||
|
||||
Go to: _[function-inputs](#user-content-function-inputs), [self-parameter](#user-content-self-parameter)_;
|
||||
Go to: _[self-parameter](#user-content-self-parameter), [function-inputs](#user-content-function-inputs)_;
|
||||
|
||||
|
||||
<a name="self-parameter"></a>
|
||||
@ -1563,7 +1566,7 @@ Go to: _[function-input](#user-content-function-input)_;
|
||||
function-input = [ %s"const" ] identifier ":" type
|
||||
```
|
||||
|
||||
Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_;
|
||||
Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_;
|
||||
|
||||
|
||||
A circuit member variable declaration consists of an identifier and a type.
|
||||
@ -1583,7 +1586,7 @@ Go to: _[member-function-declaration](#user-content-member-function-declaration)
|
||||
member-variable-declaration = identifier ":" type
|
||||
```
|
||||
|
||||
Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_;
|
||||
Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_;
|
||||
|
||||
|
||||
<a name="member-function-declaration"></a>
|
||||
@ -1618,7 +1621,7 @@ to be followed by a comma, for convenience.
|
||||
|
||||
<a name="import-declaration"></a>
|
||||
```abnf
|
||||
import-declaration = %s"import" package-path
|
||||
import-declaration = %s"import" package-path ";"
|
||||
```
|
||||
|
||||
Go to: _[package-path](#user-content-package-path)_;
|
||||
@ -1632,7 +1635,7 @@ package-path = "*"
|
||||
/ "(" package-path *( "," package-path ) [","] ")"
|
||||
```
|
||||
|
||||
Go to: _[package-path](#user-content-package-path), [package-name](#user-content-package-name), [identifier](#user-content-identifier)_;
|
||||
Go to: _[identifier](#user-content-identifier), [package-path](#user-content-package-path), [package-name](#user-content-package-name)_;
|
||||
|
||||
|
||||
Finally, we define a file as a sequence of zero or more declarations.
|
||||
@ -1647,7 +1650,7 @@ declaration = import-declaration
|
||||
/ constant-declaration
|
||||
```
|
||||
|
||||
Go to: _[import-declaration](#user-content-import-declaration), [circuit-declaration](#user-content-circuit-declaration), [constant-declaration](#user-content-constant-declaration), [function-declaration](#user-content-function-declaration)_;
|
||||
Go to: _[constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration), [function-declaration](#user-content-function-declaration), [circuit-declaration](#user-content-circuit-declaration)_;
|
||||
|
||||
|
||||
<a name="file"></a>
|
||||
|
@ -435,9 +435,12 @@ letter = uppercase-letter / lowercase-letter
|
||||
|
||||
; An identifier is a non-empty sequence of letters, digits, and underscores,
|
||||
; starting with a letter.
|
||||
; It must not be a keyword: this is an extra-grammatical constraint.
|
||||
; It must not be a keyword: this is an extra-grammatical requirement.
|
||||
; It must also not be or start with `aleo1`,
|
||||
; because that is used for address literals:
|
||||
; this is another extra-grammatical requirement.
|
||||
|
||||
identifier = letter *( letter / digit / "_" ) ; but not a keyword
|
||||
identifier = letter *( letter / digit / "_" ) ; but not a keyword or aleo1...
|
||||
|
||||
; A package name consists of one or more segments separated by single dashes,
|
||||
; where each segment is a non-empty sequence of lowercase letters and digits.
|
||||
@ -965,7 +968,7 @@ circuit-declaration = *annotation %s"circuit" identifier
|
||||
; Note that we allow the last element of the parenthesized list
|
||||
; to be followed by a comma, for convenience.
|
||||
|
||||
import-declaration = %s"import" package-path
|
||||
import-declaration = %s"import" package-path ";"
|
||||
|
||||
package-path = "*"
|
||||
/ identifier [ %s"as" identifier ]
|
||||
|
Loading…
Reference in New Issue
Block a user