Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Arrays. #2888

Merged
merged 51 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
3fda5aa
Introduce Array type
d0cd Oct 7, 2023
25b7d5c
Rename types::Tuple to types::TupleType
d0cd Oct 7, 2023
c3b92d1
Add Array type to Type
d0cd Oct 7, 2023
0792191
Add test cases
d0cd Oct 8, 2023
d8a7f74
Add support for parsing the array type
d0cd Oct 8, 2023
e372710
Introduce ArrayExpression
d0cd Oct 8, 2023
5f75ae8
Support array expressions in AST and visitors
d0cd Oct 8, 2023
f189531
Stubs for arrays in passes
d0cd Oct 8, 2023
c94acde
Support array access expressions in AST and visitors
d0cd Oct 8, 2023
eb420b6
Stubs for arrays access expressions in passes
d0cd Oct 8, 2023
2edc7aa
Parse array access expressions
d0cd Oct 8, 2023
13e1704
Parse array init expressions
d0cd Oct 8, 2023
22766a4
Fix test cases
d0cd Oct 8, 2023
7e471b7
Add type checking for arrays
d0cd Oct 9, 2023
072ab7b
Change PositiveNumber to NonzeroNumber
d0cd Oct 9, 2023
5b2e73d
Refactor TupleTyple
d0cd Oct 10, 2023
d3209da
Cleanup
d0cd Oct 10, 2023
4b9a96e
Update passes
d0cd Oct 10, 2023
82ad245
WIP flattening
d0cd Oct 10, 2023
7e5a6e9
WIP flattening for arrays
d0cd Oct 10, 2023
d1a5283
WIP
d0cd Oct 10, 2023
2fc1557
Add the type map to the symbol table
d0cd Oct 11, 2023
621a2f2
Add expressions to the type map
d0cd Oct 11, 2023
a3446d3
Introduce TypeTable
d0cd Oct 11, 2023
93aca5c
Ensure type consistency in SSA pass
d0cd Oct 11, 2023
3e59672
Cleanup
d0cd Oct 11, 2023
edcc1a6
Update RenameTable
d0cd Oct 11, 2023
c193b1d
Ensure type consistency during loop unrolling
d0cd Oct 11, 2023
6455055
Ensure type consistency during function inlining
d0cd Oct 11, 2023
17cdda2
Refactor TypeTable
d0cd Oct 12, 2023
3b72000
Update SSA pass
d0cd Oct 12, 2023
b36966d
Clean up passes
d0cd Oct 12, 2023
f494a89
Add TypeTable to compiler
d0cd Oct 12, 2023
cacc215
Update flattener
d0cd Oct 12, 2023
992f0b8
Redesign flattening
d0cd Oct 13, 2023
b1096f1
Introduce destructuring pass
d0cd Oct 13, 2023
a3c0892
Add Destructuring pass to the compiler
d0cd Oct 13, 2023
8ca1de3
Refactor Reconstructor
d0cd Oct 13, 2023
08d3997
Update TYC
d0cd Oct 13, 2023
044933c
Update loop unrolling
d0cd Oct 13, 2023
c80aee0
Update DCE
d0cd Oct 13, 2023
49a0c7a
Support codegen for arrays
d0cd Oct 13, 2023
144ef44
Update errors
d0cd Oct 13, 2023
630508c
Update tests
d0cd Oct 13, 2023
6756320
Regen expectations
d0cd Oct 20, 2023
59dfeb9
Regen expectations
d0cd Oct 13, 2023
0dcd156
Cleanup
d0cd Oct 13, 2023
b3c1723
Add tests and fixes
d0cd Oct 17, 2023
34f2dd6
Clippy
d0cd Oct 17, 2023
bdd0f78
Regen expectations
d0cd Oct 20, 2023
54566c0
Regen expectations
d0cd Oct 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
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
Loading