Merge branch 'master' of github.com:AleoHQ/leo into bug/abnf-format-strings

This commit is contained in:
gluaxspeed 2021-07-21 02:51:35 -07:00
commit c1879e6e1c
6 changed files with 105 additions and 29 deletions

View File

@ -148,24 +148,28 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
_ => None, _ => None,
}; };
let const_right = match right.map(|x| x.const_value()) { let const_right = match right.map(|x| x.const_value()) {
Some(Some(ConstValue::Int(value))) => { Some(Some(ConstValue::Int(inner_value))) => {
let value = value.to_usize(); let usize_value = inner_value.to_usize();
if let Some(value) = value { if let Some(inner_value) = usize_value {
if value > parent_size { if inner_value > parent_size {
return Err(AsgConvertError::array_index_out_of_bounds( let error_span = if let Some(right) = right {
value, right.span().cloned().unwrap_or_default()
&right.unwrap().span().cloned().unwrap_or_default(), } else {
)); value.span.clone()
};
return Err(AsgConvertError::array_index_out_of_bounds(inner_value, &error_span));
} else if let Some(left) = const_left { } else if let Some(left) = const_left {
if left > value { if left > inner_value {
return Err(AsgConvertError::array_index_out_of_bounds( let error_span = if let Some(right) = right {
value, right.span().cloned().unwrap_or_default()
&right.unwrap().span().cloned().unwrap_or_default(), } else {
)); value.span.clone()
};
return Err(AsgConvertError::array_index_out_of_bounds(inner_value, &error_span));
} }
} }
} }
value usize_value
} }
None => Some(parent_size), None => Some(parent_size),
_ => None, _ => None,
@ -188,12 +192,14 @@ impl<'a> FromAst<'a, leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessEx
)); ));
} }
} }
if let Some(value) = const_left { if let Some(left_value) = const_left {
if value + expected_len > parent_size { if left_value + expected_len > parent_size {
return Err(AsgConvertError::array_index_out_of_bounds( let error_span = if let Some(left) = left {
value, left.span().cloned().unwrap_or_default()
&left.unwrap().span().cloned().unwrap_or_default(), } else {
)); value.span.clone()
};
return Err(AsgConvertError::array_index_out_of_bounds(left_value, &error_span));
} }
} }
length = Some(expected_len); length = Some(expected_len);

View File

@ -25,9 +25,7 @@ that we suggest few changes to Leo CLI and Manifest:
- allow custom names for imports to manually resolve name conflicts; - allow custom names for imports to manually resolve name conflicts;
- add "curve" and "proving system" sections to the Manifest; - add "curve" and "proving system" sections to the Manifest;
- add "include" and "exclude" parameters for "proving system" and "curve"; - add "include" and "exclude" parameters for "proving system" and "curve";
- add a lock file which would store imported dependencies and their relations;
Later this solution can be improved by adding a lock-file which would lock
imported packages based on both their contents and version.
# Motivation # Motivation
@ -109,12 +107,7 @@ To support updated Manifest new command should be added to Leo CLI.
```bash ```bash
# pull imports # pull imports
leo install leo fetch
```
Alternatively it can be called `pull`.
```
leo pull
``` ```
## Imports Restructurization ## Imports Restructurization
@ -155,6 +148,44 @@ first-program => author1-program@0.1.0
second-program => author2-program2@1.0.4 second-program => author2-program2@1.0.4
``` ```
## Leo.lock
For imports map to be generated and read by the Leo binary and then by the Leo compiler,
a lock file needs to be created. Lock file should be generated by the `leo fetch` command,
which will pull the dependencies, process their manifests, and put the required information
to the file in the root directory of the program called `Leo.lock`.
Suggested structure of this file is similar to the Cargo.lock file:
```
[[package]]
name = "suit-mk2"
version = "0.2.0"
author = "ironman"
import_name = "suit-mk2"
[package.dependencies]
garbage = "ironman-suit@0.1.0"
[[package]]
name = "suit"
version = "0.1.0"
author = "ironman"
import_name = "garbage"
```
In the example above, you can see that all program dependencies are defined as an
array called `package`. Each of the dependencies contains main information about
it, including the `import_name` field which is the imported package's name in
the Leo program. Also, it stores relationships between these dependencies in the
field `dependencies`.
The format described here allows the Leo binary to form an imports map which can be
passed to the compiler.
It is important to note that Leo.lock file is created only when a package has dependencies.
For programs with no dependencies, a lock file is not required and not created.
## Recursive Dependencies ## Recursive Dependencies
This improvement introduces recursive dependencies. To solve this case preemptively This improvement introduces recursive dependencies. To solve this case preemptively

View File

@ -94,6 +94,26 @@ for i in 0..5 {}
for i in 0..=5 {} for i in 0..=5 {}
``` ```
## Step and Direction
We remark that the step of both counting-up and counting-down loops is implicitly 1;
that is, the loop variable is incremented or decremented by 1.
Whether the loop counts up or down is determined by how the starting and ending bounds compare.
Note that the bounds are not necessarily literals;
they may be more complex `const` expressions, and thus in general their values are resolved at code flattening time.
Because of the type restrictions on bounds, their values are always non-negative integers.
If `S` is the integer value of the starting bound and `E` is the integer value of the ending bound,
there are several cases to consider:
1. If `S == E` and the ending bound is exclusive, there is no actual loop; the range is empty.
2. If `S == E` and the ending bound is inclusive, the loop consists of just one iteration; the loop counts neither up nor down.
3. If `S < E` and the ending bound is exclusive, the loop counts up, from `S` to `E-1`.
4. If `S < E` and the ending bound is inclusive, the loop counts up, from `S` to `E`.
5. If `S > E` and the ending bound is exclusive, the loop counts down, from `S` to `E+1`.
6. If `S > E` and the ending bound is inclusive, the loop counts down, from `S` to `E`.
Cases 3 and 5 consist of one or more iterations; cases 4 and 6 consist of two or more iterations.
## Example ## Example
The code example demostrated in the Motivation part of this document The code example demostrated in the Motivation part of this document

View File

@ -0,0 +1,12 @@
/*
namespace: Compile
expectation: Fail
input_file: input/array_range_access_fail.in
*/
function main (
const x: u32
) {
const y = [1u8; 3];
const z: [u8; 2] = y[..1u32][..x];
}

View File

@ -0,0 +1,2 @@
[constants]
x: u32 = 1u32;

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- " --> compiler-test:7:24\n |\n 7 | const z: [u8; 2] = y[..1u32][..x];\n | ^^^^^^^^^^^^^^\n |\n = array index out of bounds: '0'"