Skip to content

Commit

Permalink
Merge pull request #2888 from AleoHQ/feat/array
Browse files Browse the repository at this point in the history
[Feature] Arrays.
  • Loading branch information
d0cd authored Oct 27, 2023
2 parents a5f164c + 54566c0 commit 63b75db
Show file tree
Hide file tree
Showing 765 changed files with 5,958 additions and 3,646 deletions.
42 changes: 42 additions & 0 deletions compiler/ast/src/access/array_access.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2019-2023 Aleo Systems Inc.
// This file is part of the Leo library.

// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// 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/>.

use crate::{Expression, Node, NodeID};
use leo_span::Span;

use serde::{Deserialize, Serialize};
use std::fmt;

/// An array access expression, e.g., `foo[index]`.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ArrayAccess {
/// An expression evaluating to some array type, e.g., `[false, true]`.
pub array: Box<Expression>,
/// The index to access in the array expression. E.g., `0` for `[false, true]` would yield `false`.
pub index: Box<Expression>,
/// The span for the entire expression `foo[index]`.
pub span: Span,
/// The ID of the node.
pub id: NodeID,
}

impl fmt::Display for ArrayAccess {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}.{}", self.array, self.index)
}
}

crate::simple_node_impl!(ArrayAccess);
3 changes: 3 additions & 0 deletions compiler/ast/src/access/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
// 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/>.

mod array_access;
pub use array_access::*;

mod associated_constant_access;
pub use associated_constant_access::*;

Expand Down
4 changes: 2 additions & 2 deletions compiler/ast/src/access/tuple_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// 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/>.

use crate::{Expression, Node, NodeID, PositiveNumber};
use crate::{Expression, Node, NodeID, NonNegativeNumber};
use leo_span::Span;

