mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-19 15:41:36 +03:00
Merge branch 'master' into dead-code-elimination
This commit is contained in:
commit
d120e90d6e
@ -57,6 +57,19 @@ impl<'a> FromAst<'a, leo_ast::IterationStatement> for &'a Statement<'a> {
|
|||||||
let expected_index_type = Some(PartialType::Integer(None, Some(IntegerType::U32)));
|
let expected_index_type = Some(PartialType::Integer(None, Some(IntegerType::U32)));
|
||||||
let start = <&Expression<'a>>::from_ast(scope, &statement.start, expected_index_type.clone())?;
|
let start = <&Expression<'a>>::from_ast(scope, &statement.start, expected_index_type.clone())?;
|
||||||
let stop = <&Expression<'a>>::from_ast(scope, &statement.stop, expected_index_type)?;
|
let stop = <&Expression<'a>>::from_ast(scope, &statement.stop, expected_index_type)?;
|
||||||
|
|
||||||
|
// Return an error if start or stop is not constant.
|
||||||
|
if !start.is_consty() {
|
||||||
|
return Err(AsgConvertError::unexpected_nonconst(
|
||||||
|
&start.span().cloned().unwrap_or_default(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if !stop.is_consty() {
|
||||||
|
return Err(AsgConvertError::unexpected_nonconst(
|
||||||
|
&stop.span().cloned().unwrap_or_default(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let variable = scope.context.alloc_variable(RefCell::new(InnerVariable {
|
let variable = scope.context.alloc_variable(RefCell::new(InnerVariable {
|
||||||
id: scope.context.get_id(),
|
id: scope.context.get_id(),
|
||||||
name: statement.variable.clone(),
|
name: statement.variable.clone(),
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{Node, Span};
|
use crate::{Identifier, Node, Span};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -22,8 +22,9 @@ use std::fmt;
|
|||||||
/// The `input` keyword can view program register, record, and state values.
|
/// The `input` keyword can view program register, record, and state values.
|
||||||
/// Values cannot be modified. The `input` keyword cannot be made mutable.
|
/// Values cannot be modified. The `input` keyword cannot be made mutable.
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||||
|
#[serde(transparent)]
|
||||||
pub struct InputKeyword {
|
pub struct InputKeyword {
|
||||||
pub span: Span,
|
pub identifier: Identifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for InputKeyword {
|
impl fmt::Display for InputKeyword {
|
||||||
@ -34,10 +35,10 @@ impl fmt::Display for InputKeyword {
|
|||||||
|
|
||||||
impl Node for InputKeyword {
|
impl Node for InputKeyword {
|
||||||
fn span(&self) -> &Span {
|
fn span(&self) -> &Span {
|
||||||
&self.span
|
&self.identifier.span
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_span(&mut self, span: Span) {
|
fn set_span(&mut self, span: Span) {
|
||||||
self.span = span;
|
self.identifier.span = span;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,16 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{Node, Span};
|
use crate::{Identifier, Node, Span};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// The `mut self` keyword can view and modify circuit values inside of a circuit function.
|
/// The `mut self` keyword can view and modify circuit values inside of a circuit function.
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||||
|
#[serde(transparent)]
|
||||||
pub struct MutSelfKeyword {
|
pub struct MutSelfKeyword {
|
||||||
pub span: Span,
|
pub identifier: Identifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for MutSelfKeyword {
|
impl fmt::Display for MutSelfKeyword {
|
||||||
@ -33,10 +34,10 @@ impl fmt::Display for MutSelfKeyword {
|
|||||||
|
|
||||||
impl Node for MutSelfKeyword {
|
impl Node for MutSelfKeyword {
|
||||||
fn span(&self) -> &Span {
|
fn span(&self) -> &Span {
|
||||||
&self.span
|
&self.identifier.span
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_span(&mut self, span: Span) {
|
fn set_span(&mut self, span: Span) {
|
||||||
self.span = span;
|
self.identifier.span = span;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{Node, Span};
|
use crate::{Identifier, Node, Span};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -22,8 +22,9 @@ use std::fmt;
|
|||||||
/// The `self` keyword can view circuit values inside of a circuit function.
|
/// The `self` keyword can view circuit values inside of a circuit function.
|
||||||
/// Circuit values cannot be modified. To modify values use the `mut self` [MutSelfKeyword].
|
/// Circuit values cannot be modified. To modify values use the `mut self` [MutSelfKeyword].
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||||
|
#[serde(transparent)]
|
||||||
pub struct SelfKeyword {
|
pub struct SelfKeyword {
|
||||||
pub span: Span,
|
pub identifier: Identifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for SelfKeyword {
|
impl fmt::Display for SelfKeyword {
|
||||||
@ -34,10 +35,10 @@ impl fmt::Display for SelfKeyword {
|
|||||||
|
|
||||||
impl Node for SelfKeyword {
|
impl Node for SelfKeyword {
|
||||||
fn span(&self) -> &Span {
|
fn span(&self) -> &Span {
|
||||||
&self.span
|
&self.identifier.span
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_span(&mut self, span: Span) {
|
fn set_span(&mut self, span: Span) {
|
||||||
self.span = span;
|
self.identifier.span = span;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,9 +96,9 @@ impl Node for FunctionInput {
|
|||||||
fn span(&self) -> &Span {
|
fn span(&self) -> &Span {
|
||||||
use FunctionInput::*;
|
use FunctionInput::*;
|
||||||
match self {
|
match self {
|
||||||
InputKeyword(keyword) => &keyword.span,
|
InputKeyword(keyword) => &keyword.identifier.span,
|
||||||
SelfKeyword(keyword) => &keyword.span,
|
SelfKeyword(keyword) => &keyword.identifier.span,
|
||||||
MutSelfKeyword(keyword) => &keyword.span,
|
MutSelfKeyword(keyword) => &keyword.identifier.span,
|
||||||
Variable(variable) => &variable.span,
|
Variable(variable) => &variable.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,9 +106,9 @@ impl Node for FunctionInput {
|
|||||||
fn set_span(&mut self, span: Span) {
|
fn set_span(&mut self, span: Span) {
|
||||||
use FunctionInput::*;
|
use FunctionInput::*;
|
||||||
match self {
|
match self {
|
||||||
InputKeyword(keyword) => keyword.span = span,
|
InputKeyword(keyword) => keyword.identifier.span = span,
|
||||||
SelfKeyword(keyword) => keyword.span = span,
|
SelfKeyword(keyword) => keyword.identifier.span = span,
|
||||||
MutSelfKeyword(keyword) => keyword.span = span,
|
MutSelfKeyword(keyword) => keyword.identifier.span = span,
|
||||||
Variable(variable) => variable.span = span,
|
Variable(variable) => variable.span = span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,31 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
|||||||
let content = fs::read_to_string(&self.main_file_path)
|
let content = fs::read_to_string(&self.main_file_path)
|
||||||
.map_err(|e| CompilerError::FileReadError(self.main_file_path.clone(), e))?;
|
.map_err(|e| CompilerError::FileReadError(self.main_file_path.clone(), e))?;
|
||||||
|
|
||||||
self.parse_program_from_string(&content)
|
self.parse_program_from_string(&content).map_err(|mut error| {
|
||||||
|
// Return a formatted error with file path and code text.
|
||||||
|
|
||||||
|
let path = match error.get_path().map(|x| x.to_string()) {
|
||||||
|
// Get the file path if it exists
|
||||||
|
Some(path) => path,
|
||||||
|
|
||||||
|
// If a file path does not exist, then insert the main file path.
|
||||||
|
None => match self.main_file_path.clone().into_os_string().into_string() {
|
||||||
|
Err(e) => return CompilerError::FileStringError(e),
|
||||||
|
Ok(path) => path,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resolve the code text using the file path.
|
||||||
|
let content = match self.resolve_content(&path) {
|
||||||
|
Err(e) => return e,
|
||||||
|
Ok(x) => x,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update the formatted error.
|
||||||
|
error.set_path(&path, &content[..]);
|
||||||
|
|
||||||
|
error
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -23,7 +23,7 @@ use leo_parser::SyntaxError;
|
|||||||
use leo_state::LocalDataVerificationError;
|
use leo_state::LocalDataVerificationError;
|
||||||
|
|
||||||
use bincode::Error as SerdeError;
|
use bincode::Error as SerdeError;
|
||||||
use std::path::PathBuf;
|
use std::{ffi::OsString, path::PathBuf};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum CompilerError {
|
pub enum CompilerError {
|
||||||
@ -51,6 +51,9 @@ pub enum CompilerError {
|
|||||||
#[error("Cannot read from the provided file path '{:?}': {}", _0, _1)]
|
#[error("Cannot read from the provided file path '{:?}': {}", _0, _1)]
|
||||||
FileReadError(PathBuf, std::io::Error),
|
FileReadError(PathBuf, std::io::Error),
|
||||||
|
|
||||||
|
#[error("Cannot parse file string `{:?}`", _0)]
|
||||||
|
FileStringError(OsString),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
LocalDataVerificationError(#[from] LocalDataVerificationError),
|
LocalDataVerificationError(#[from] LocalDataVerificationError),
|
||||||
|
|
||||||
|
2
compiler/tests/statements/iteration_input.in
Normal file
2
compiler/tests/statements/iteration_input.in
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[main]
|
||||||
|
x: u8 = 1;
|
5
compiler/tests/statements/iteration_input.leo
Normal file
5
compiler/tests/statements/iteration_input.leo
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
function main(x: u8) {
|
||||||
|
for i in 0..x {
|
||||||
|
console.log("{}", i);
|
||||||
|
}
|
||||||
|
}
|
7
compiler/tests/statements/iteration_variable.leo
Normal file
7
compiler/tests/statements/iteration_variable.leo
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
function main() {
|
||||||
|
let x: u32 = 5;
|
||||||
|
|
||||||
|
for i in 0..x {
|
||||||
|
console.log("{}", i);
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{assert_satisfied, expect_asg_error, generate_main_input, parse_program};
|
use crate::{assert_satisfied, expect_asg_error, generate_main_input, parse_program, parse_program_with_input};
|
||||||
use leo_ast::InputValue;
|
use leo_ast::InputValue;
|
||||||
|
|
||||||
pub mod conditional;
|
pub mod conditional;
|
||||||
@ -72,3 +72,20 @@ fn test_block() {
|
|||||||
|
|
||||||
assert_satisfied(program);
|
assert_satisfied(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_iteration_input() {
|
||||||
|
let input_string = include_str!("iteration_input.in");
|
||||||
|
let program_string = include_str!("iteration_input.leo");
|
||||||
|
let error = parse_program_with_input(program_string, input_string).err().unwrap();
|
||||||
|
|
||||||
|
expect_asg_error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_iteration_variable() {
|
||||||
|
let program_string = include_str!("iteration_variable.leo");
|
||||||
|
let program = parse_program(program_string).unwrap();
|
||||||
|
|
||||||
|
assert_satisfied(program);
|
||||||
|
}
|
||||||
|
@ -507,7 +507,7 @@ impl ParserContext {
|
|||||||
/// Returns an [`Expression`] AST node if the next tokens represent an
|
/// Returns an [`Expression`] AST node if the next tokens represent an
|
||||||
/// circuit initialization expression.
|
/// circuit initialization expression.
|
||||||
///
|
///
|
||||||
pub fn parse_circuit_init(&mut self, ident: Identifier) -> SyntaxResult<Expression> {
|
pub fn parse_circuit_init(&mut self, identifier: Identifier) -> SyntaxResult<Expression> {
|
||||||
self.expect(Token::LeftCurly)?;
|
self.expect(Token::LeftCurly)?;
|
||||||
let mut members = vec![];
|
let mut members = vec![];
|
||||||
let end_span;
|
let end_span;
|
||||||
@ -535,8 +535,8 @@ impl ParserContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Expression::CircuitInit(CircuitInitExpression {
|
Ok(Expression::CircuitInit(CircuitInitExpression {
|
||||||
span: &ident.span + &end_span,
|
span: &identifier.span + &end_span,
|
||||||
name: ident,
|
name: identifier,
|
||||||
members,
|
members,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -309,11 +309,16 @@ impl ParserContext {
|
|||||||
///
|
///
|
||||||
pub fn parse_function_input(&mut self) -> SyntaxResult<FunctionInput> {
|
pub fn parse_function_input(&mut self) -> SyntaxResult<FunctionInput> {
|
||||||
if let Some(token) = self.eat(Token::Input) {
|
if let Some(token) = self.eat(Token::Input) {
|
||||||
return Ok(FunctionInput::InputKeyword(InputKeyword { span: token.span }));
|
return Ok(FunctionInput::InputKeyword(InputKeyword {
|
||||||
|
identifier: Identifier {
|
||||||
|
name: token.token.to_string(),
|
||||||
|
span: token.span,
|
||||||
|
},
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
let const_ = self.eat(Token::Const);
|
let const_ = self.eat(Token::Const);
|
||||||
let mutable = self.eat(Token::Mut);
|
let mutable = self.eat(Token::Mut);
|
||||||
let name = if let Some(token) = self.eat(Token::LittleSelf) {
|
let mut name = if let Some(token) = self.eat(Token::LittleSelf) {
|
||||||
Identifier {
|
Identifier {
|
||||||
name: token.token.to_string(),
|
name: token.token.to_string(),
|
||||||
span: token.span,
|
span: token.span,
|
||||||
@ -326,11 +331,11 @@ impl ParserContext {
|
|||||||
//error
|
//error
|
||||||
}
|
}
|
||||||
if let Some(mutable) = &mutable {
|
if let Some(mutable) = &mutable {
|
||||||
return Ok(FunctionInput::MutSelfKeyword(MutSelfKeyword {
|
name.span = &mutable.span + &name.span;
|
||||||
span: &mutable.span + &name.span,
|
name.name = "mut self".to_string();
|
||||||
}));
|
return Ok(FunctionInput::MutSelfKeyword(MutSelfKeyword { identifier: name }));
|
||||||
}
|
}
|
||||||
return Ok(FunctionInput::SelfKeyword(SelfKeyword { span: name.span }));
|
return Ok(FunctionInput::SelfKeyword(SelfKeyword { identifier: name }));
|
||||||
}
|
}
|
||||||
self.expect(Token::Colon)?;
|
self.expect(Token::Colon)?;
|
||||||
let type_ = self.parse_type()?.0;
|
let type_ = self.parse_type()?.0;
|
||||||
|
Loading…
Reference in New Issue
Block a user