use serde::{Deserialize, Serialize};
Expand All @@ -26,7 +26,7 @@ pub struct TupleAccess {
/// An expression evaluating to some tuple type, e.g., `(5, 2)`.
pub tuple: Box<Expression>,
/// The index to access in the tuple expression. E.g., `0` for `(5, 2)` would yield `5`.
pub index: PositiveNumber,
pub index: NonNegativeNumber,
/// The span for the entire expression `tuple.index`.
pub span: Span,
/// The ID of the node.
Expand Down
42 changes: 31 additions & 11 deletions compiler/ast/src/common/positive_number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,47 @@
use serde::{Deserialize, Serialize};
use std::{fmt, str::FromStr};

/// A number string guaranteed to be positive.
/// A number string guaranteed to be non-negative.
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
pub struct PositiveNumber {
/// The string representation of the positive number.
// FIXME(Centril): This should become an `u128`.
pub value: String,
pub struct NonNegativeNumber {
/// The string representation of the non-negative number.
string: String,
/// The numeric value of the non-negative number.
value: usize,
}

impl PositiveNumber {
impl NonNegativeNumber {
/// Returns the string representation of the non-negative number.
pub fn string(&self) -> &str {
&self.string
}

/// Returns the numeric value of the non-negative number.
pub fn value(&self) -> usize {
self.value
}

/// Returns `true` if this number is zero.
pub fn is_zero(&self) -> bool {
self.value.eq("0")
self.value == 0
}
}

impl From<String> for NonNegativeNumber {
fn from(string: String) -> Self {
let value = usize::from_str(&string).unwrap();
Self { string, value }
}
}

/// Converts the positive number into a `usize` or panics if it was malformed.
pub fn to_usize(&self) -> usize {
usize::from_str(&self.value).expect("failed to parse positive number")
impl From<usize> for NonNegativeNumber {
fn from(value: usize) -> Self {
let string = value.to_string();
Self { string, value }
}
}

impl fmt::Display for PositiveNumber {
impl fmt::Display for NonNegativeNumber {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
Expand Down
9 changes: 7 additions & 2 deletions compiler/ast/src/expressions/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ use std::fmt;
/// An access expressions, extracting a smaller part out of a whole.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum AccessExpression {
// /// An `array[index]` expression.
// Array(ArrayAccess),
/// An `array[index]` expression.
Array(ArrayAccess),
// /// An expression accessing a range of an array.
// ArrayRange(ArrayRangeAccess),
/// Access to an associated variable of a struct e.g `u8::MAX`.
Expand All @@ -40,6 +40,7 @@ pub enum AccessExpression {
impl Node for AccessExpression {
fn span(&self) -> Span {
match self {
AccessExpression::Array(n) => n.span(),
AccessExpression::AssociatedConstant(n) => n.span(),
AccessExpression::AssociatedFunction(n) => n.span(),
AccessExpression::Member(n) => n.span(),
Expand All @@ -49,6 +50,7 @@ impl Node for AccessExpression {

fn set_span(&mut self, span: Span) {
match self {
AccessExpression::Array(n) => n.set_span(span),
AccessExpression::AssociatedConstant(n) => n.set_span(span),
AccessExpression::AssociatedFunction(n) => n.set_span(span),
AccessExpression::Member(n) => n.set_span(span),
Expand All @@ -58,6 +60,7 @@ impl Node for AccessExpression {

fn id(&self) -> NodeID {
match self {
AccessExpression::Array(n) => n.id(),
AccessExpression::AssociatedConstant(n) => n.id(),
AccessExpression::AssociatedFunction(n) => n.id(),
AccessExpression::Member(n) => n.id(),
Expand All @@ -67,6 +70,7 @@ impl Node for AccessExpression {

fn set_id(&mut self, id: NodeID) {
match self {
AccessExpression::Array(n) => n.set_id(id),
AccessExpression::AssociatedConstant(n) => n.set_id(id),
AccessExpression::AssociatedFunction(n) => n.set_id(id),
AccessExpression::Member(n) => n.set_id(id),
Expand All @@ -79,6 +83,7 @@ impl fmt::Display for AccessExpression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use AccessExpression::*;
match self {
Array(access) => access.fmt(f),
AssociatedConstant(access) => access.fmt(f),
AssociatedFunction(access) => access.fmt(f),
Member(access) => access.fmt(f),
Expand Down
36 changes: 36 additions & 0 deletions compiler/ast/src/expressions/array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2019-2023 Aleo Systems Inc.
// This file is part of the Leo library.

// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// 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/>.

use super::*;

/// An array expression, e.g., `[true, false, true, false]`.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ArrayExpression {
/// The elements of the array.
pub elements: Vec<Expression>,
/// The span from `[` to `]`.
pub span: Span,
/// The ID of the node.
pub id: NodeID,
}

impl fmt::Display for ArrayExpression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}]", self.elements.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","))
}
}

crate::simple_node_impl!(ArrayExpression);
1 change: 0 additions & 1 deletion compiler/ast/src/expressions/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use crate::{GroupLiteral, IntegerType};

use super::*;

// TODO: Refactor integer literals to use `IntegerType`.
/// A literal.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Literal {
Expand Down
12 changes: 11 additions & 1 deletion compiler/ast/src/expressions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ use std::fmt;
mod access;
pub use access::*;

mod array;
pub use array::*;

mod binary;
pub use binary::*;

Expand Down Expand Up @@ -56,8 +59,10 @@ pub use literal::*;
/// Expression that evaluates to a value.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Expression {
/// A struct access expression, e.g., `Foo.bar`.
/// A struct access expression, e.g. `Foo.bar`.
Access(AccessExpression),
/// An array expression, e.g., `[true, false, true, false]`.
Array(ArrayExpression),
/// A binary expression, e.g., `42 + 24`.
Binary(BinaryExpression),
/// A call expression, e.g., `my_fun(args)`.
Expand Down Expand Up @@ -88,6 +93,7 @@ impl Node for Expression {
use Expression::*;
match self {
Access(n) => n.span(),
Array(n) => n.span(),
Binary(n) => n.span(),
Call(n) => n.span(),
Cast(n) => n.span(),
Expand All @@ -106,6 +112,7 @@ impl Node for Expression {
use Expression::*;
match self {
Access(n) => n.set_span(span),
Array(n) => n.set_span(span),
Binary(n) => n.set_span(span),
Call(n) => n.set_span(span),
Cast(n) => n.set_span(span),
Expand All @@ -124,6 +131,7 @@ impl Node for Expression {
use Expression::*;
match self {
Access(n) => n.id(),
Array(n) => n.id(),
Binary(n) => n.id(),
Call(n) => n.id(),
Cast(n) => n.id(),
Expand All @@ -142,6 +150,7 @@ impl Node for Expression {
use Expression::*;
match self {
Access(n) => n.set_id(id),
Array(n) => n.set_id(id),
Binary(n) => n.set_id(id),
Call(n) => n.set_id(id),
Cast(n) => n.set_id(id),
Expand All @@ -162,6 +171,7 @@ impl fmt::Display for Expression {
use Expression::*;
match &self {
Access(n) => n.fmt(f),
Array(n) => n.fmt(f),
Binary(n) => n.fmt(f),
Call(n) => n.fmt(f),
Cast(n) => n.fmt(f),
Expand Down
4 changes: 2 additions & 2 deletions compiler/ast/src/functions/finalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// 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/>.

use crate::{Block, Identifier, Input, Node, NodeID, Output, Tuple, Type};
use crate::{Block, Identifier, Input, Node, NodeID, Output, TupleType, Type};

use leo_span::Span;

Expand Down Expand Up @@ -53,7 +53,7 @@ impl Finalize {
let output_type = match output.len() {
0 => Type::Unit,
1 => output[0].type_(),
_ => Type::Tuple(Tuple(output.iter().map(|output| output.type_()).collect())),
_ => Type::Tuple(TupleType::new(output.iter().map(|output| output.type_()).collect())),
};

Self { identifier, input, output, output_type, block, span, id }
Expand Down
4 changes: 2 additions & 2 deletions compiler/ast/src/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub use output::*;
pub mod mode;
pub use mode::*;

use crate::{Block, Identifier, Node, NodeID, Tuple, Type};
use crate::{Block, Identifier, Node, NodeID, TupleType, Type};
use leo_span::{sym, Span, Symbol};

use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -100,7 +100,7 @@ impl Function {
let output_type = match output.len() {
0 => Type::Unit,
1 => get_output_type(&output[0]),
_ => Type::Tuple(Tuple(output.iter().map(get_output_type).collect())),
_ => Type::Tuple(TupleType::new(output.iter().map(get_output_type).collect())),
};

Function { annotations, variant, identifier, input, output, output_type, block, finalize, span, id }
Expand Down
3 changes: 3 additions & 0 deletions compiler/ast/src/passes/consumer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub trait ExpressionConsumer {
fn consume_expression(&mut self, input: Expression) -> Self::Output {
match input {
Expression::Access(access) => self.consume_access(access),
Expression::Array(array) => self.consume_array(array),
Expression::Binary(binary) => self.consume_binary(binary),
Expression::Call(call) => self.consume_call(call),
Expression::Cast(cast) => self.consume_cast(cast),
Expand All @@ -42,6 +43,8 @@ pub trait ExpressionConsumer {

fn consume_access(&mut self, _input: AccessExpression) -> Self::Output;

fn consume_array(&mut self, _input: ArrayExpression) -> Self::Output;

fn consume_binary(&mut self, _input: BinaryExpression) -> Self::Output;

fn consume_call(&mut self, _input: CallExpression) -> Self::Output;
Expand Down
Loading

0 comments on commit 63b75db

Please sign in to comment.