mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-21 16:41:42 +03:00
stashing another set of dev changes
This commit is contained in:
parent
466c41809c
commit
5b4ac6b509
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1112,7 +1112,6 @@ dependencies = [
|
|||||||
"criterion",
|
"criterion",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"leo-errors",
|
"leo-errors",
|
||||||
"leo-input",
|
|
||||||
"leo-span",
|
"leo-span",
|
||||||
"pest",
|
"pest",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1140,7 +1139,6 @@ dependencies = [
|
|||||||
"colored",
|
"colored",
|
||||||
"derivative",
|
"derivative",
|
||||||
"eyre",
|
"eyre",
|
||||||
"leo-input",
|
|
||||||
"leo-span",
|
"leo-span",
|
||||||
"pest",
|
"pest",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -21,9 +21,9 @@ rust-version = "1.56"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
smallvec = { version = "1.8.0", features = ["serde"] }
|
smallvec = { version = "1.8.0", features = ["serde"] }
|
||||||
|
|
||||||
[dependencies.leo-input]
|
# [dependencies.leo-input]
|
||||||
path = "../input"
|
# path = "../input"
|
||||||
version = "1.5.3"
|
# version = "1.5.3"
|
||||||
|
|
||||||
[dependencies.leo-errors]
|
[dependencies.leo-errors]
|
||||||
path = "../errors"
|
path = "../errors"
|
||||||
|
412
ast/src/_input/input_value.rs
Normal file
412
ast/src/_input/input_value.rs
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
// Copyright (C) 2019-2022 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::{ArrayDimensions, Char, CharValue, GroupValue, IntegerType};
|
||||||
|
use leo_input::{
|
||||||
|
errors::InputParserError,
|
||||||
|
expressions::{ArrayInitializerExpression, ArrayInlineExpression, Expression, StringExpression, TupleExpression},
|
||||||
|
types::{ArrayType, CharType, DataType, IntegerType as InputIntegerType, TupleType, Type},
|
||||||
|
values::{
|
||||||
|
Address, AddressValue, BooleanValue, CharValue as InputCharValue, FieldValue, GroupValue as InputGroupValue,
|
||||||
|
IntegerValue, NumberValue, Value,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use leo_span::Span as AstSpan;
|
||||||
|
use pest::Span;
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum InputValue {
|
||||||
|
Address(String),
|
||||||
|
Boolean(bool),
|
||||||
|
Char(CharValue),
|
||||||
|
Field(String),
|
||||||
|
Group(GroupValue),
|
||||||
|
Integer(IntegerType, String),
|
||||||
|
Array(Vec<InputValue>),
|
||||||
|
Tuple(Vec<InputValue>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputValue {
|
||||||
|
fn from_address(address: Address) -> Self {
|
||||||
|
InputValue::Address(address.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_address_value(value: AddressValue) -> Self {
|
||||||
|
match value {
|
||||||
|
AddressValue::Explicit(address) => Self::from_address(address.address),
|
||||||
|
AddressValue::Implicit(address) => Self::from_address(address),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_boolean(boolean: BooleanValue) -> Result<Self, InputParserError> {
|
||||||
|
let boolean = boolean.value.parse::<bool>()?;
|
||||||
|
Ok(InputValue::Boolean(boolean))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_char(input_character: InputCharValue) -> Result<Self, InputParserError> {
|
||||||
|
let character = match input_character.value.inner()? {
|
||||||
|
leo_input::values::Char::Scalar(scalar) => Char::Scalar(scalar),
|
||||||
|
leo_input::values::Char::NonScalar(non_scalar) => Char::NonScalar(non_scalar),
|
||||||
|
};
|
||||||
|
|
||||||
|
let span = AstSpan::from(input_character.span);
|
||||||
|
Ok(InputValue::Char(CharValue { character, span }))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_number(integer_type: InputIntegerType, number: String) -> Self {
|
||||||
|
InputValue::Integer(integer_type.into(), number)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_group(group: InputGroupValue) -> Self {
|
||||||
|
InputValue::Group(GroupValue::from(group))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_field(field: FieldValue) -> Self {
|
||||||
|
InputValue::Field(field.number.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_implicit(data_type: DataType, implicit: NumberValue) -> Result<Self, InputParserError> {
|
||||||
|
match data_type {
|
||||||
|
DataType::Address(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||||
|
DataType::Boolean(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||||
|
DataType::Char(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||||
|
DataType::Integer(integer_type) => Ok(InputValue::from_number(integer_type, implicit.to_string())),
|
||||||
|
DataType::Group(_) => Err(InputParserError::implicit_group(implicit)),
|
||||||
|
DataType::Field(_) => Ok(InputValue::Field(implicit.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_value(data_type: DataType, value: Value) -> Result<Self, InputParserError> {
|
||||||
|
match (data_type, value) {
|
||||||
|
(DataType::Address(_), Value::Address(address)) => Ok(InputValue::from_address_value(address)),
|
||||||
|
(DataType::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean),
|
||||||
|
(DataType::Char(_), Value::Char(character)) => InputValue::from_char(character),
|
||||||
|
(DataType::Integer(integer_type), Value::Integer(integer)) => {
|
||||||
|
match integer.clone() {
|
||||||
|
IntegerValue::Signed(signed) => {
|
||||||
|
if let InputIntegerType::Signed(inner) = integer_type.clone() {
|
||||||
|
let singed_type = signed.clone().type_;
|
||||||
|
if std::mem::discriminant(&inner) != std::mem::discriminant(&singed_type) {
|
||||||
|
return Err(InputParserError::integer_type_mismatch(
|
||||||
|
integer_type,
|
||||||
|
InputIntegerType::Signed(singed_type),
|
||||||
|
integer.span(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IntegerValue::Unsigned(unsigned) => {
|
||||||
|
if let InputIntegerType::Unsigned(inner) = integer_type.clone() {
|
||||||
|
let unsinged_type = unsigned.clone().type_;
|
||||||
|
if std::mem::discriminant(&inner) != std::mem::discriminant(&unsinged_type) {
|
||||||
|
return Err(InputParserError::integer_type_mismatch(
|
||||||
|
integer_type,
|
||||||
|
InputIntegerType::Unsigned(unsinged_type),
|
||||||
|
integer.span(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(InputValue::from_number(integer_type, integer.to_string()))
|
||||||
|
}
|
||||||
|
(DataType::Group(_), Value::Group(group)) => Ok(InputValue::from_group(group)),
|
||||||
|
(DataType::Field(_), Value::Field(field)) => Ok(InputValue::from_field(field)),
|
||||||
|
(data_type, Value::Implicit(implicit)) => InputValue::from_implicit(data_type, implicit),
|
||||||
|
(data_type, value) => Err(InputParserError::data_type_mismatch(data_type, value)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_expression(type_: Type, expression: Expression) -> Result<Self, InputParserError> {
|
||||||
|
match (type_, expression) {
|
||||||
|
(Type::Basic(data_type), Expression::Value(value)) => InputValue::from_value(data_type, value),
|
||||||
|
(Type::Array(array_type), Expression::ArrayInline(inline)) => {
|
||||||
|
InputValue::from_array_inline(array_type, inline)
|
||||||
|
}
|
||||||
|
(Type::Array(array_type), Expression::ArrayInitializer(initializer)) => {
|
||||||
|
InputValue::from_array_initializer(array_type, initializer)
|
||||||
|
}
|
||||||
|
(Type::Array(array_type), Expression::StringExpression(string)) => {
|
||||||
|
InputValue::from_string(array_type, string)
|
||||||
|
}
|
||||||
|
(Type::Tuple(tuple_type), Expression::Tuple(tuple)) => InputValue::from_tuple(tuple_type, tuple),
|
||||||
|
(type_, expression) => Err(InputParserError::expression_type_mismatch(type_, expression)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns a new `InputValue` from the given `ArrayType` and `StringExpression`.
|
||||||
|
///
|
||||||
|
pub(crate) fn from_string(mut array_type: ArrayType, string: StringExpression) -> Result<Self, InputParserError> {
|
||||||
|
// Create a new `ArrayDimensions` type from the input array_type dimensions.
|
||||||
|
let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone());
|
||||||
|
assert!(matches!(*array_type.type_, Type::Basic(DataType::Char(CharType {}))));
|
||||||
|
|
||||||
|
// Convert the array dimensions to usize.
|
||||||
|
let array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?;
|
||||||
|
|
||||||
|
// Return an error if the outer array dimension does not equal the number of array elements.
|
||||||
|
if array_dimensions[0] != string.chars.len() {
|
||||||
|
return Err(InputParserError::invalid_string_length(
|
||||||
|
array_dimensions[0],
|
||||||
|
string.chars.len(),
|
||||||
|
&string.span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
array_type.dimensions = array_type.dimensions.next_dimension();
|
||||||
|
|
||||||
|
let inner_array_type = if array_dimensions.len() == 1 {
|
||||||
|
// This is a single array
|
||||||
|
*array_type.type_
|
||||||
|
} else {
|
||||||
|
// This is a multi-dimensional array
|
||||||
|
return Err(InputParserError::invalid_string_dimensions(&array_type.span));
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut elements = Vec::with_capacity(string.chars.len());
|
||||||
|
for character in string.chars.into_iter() {
|
||||||
|
let element = InputValue::from_expression(
|
||||||
|
inner_array_type.clone(),
|
||||||
|
Expression::Value(Value::Char(InputCharValue {
|
||||||
|
value: character.clone(),
|
||||||
|
span: character.span().clone(),
|
||||||
|
})),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
elements.push(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(InputValue::Array(elements))
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns a new `InputValue` from the given `ArrayType` and `ArrayInlineExpression`.
|
||||||
|
///
|
||||||
|
pub(crate) fn from_array_inline(
|
||||||
|
mut array_type: ArrayType,
|
||||||
|
inline: ArrayInlineExpression,
|
||||||
|
) -> Result<Self, InputParserError> {
|
||||||
|
// Create a new `ArrayDimensions` type from the input array_type dimensions.
|
||||||
|
let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone());
|
||||||
|
|
||||||
|
// Convert the array dimensions to usize.
|
||||||
|
let array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?;
|
||||||
|
|
||||||
|
// Return an error if the outer array dimension does not equal the number of array elements.
|
||||||
|
if array_dimensions[0] != inline.expressions.len() {
|
||||||
|
return Err(InputParserError::array_inline_length(array_dimensions[0], inline));
|
||||||
|
}
|
||||||
|
|
||||||
|
array_type.dimensions = array_type.dimensions.next_dimension();
|
||||||
|
|
||||||
|
let inner_array_type = if array_dimensions.len() == 1 {
|
||||||
|
// This is a single array
|
||||||
|
*array_type.type_
|
||||||
|
} else {
|
||||||
|
// This is a multi-dimensional array
|
||||||
|
Type::Array(array_type)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut elements = Vec::with_capacity(inline.expressions.len());
|
||||||
|
for expression in inline.expressions.into_iter() {
|
||||||
|
let element = InputValue::from_expression(inner_array_type.clone(), expression)?;
|
||||||
|
|
||||||
|
elements.push(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(InputValue::Array(elements))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_array_initializer(
|
||||||
|
array_type: ArrayType,
|
||||||
|
initializer: ArrayInitializerExpression,
|
||||||
|
) -> Result<Self, InputParserError> {
|
||||||
|
let array_dimensions_type = ArrayDimensions::from(initializer.dimensions.clone());
|
||||||
|
let array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?;
|
||||||
|
|
||||||
|
if array_dimensions.len() > 1 {
|
||||||
|
// The expression is an array initializer with tuple syntax
|
||||||
|
Self::from_array_initializer_tuple(array_type, initializer, array_dimensions)
|
||||||
|
} else {
|
||||||
|
// The expression is an array initializer with nested syntax
|
||||||
|
Self::from_array_initializer_nested(array_type, initializer, array_dimensions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_array_initializer_tuple(
|
||||||
|
array_type: ArrayType,
|
||||||
|
initializer: ArrayInitializerExpression,
|
||||||
|
initializer_dimensions: Vec<usize>,
|
||||||
|
) -> Result<Self, InputParserError> {
|
||||||
|
let (array_dimensions, array_element_type) = fetch_nested_array_type_dimensions(array_type.clone(), vec![])?;
|
||||||
|
|
||||||
|
// Return an error if the dimensions of the array are incorrect.
|
||||||
|
if array_dimensions.ne(&initializer_dimensions) {
|
||||||
|
return Err(InputParserError::array_init_length(
|
||||||
|
array_dimensions,
|
||||||
|
initializer_dimensions,
|
||||||
|
&initializer.span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = InputValue::from_expression(array_element_type, *initializer.expression.clone())?;
|
||||||
|
let mut elements = vec![];
|
||||||
|
|
||||||
|
// Build the elements of the array using the `vec!` macro
|
||||||
|
for (i, dimension) in initializer_dimensions.into_iter().rev().enumerate() {
|
||||||
|
if i == 0 {
|
||||||
|
elements = vec![value.clone(); dimension];
|
||||||
|
} else {
|
||||||
|
let element = InputValue::Array(elements.clone());
|
||||||
|
|
||||||
|
elements = vec![element; dimension];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(InputValue::Array(elements))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_array_initializer_nested(
|
||||||
|
mut array_type: ArrayType,
|
||||||
|
initializer: ArrayInitializerExpression,
|
||||||
|
initializer_dimensions: Vec<usize>,
|
||||||
|
) -> Result<Self, InputParserError> {
|
||||||
|
// Create a new `ArrayDimensions` type from the input array_type dimensions.
|
||||||
|
let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone());
|
||||||
|
|
||||||
|
// Convert the array dimensions to usize.
|
||||||
|
let array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?;
|
||||||
|
|
||||||
|
let current_array_dimension = array_dimensions[0];
|
||||||
|
let current_initializer_dimension = initializer_dimensions[0];
|
||||||
|
|
||||||
|
// Return an error if the outer array dimension does not equal the number of array elements.
|
||||||
|
if current_array_dimension.ne(¤t_initializer_dimension) {
|
||||||
|
return Err(InputParserError::array_init_length(
|
||||||
|
array_dimensions,
|
||||||
|
initializer_dimensions,
|
||||||
|
&initializer.span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
array_type.dimensions = array_type.dimensions.next_dimension();
|
||||||
|
|
||||||
|
let inner_array_type = if array_dimensions.len() == 1 {
|
||||||
|
// This is the innermost dimension
|
||||||
|
*array_type.type_
|
||||||
|
} else {
|
||||||
|
// This is an outer dimension of a multi-dimensional array
|
||||||
|
Type::Array(array_type)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Evaluate the array initializer
|
||||||
|
let element = InputValue::from_expression(inner_array_type.clone(), *initializer.expression)?;
|
||||||
|
let elements = vec![element; current_initializer_dimension];
|
||||||
|
|
||||||
|
Ok(InputValue::Array(elements))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_tuple(tuple_type: TupleType, tuple: TupleExpression) -> Result<Self, InputParserError> {
|
||||||
|
let num_types = tuple_type.types_.len();
|
||||||
|
let num_values = tuple.expressions.len();
|
||||||
|
|
||||||
|
if num_types != num_values {
|
||||||
|
return Err(InputParserError::tuple_length(num_types, num_values, &tuple_type.span));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut values = Vec::with_capacity(tuple_type.types_.len());
|
||||||
|
for (type_, value) in tuple_type.types_.into_iter().zip(tuple.expressions.into_iter()) {
|
||||||
|
let value = InputValue::from_expression(type_, value)?;
|
||||||
|
|
||||||
|
values.push(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(InputValue::Tuple(values))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new vector of usize values from an [`ArrayDimensions`] type.
|
||||||
|
///
|
||||||
|
/// Attempts to parse each dimension in the array from a `String` to a `usize` value. If parsing
|
||||||
|
/// is successful, the `usize` value is appended to the return vector. If parsing fails, an error
|
||||||
|
/// is returned.
|
||||||
|
fn parse_array_dimensions(dimensions: ArrayDimensions, span: &Span) -> Result<Vec<usize>, InputParserError> {
|
||||||
|
// Convert the array dimensions to usize.
|
||||||
|
let mut result_array_dimensions = Vec::with_capacity(dimensions.len());
|
||||||
|
|
||||||
|
for dimension in dimensions.iter() {
|
||||||
|
// Convert the dimension to a string.
|
||||||
|
let dimension_string = dimension.to_string();
|
||||||
|
|
||||||
|
// Convert the string to usize.
|
||||||
|
let dimension_usize = match dimension_string.parse::<usize>() {
|
||||||
|
Ok(dimension_usize) => dimension_usize,
|
||||||
|
Err(_) => return Err(InputParserError::array_index(dimension_string, span)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Collect dimension usize values.
|
||||||
|
result_array_dimensions.push(dimension_usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result_array_dimensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Recursively fetch all dimensions from the array type.
|
||||||
|
///
|
||||||
|
fn fetch_nested_array_type_dimensions(
|
||||||
|
array_type: ArrayType,
|
||||||
|
mut array_dimensions: Vec<usize>,
|
||||||
|
) -> Result<(Vec<usize>, Type), InputParserError> {
|
||||||
|
// Create a new `ArrayDimensions` type from the input array_type dimensions.
|
||||||
|
let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone());
|
||||||
|
|
||||||
|
// Convert the array dimensions to usize.
|
||||||
|
let mut current_dimension = parse_array_dimensions(array_dimensions_type, &array_type.span)?;
|
||||||
|
|
||||||
|
array_dimensions.append(&mut current_dimension);
|
||||||
|
|
||||||
|
match *array_type.type_ {
|
||||||
|
Type::Array(next_array_type) => fetch_nested_array_type_dimensions(next_array_type, array_dimensions),
|
||||||
|
type_ => Ok((array_dimensions, type_)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for InputValue {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
InputValue::Address(ref address) => write!(f, "{}", address),
|
||||||
|
InputValue::Boolean(ref boolean) => write!(f, "{}", boolean),
|
||||||
|
InputValue::Char(ref character) => write!(f, "{}", character),
|
||||||
|
InputValue::Group(ref group) => write!(f, "{}", group),
|
||||||
|
InputValue::Field(ref field) => write!(f, "{}", field),
|
||||||
|
InputValue::Integer(ref type_, ref number) => write!(f, "{}{:?}", number, type_),
|
||||||
|
InputValue::Array(ref array) => {
|
||||||
|
let values = array.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ");
|
||||||
|
|
||||||
|
write!(f, "array [{}]", values)
|
||||||
|
}
|
||||||
|
InputValue::Tuple(ref tuple) => {
|
||||||
|
let values = tuple.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ");
|
||||||
|
|
||||||
|
write!(f, "({})", values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,5 +14,23 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
mod context;
|
#![allow(clippy::module_inception)]
|
||||||
pub use context::*;
|
|
||||||
|
#[macro_use]
|
||||||
|
pub mod macros;
|
||||||
|
pub use macros::*;
|
||||||
|
|
||||||
|
pub mod input;
|
||||||
|
pub use input::*;
|
||||||
|
|
||||||
|
pub mod input_value;
|
||||||
|
pub use input_value::*;
|
||||||
|
|
||||||
|
pub mod parameters;
|
||||||
|
pub use parameters::*;
|
||||||
|
|
||||||
|
pub mod program_input;
|
||||||
|
pub use program_input::*;
|
||||||
|
|
||||||
|
pub mod program_state;
|
||||||
|
pub use program_state::*;
|
@ -17,7 +17,6 @@
|
|||||||
use leo_span::Span;
|
use leo_span::Span;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
// use serde::de::{Deserialize as SerDeserialize, Deserializer};
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
fn char_to_u32<S>(character: &char, serializer: S) -> Result<S::Ok, S::Error>
|
fn char_to_u32<S>(character: &char, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
// 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::PositiveNumber;
|
use crate::PositiveNumber;
|
||||||
use leo_input::types::ArrayDimensions as InputArrayDimensions;
|
|
||||||
|
|
||||||
use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer};
|
use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
@ -114,24 +113,6 @@ impl Serialize for ArrayDimensions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new [`ArrayDimensions`] from a [`InputArrayDimensions`] in a Leo program file.
|
|
||||||
impl<'ast> From<InputArrayDimensions<'ast>> for ArrayDimensions {
|
|
||||||
fn from(dimensions: InputArrayDimensions<'ast>) -> Self {
|
|
||||||
match dimensions {
|
|
||||||
InputArrayDimensions::Single(single) => {
|
|
||||||
Self(smallvec![Dimension::Number(PositiveNumber::from(single.number))])
|
|
||||||
}
|
|
||||||
InputArrayDimensions::Multiple(multiple) => Self(
|
|
||||||
multiple
|
|
||||||
.numbers
|
|
||||||
.into_iter()
|
|
||||||
.map(|num| Dimension::Number(PositiveNumber::from(num)))
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for ArrayDimensions {
|
impl fmt::Display for ArrayDimensions {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match &*self.0 {
|
match &*self.0 {
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
// 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 leo_input::common::Identifier as InputIdentifier;
|
|
||||||
use leo_span::{Span, Symbol};
|
use leo_span::{Span, Symbol};
|
||||||
|
|
||||||
use crate::Node;
|
use crate::Node;
|
||||||
@ -68,15 +67,6 @@ impl Identifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<InputIdentifier<'ast>> for Identifier {
|
|
||||||
fn from(identifier: InputIdentifier<'ast>) -> Self {
|
|
||||||
Self {
|
|
||||||
name: Symbol::intern(&identifier.value),
|
|
||||||
span: Span::from(identifier.span),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Identifier {
|
impl fmt::Display for Identifier {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.name)
|
write!(f, "{}", self.name)
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
// 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 leo_input::values::PositiveNumber as InputPositiveNumber;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use tendril::StrTendril;
|
use tendril::StrTendril;
|
||||||
@ -36,15 +34,6 @@ impl PositiveNumber {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new [`PositiveNumber`] from an [`InputPositiveNumber`] in a Leo input file.
|
|
||||||
impl<'ast> From<InputPositiveNumber<'ast>> for PositiveNumber {
|
|
||||||
fn from(array: InputPositiveNumber<'ast>) -> Self {
|
|
||||||
Self {
|
|
||||||
value: array.value.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for PositiveNumber {
|
impl fmt::Display for PositiveNumber {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.value)
|
write!(f, "{}", self.value)
|
||||||
|
@ -14,10 +14,6 @@
|
|||||||
// 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 leo_input::values::{
|
|
||||||
GroupCoordinate as InputGroupCoordinate, Inferred as InputInferred, NumberValue as InputNumberValue,
|
|
||||||
SignHigh as InputSignHigh, SignLow as InputSignLow,
|
|
||||||
};
|
|
||||||
use leo_span::Span;
|
use leo_span::Span;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -40,17 +36,6 @@ pub enum GroupCoordinate {
|
|||||||
Inferred,
|
Inferred,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<InputGroupCoordinate<'ast>> for GroupCoordinate {
|
|
||||||
fn from(coordinate: InputGroupCoordinate<'ast>) -> Self {
|
|
||||||
match coordinate {
|
|
||||||
InputGroupCoordinate::Number(number) => GroupCoordinate::from(number),
|
|
||||||
InputGroupCoordinate::SignHigh(sign_high) => GroupCoordinate::from(sign_high),
|
|
||||||
InputGroupCoordinate::SignLow(sign_low) => GroupCoordinate::from(sign_low),
|
|
||||||
InputGroupCoordinate::Inferred(inferred) => GroupCoordinate::from(inferred),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for GroupCoordinate {
|
impl fmt::Display for GroupCoordinate {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
@ -61,30 +46,3 @@ impl fmt::Display for GroupCoordinate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<InputNumberValue<'ast>> for GroupCoordinate {
|
|
||||||
fn from(number: InputNumberValue<'ast>) -> Self {
|
|
||||||
let value = number.to_string();
|
|
||||||
let span = Span::from(number.span().clone());
|
|
||||||
|
|
||||||
GroupCoordinate::Number(value.into(), span)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<InputSignHigh<'ast>> for GroupCoordinate {
|
|
||||||
fn from(_sign: InputSignHigh<'ast>) -> Self {
|
|
||||||
GroupCoordinate::SignHigh
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<InputSignLow<'ast>> for GroupCoordinate {
|
|
||||||
fn from(_sign: InputSignLow<'ast>) -> Self {
|
|
||||||
GroupCoordinate::SignLow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<InputInferred<'ast>> for GroupCoordinate {
|
|
||||||
fn from(_sign: InputInferred<'ast>) -> Self {
|
|
||||||
GroupCoordinate::Inferred
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -15,9 +15,6 @@
|
|||||||
// 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::groups::GroupCoordinate;
|
use crate::groups::GroupCoordinate;
|
||||||
use leo_input::values::{
|
|
||||||
GroupRepresentation as InputGroupRepresentation, GroupTuple as InputGroupTuple, GroupValue as InputGroupValue,
|
|
||||||
};
|
|
||||||
use leo_span::Span;
|
use leo_span::Span;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -52,17 +49,6 @@ impl GroupValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<InputGroupValue<'ast>> for GroupValue {
|
|
||||||
fn from(ast_group: InputGroupValue) -> Self {
|
|
||||||
let span = Span::from(ast_group.span);
|
|
||||||
|
|
||||||
match ast_group.value {
|
|
||||||
InputGroupRepresentation::Single(number) => GroupValue::Single(number.to_string().into(), span),
|
|
||||||
InputGroupRepresentation::Tuple(tuple) => GroupValue::Tuple(GroupTuple::from(tuple)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for GroupValue {
|
impl fmt::Display for GroupValue {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
@ -83,19 +69,6 @@ pub struct GroupTuple {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<InputGroupTuple<'ast>> for GroupTuple {
|
|
||||||
fn from(ast_group: InputGroupTuple<'ast>) -> Self {
|
|
||||||
let ast_x = ast_group.x;
|
|
||||||
let ast_y = ast_group.y;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
x: GroupCoordinate::from(ast_x),
|
|
||||||
y: GroupCoordinate::from(ast_y),
|
|
||||||
span: Span::from(ast_group.span),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for GroupTuple {
|
impl fmt::Display for GroupTuple {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "({}, {})", self.x, self.y)
|
write!(f, "({}, {})", self.x, self.y)
|
||||||
|
@ -15,15 +15,6 @@
|
|||||||
// 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::{ArrayDimensions, Char, CharValue, GroupValue, IntegerType};
|
use crate::{ArrayDimensions, Char, CharValue, GroupValue, IntegerType};
|
||||||
use leo_input::{
|
|
||||||
errors::InputParserError,
|
|
||||||
expressions::{ArrayInitializerExpression, ArrayInlineExpression, Expression, StringExpression, TupleExpression},
|
|
||||||
types::{ArrayType, CharType, DataType, IntegerType as InputIntegerType, TupleType, Type},
|
|
||||||
values::{
|
|
||||||
Address, AddressValue, BooleanValue, CharValue as InputCharValue, FieldValue, GroupValue as InputGroupValue,
|
|
||||||
IntegerValue, NumberValue, Value,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use leo_span::Span as AstSpan;
|
use leo_span::Span as AstSpan;
|
||||||
use pest::Span;
|
use pest::Span;
|
||||||
|
|
||||||
@ -80,23 +71,23 @@ impl InputValue {
|
|||||||
InputValue::Field(field.number.to_string())
|
InputValue::Field(field.number.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_implicit(data_type: DataType, implicit: NumberValue) -> Result<Self, InputParserError> {
|
fn from_implicit(data_type: Type, implicit: NumberValue) -> Result<Self, InputParserError> {
|
||||||
match data_type {
|
match data_type {
|
||||||
DataType::Address(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
Type::Address(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||||
DataType::Boolean(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
Type::Boolean(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||||
DataType::Char(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
Type::Char(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||||
DataType::Integer(integer_type) => Ok(InputValue::from_number(integer_type, implicit.to_string())),
|
Type::Integer(integer_type) => Ok(InputValue::from_number(integer_type, implicit.to_string())),
|
||||||
DataType::Group(_) => Err(InputParserError::implicit_group(implicit)),
|
Type::Group(_) => Err(InputParserError::implicit_group(implicit)),
|
||||||
DataType::Field(_) => Ok(InputValue::Field(implicit.to_string())),
|
Type::Field(_) => Ok(InputValue::Field(implicit.to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_value(data_type: DataType, value: Value) -> Result<Self, InputParserError> {
|
fn from_value(data_type: Type, value: Value) -> Result<Self, InputParserError> {
|
||||||
match (data_type, value) {
|
match (data_type, value) {
|
||||||
(DataType::Address(_), Value::Address(address)) => Ok(InputValue::from_address_value(address)),
|
(Type::Address(_), Value::Address(address)) => Ok(InputValue::from_address_value(address)),
|
||||||
(DataType::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean),
|
(Type::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean),
|
||||||
(DataType::Char(_), Value::Char(character)) => InputValue::from_char(character),
|
(Type::Char(_), Value::Char(character)) => InputValue::from_char(character),
|
||||||
(DataType::Integer(integer_type), Value::Integer(integer)) => {
|
(Type::Integer(integer_type), Value::Integer(integer)) => {
|
||||||
match integer.clone() {
|
match integer.clone() {
|
||||||
IntegerValue::Signed(signed) => {
|
IntegerValue::Signed(signed) => {
|
||||||
if let InputIntegerType::Signed(inner) = integer_type.clone() {
|
if let InputIntegerType::Signed(inner) = integer_type.clone() {
|
||||||
@ -125,8 +116,8 @@ impl InputValue {
|
|||||||
}
|
}
|
||||||
Ok(InputValue::from_number(integer_type, integer.to_string()))
|
Ok(InputValue::from_number(integer_type, integer.to_string()))
|
||||||
}
|
}
|
||||||
(DataType::Group(_), Value::Group(group)) => Ok(InputValue::from_group(group)),
|
(Type::Group(_), Value::Group(group)) => Ok(InputValue::from_group(group)),
|
||||||
(DataType::Field(_), Value::Field(field)) => Ok(InputValue::from_field(field)),
|
(Type::Field(_), Value::Field(field)) => Ok(InputValue::from_field(field)),
|
||||||
(data_type, Value::Implicit(implicit)) => InputValue::from_implicit(data_type, implicit),
|
(data_type, Value::Implicit(implicit)) => InputValue::from_implicit(data_type, implicit),
|
||||||
(data_type, value) => Err(InputParserError::data_type_mismatch(data_type, value)),
|
(data_type, value) => Err(InputParserError::data_type_mismatch(data_type, value)),
|
||||||
}
|
}
|
||||||
@ -155,7 +146,7 @@ impl InputValue {
|
|||||||
pub(crate) fn from_string(mut array_type: ArrayType, string: StringExpression) -> Result<Self, InputParserError> {
|
pub(crate) fn from_string(mut array_type: ArrayType, string: StringExpression) -> Result<Self, InputParserError> {
|
||||||
// Create a new `ArrayDimensions` type from the input array_type dimensions.
|
// Create a new `ArrayDimensions` type from the input array_type dimensions.
|
||||||
let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone());
|
let array_dimensions_type = ArrayDimensions::from(array_type.dimensions.clone());
|
||||||
assert!(matches!(*array_type.type_, Type::Basic(DataType::Char(CharType {}))));
|
assert!(matches!(*array_type.type_, Type::Basic(Type::Char(CharType {}))));
|
||||||
|
|
||||||
// Convert the array dimensions to usize.
|
// Convert the array dimensions to usize.
|
||||||
let array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?;
|
let array_dimensions = parse_array_dimensions(array_dimensions_type, &array_type.span)?;
|
||||||
|
@ -14,23 +14,146 @@
|
|||||||
// 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/>.
|
||||||
|
|
||||||
#![allow(clippy::module_inception)]
|
use crate::{
|
||||||
|
CharValue, Expression, GroupValue, Identifier, IntegerType, Node, SpreadOrExpression, Type, ValueExpression,
|
||||||
|
};
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
use leo_errors::{AstError, LeoError, ParserError, Result};
|
||||||
|
use pest::Parser;
|
||||||
|
|
||||||
#[macro_use]
|
#[derive(Clone, Debug)]
|
||||||
pub mod macros;
|
pub struct Input {
|
||||||
pub use macros::*;
|
values: IndexMap<Identifier, IndexMap<Identifier, (Type, Expression)>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub mod input;
|
impl Input {
|
||||||
pub use input::*;
|
pub fn new(values: IndexMap<Identifier, IndexMap<Identifier, (Type, Expression)>>) -> Self {
|
||||||
|
for (ident, definitions) in values.iter() {
|
||||||
|
// println!("ident: {}", ident);
|
||||||
|
for (_var, (type_, value)) in definitions.iter() {
|
||||||
|
let _ = InputValue::create(type_.clone(), value.clone())
|
||||||
|
.map_err(|_| ParserError::unexpected_eof(value.span()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod input_value;
|
Input { values }
|
||||||
pub use input_value::*;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod parameters;
|
impl InputValue {
|
||||||
pub use parameters::*;
|
pub fn create(type_: Type, expression: Expression) -> Result<Self> {
|
||||||
|
dbg!(InputValue::try_from((type_, expression))?);
|
||||||
|
Ok(InputValue::Boolean(true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod program_input;
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub use program_input::*;
|
pub enum InputValue {
|
||||||
|
Address(String),
|
||||||
|
Boolean(bool),
|
||||||
|
Char(CharValue),
|
||||||
|
Field(String),
|
||||||
|
Group(GroupValue),
|
||||||
|
Integer(IntegerType, String),
|
||||||
|
Array(Vec<InputValue>),
|
||||||
|
Tuple(Vec<InputValue>),
|
||||||
|
|
||||||
pub mod program_state;
|
// Should be removed later
|
||||||
pub use program_state::*;
|
Implicit(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputValue {
|
||||||
|
fn verify_type(self, type_: Type) -> Result<Self> {
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<(Type, Expression)> for InputValue {
|
||||||
|
type Error = LeoError;
|
||||||
|
fn try_from(value: (Type, Expression)) -> Result<Self> {
|
||||||
|
Ok(match value {
|
||||||
|
(type_, Expression::Value(value)) => {
|
||||||
|
match value {
|
||||||
|
ValueExpression::Address(value, _) => Self::Address(value.to_string()),
|
||||||
|
ValueExpression::Boolean(value, span) => {
|
||||||
|
let bool_value = value.parse::<bool>().map_err(|_| ParserError::unexpected_eof(&span))?; // TODO: change error
|
||||||
|
Self::Boolean(bool_value)
|
||||||
|
}
|
||||||
|
ValueExpression::Char(value) => Self::Char(value),
|
||||||
|
ValueExpression::Field(value, _) => Self::Field(value.to_string()),
|
||||||
|
ValueExpression::Group(value) => Self::Group(*value),
|
||||||
|
ValueExpression::Implicit(value, _) => Self::Implicit(value.to_string()),
|
||||||
|
ValueExpression::Integer(type_, value, _) => Self::Integer(type_, value.to_string()),
|
||||||
|
ValueExpression::String(string, span) => Self::Array(
|
||||||
|
string
|
||||||
|
.into_iter()
|
||||||
|
.map(|c| {
|
||||||
|
Self::Char(CharValue {
|
||||||
|
character: c,
|
||||||
|
span: span.clone(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
.verify_type(type_)?
|
||||||
|
}
|
||||||
|
(Type::Array(type_, type_dimensions), Expression::ArrayInit(array_init)) => {
|
||||||
|
let mut dimensions = array_init.dimensions;
|
||||||
|
let expression = array_init.element;
|
||||||
|
let span = array_init.span.clone();
|
||||||
|
|
||||||
|
if type_dimensions != dimensions || dimensions.is_zero() {
|
||||||
|
return Err(AstError::invalid_array_dimension_size(&span).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if dimensions.len() > 1 {
|
||||||
|
while let Some(dimension) = dimensions.remove_first() {
|
||||||
|
if let Some(number) = dimension.as_specified() {
|
||||||
|
let size = number.value.parse::<usize>().unwrap();
|
||||||
|
// let elements = Vec::with_capacity(size);
|
||||||
|
// for i in 0..size {
|
||||||
|
// // elements.push()
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
return Err(AstError::invalid_array_dimension_size(&span).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
// let elements = Vec::with_capacity(dimensions.len());
|
||||||
|
|
||||||
|
dbg!(dimensions);
|
||||||
|
dbg!(expression);
|
||||||
|
|
||||||
|
// TBD
|
||||||
|
|
||||||
|
Self::Boolean(false).verify_type(*type_)?
|
||||||
|
}
|
||||||
|
(type_, Expression::TupleInit(tuple_init)) => {
|
||||||
|
let mut elements = Vec::with_capacity(tuple_init.elements.len());
|
||||||
|
for element in tuple_init.elements.into_iter() {
|
||||||
|
elements.push(Self::try_from((type_.clone(), element))?);
|
||||||
|
}
|
||||||
|
Self::Tuple(elements).verify_type(type_)?
|
||||||
|
}
|
||||||
|
(type_, Expression::ArrayInline(array_inline)) => {
|
||||||
|
let mut elements = Vec::with_capacity(array_inline.elements.len());
|
||||||
|
let span = array_inline.span().clone();
|
||||||
|
for element in array_inline.elements.into_iter() {
|
||||||
|
if let SpreadOrExpression::Expression(value_expression) = element {
|
||||||
|
elements.push(Self::try_from((type_.clone(), value_expression))?);
|
||||||
|
} else {
|
||||||
|
return Err(ParserError::unexpected_eof(&span).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Array(elements).verify_type(type_)?
|
||||||
|
}
|
||||||
|
(_type_, expr) => {
|
||||||
|
dbg!(&expr);
|
||||||
|
return Err(ParserError::unexpected_eof(expr.span()).into());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,10 +14,6 @@
|
|||||||
// 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 leo_input::types::{
|
|
||||||
IntegerType as InputIntegerType, SignedIntegerType as InputSignedIntegerType,
|
|
||||||
UnsignedIntegerType as InputUnsignedIntegerType,
|
|
||||||
};
|
|
||||||
use leo_span::{sym, Symbol};
|
use leo_span::{sym, Symbol};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -63,39 +59,6 @@ impl IntegerType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<InputIntegerType> for IntegerType {
|
|
||||||
fn from(integer_type: InputIntegerType) -> Self {
|
|
||||||
match integer_type {
|
|
||||||
InputIntegerType::Signed(signed) => Self::from(signed),
|
|
||||||
InputIntegerType::Unsigned(unsigned) => Self::from(unsigned),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<InputUnsignedIntegerType> for IntegerType {
|
|
||||||
fn from(integer_type: InputUnsignedIntegerType) -> Self {
|
|
||||||
match integer_type {
|
|
||||||
InputUnsignedIntegerType::U8Type(_type) => IntegerType::U8,
|
|
||||||
InputUnsignedIntegerType::U16Type(_type) => IntegerType::U16,
|
|
||||||
InputUnsignedIntegerType::U32Type(_type) => IntegerType::U32,
|
|
||||||
InputUnsignedIntegerType::U64Type(_type) => IntegerType::U64,
|
|
||||||
InputUnsignedIntegerType::U128Type(_type) => IntegerType::U128,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<InputSignedIntegerType> for IntegerType {
|
|
||||||
fn from(integer_type: InputSignedIntegerType) -> Self {
|
|
||||||
match integer_type {
|
|
||||||
InputSignedIntegerType::I8Type(_type) => IntegerType::I8,
|
|
||||||
InputSignedIntegerType::I16Type(_type) => IntegerType::I16,
|
|
||||||
InputSignedIntegerType::I32Type(_type) => IntegerType::I32,
|
|
||||||
InputSignedIntegerType::I64Type(_type) => IntegerType::I64,
|
|
||||||
InputSignedIntegerType::I128Type(_type) => IntegerType::I128,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for IntegerType {
|
impl fmt::Display for IntegerType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -15,9 +15,6 @@
|
|||||||
// 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::{ArrayDimensions, Identifier, IntegerType};
|
use crate::{ArrayDimensions, Identifier, IntegerType};
|
||||||
use leo_input::types::{
|
|
||||||
ArrayType as InputArrayType, DataType as InputDataType, TupleType as InputTupleType, Type as InputType,
|
|
||||||
};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -122,48 +119,6 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// input pest ast -> Explicit Type
|
|
||||||
|
|
||||||
impl From<InputDataType> for Type {
|
|
||||||
fn from(data_type: InputDataType) -> Self {
|
|
||||||
match data_type {
|
|
||||||
InputDataType::Address(_type) => Type::Address,
|
|
||||||
InputDataType::Boolean(_type) => Type::Boolean,
|
|
||||||
InputDataType::Char(_type) => Type::Char,
|
|
||||||
InputDataType::Field(_type) => Type::Field,
|
|
||||||
InputDataType::Group(_type) => Type::Group,
|
|
||||||
InputDataType::Integer(type_) => Type::IntegerType(IntegerType::from(type_)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<InputArrayType<'ast>> for Type {
|
|
||||||
fn from(array_type: InputArrayType<'ast>) -> Self {
|
|
||||||
let element_type = Box::new(Type::from(*array_type.type_));
|
|
||||||
let dimensions = ArrayDimensions::from(array_type.dimensions);
|
|
||||||
|
|
||||||
Type::Array(element_type, dimensions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<InputTupleType<'ast>> for Type {
|
|
||||||
fn from(tuple_type: InputTupleType<'ast>) -> Self {
|
|
||||||
let types = tuple_type.types_.into_iter().map(Type::from).collect();
|
|
||||||
|
|
||||||
Type::Tuple(types)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> From<InputType<'ast>> for Type {
|
|
||||||
fn from(type_: InputType<'ast>) -> Self {
|
|
||||||
match type_ {
|
|
||||||
InputType::Basic(type_) => Type::from(type_),
|
|
||||||
InputType::Array(type_) => Type::from(type_),
|
|
||||||
InputType::Tuple(type_) => Type::from(type_),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Type {
|
impl fmt::Display for Type {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -1 +0,0 @@
|
|||||||
ok
|
|
@ -25,9 +25,9 @@ version = "0.3.62"
|
|||||||
path = "../span"
|
path = "../span"
|
||||||
version = "1.5.3"
|
version = "1.5.3"
|
||||||
|
|
||||||
[dependencies.leo-input]
|
# [dependencies.leo-input]
|
||||||
path = "../input"
|
# path = "../input"
|
||||||
version = "1.5.3"
|
# version = "1.5.3"
|
||||||
|
|
||||||
[dependencies.colored]
|
[dependencies.colored]
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
@ -64,7 +64,7 @@ pub use self::state::*;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate thiserror;
|
extern crate thiserror;
|
||||||
|
|
||||||
use leo_input::InputParserError;
|
// use leo_input::InputParserError;
|
||||||
|
|
||||||
/// The LeoError type that contains all sub error types.
|
/// The LeoError type that contains all sub error types.
|
||||||
/// This allows a unified error type throughout the Leo crates.
|
/// This allows a unified error type throughout the Leo crates.
|
||||||
@ -91,8 +91,8 @@ pub enum LeoError {
|
|||||||
ImportError(#[from] ImportError),
|
ImportError(#[from] ImportError),
|
||||||
|
|
||||||
/// Represents an Input Error in a Leo Error.
|
/// Represents an Input Error in a Leo Error.
|
||||||
#[error(transparent)]
|
// #[error(transparent)]
|
||||||
InputError(#[from] InputParserError),
|
// InputError(#[from] InputParserError),
|
||||||
|
|
||||||
/// Represents an Package Error in a Leo Error.
|
/// Represents an Package Error in a Leo Error.
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
@ -122,7 +122,7 @@ impl LeoError {
|
|||||||
CliError(error) => error.error_code(),
|
CliError(error) => error.error_code(),
|
||||||
CompilerError(error) => error.error_code(),
|
CompilerError(error) => error.error_code(),
|
||||||
ImportError(error) => error.error_code(),
|
ImportError(error) => error.error_code(),
|
||||||
InputError(_error) => Default::default(), // TODO migrate me, or not cause we want inputs to have 0 deps.
|
// InputError(_error) => Default::default(), // TODO migrate me, or not cause we want inputs to have 0 deps.
|
||||||
PackageError(error) => error.error_code(),
|
PackageError(error) => error.error_code(),
|
||||||
ParserError(error) => error.error_code(),
|
ParserError(error) => error.error_code(),
|
||||||
SnarkVMError(_error) => Default::default(), // TODO update once snarkvm implments a global top level error similar to LeoError.
|
SnarkVMError(_error) => Default::default(), // TODO update once snarkvm implments a global top level error similar to LeoError.
|
||||||
@ -140,7 +140,7 @@ impl LeoError {
|
|||||||
CliError(error) => error.exit_code(),
|
CliError(error) => error.exit_code(),
|
||||||
CompilerError(error) => error.exit_code(),
|
CompilerError(error) => error.exit_code(),
|
||||||
ImportError(error) => error.exit_code(),
|
ImportError(error) => error.exit_code(),
|
||||||
InputError(_error) => 1, // TODO migrate me, or not cause we want inputs to have 0 deps.
|
// InputError(_error) => 1, // TODO migrate me, or not cause we want inputs to have 0 deps.
|
||||||
PackageError(error) => error.exit_code(),
|
PackageError(error) => error.exit_code(),
|
||||||
ParserError(error) => error.exit_code(),
|
ParserError(error) => error.exit_code(),
|
||||||
SnarkVMError(_error) => 1, // TODO update once snarkvm implments a global top level error similar to LeoError.
|
SnarkVMError(_error) => 1, // TODO update once snarkvm implments a global top level error similar to LeoError.
|
||||||
|
@ -18,8 +18,8 @@ use crate::{commands::Command, context::Context};
|
|||||||
use leo_compiler::Compiler;
|
use leo_compiler::Compiler;
|
||||||
use leo_errors::{CliError, Result};
|
use leo_errors::{CliError, Result};
|
||||||
use leo_package::{
|
use leo_package::{
|
||||||
inputs::*,
|
// inputs::*,
|
||||||
outputs::{ChecksumFile, CircuitFile, OutputsDirectory, OUTPUTS_DIRECTORY_NAME},
|
outputs::{ChecksumFile, /* CircuitFile, */ OutputsDirectory, OUTPUTS_DIRECTORY_NAME},
|
||||||
source::{MainFile, MAIN_FILENAME, SOURCE_DIRECTORY_NAME},
|
source::{MainFile, MAIN_FILENAME, SOURCE_DIRECTORY_NAME},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,8 +93,8 @@ pub struct BuildOptions {
|
|||||||
#[derive(StructOpt, Debug)]
|
#[derive(StructOpt, Debug)]
|
||||||
#[structopt(setting = structopt::clap::AppSettings::ColoredHelp)]
|
#[structopt(setting = structopt::clap::AppSettings::ColoredHelp)]
|
||||||
pub struct Build {
|
pub struct Build {
|
||||||
#[structopt(flatten)]
|
// #[structopt(flatten)]
|
||||||
pub(crate) compiler_options: BuildOptions,
|
// pub(crate) compiler_options: BuildOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command for Build {
|
impl Command for Build {
|
||||||
|
@ -29,7 +29,7 @@ use commands::{
|
|||||||
// Deploy, Init, Lint, New, Prove, Run, Setup, Test, Update, Watch,
|
// Deploy, Init, Lint, New, Prove, Run, Setup, Test, Update, Watch,
|
||||||
};
|
};
|
||||||
use leo_errors::Result;
|
use leo_errors::Result;
|
||||||
use snarkvm_utilities::Write;
|
// use snarkvm_utilities::Write;
|
||||||
|
|
||||||
use std::{path::PathBuf, process::exit};
|
use std::{path::PathBuf, process::exit};
|
||||||
use structopt::{clap::AppSettings, StructOpt};
|
use structopt::{clap::AppSettings, StructOpt};
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
// 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 leo_ast::Input;
|
|
||||||
use leo_errors::{emitter::Handler, Result};
|
use leo_errors::{emitter::Handler, Result};
|
||||||
use leo_span::symbol::create_session_if_not_set_then;
|
use leo_span::symbol::create_session_if_not_set_then;
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ fn to_leo_tree(filepath: &Path) -> Result<String> {
|
|||||||
program_string.clone(),
|
program_string.clone(),
|
||||||
filepath.to_str().unwrap(),
|
filepath.to_str().unwrap(),
|
||||||
program_string,
|
program_string,
|
||||||
filepath.to_str().unwrap()
|
filepath.to_str().unwrap(),
|
||||||
)?;
|
)?;
|
||||||
// Ok(Input::to_json_string(&ast).expect("serialization failed"))
|
// Ok(Input::to_json_string(&ast).expect("serialization failed"))
|
||||||
Ok("aa".to_string())
|
Ok("aa".to_string())
|
||||||
|
@ -1,450 +0,0 @@
|
|||||||
// Copyright (C) 2019-2022 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::{assert_no_whitespace, tokenizer::*, Token, KEYWORD_TOKENS};
|
|
||||||
|
|
||||||
use leo_ast::*;
|
|
||||||
use leo_errors::emitter::Handler;
|
|
||||||
use leo_errors::{LeoError, ParserError, Result};
|
|
||||||
use leo_span::{Span, Symbol};
|
|
||||||
|
|
||||||
use std::{borrow::Cow, unreachable};
|
|
||||||
use tendril::format_tendril;
|
|
||||||
|
|
||||||
/// Stores a program in tokenized format plus additional context.
|
|
||||||
/// May be converted into a [`Program`] AST by parsing all tokens.
|
|
||||||
pub struct ParserContext<'a> {
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) handler: &'a Handler,
|
|
||||||
tokens: Vec<SpannedToken>,
|
|
||||||
end_span: Span,
|
|
||||||
// true if parsing an expression for an if statement -- means circuit inits are not legal
|
|
||||||
pub(crate) fuzzy_struct_state: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for ParserContext<'_> {
|
|
||||||
type Item = SpannedToken;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<SpannedToken> {
|
|
||||||
self.bump()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ParserContext<'a> {
|
|
||||||
///
|
|
||||||
/// Returns a new [`ParserContext`] type given a vector of tokens.
|
|
||||||
///
|
|
||||||
pub fn new(handler: &'a Handler, mut tokens: Vec<SpannedToken>) -> Self {
|
|
||||||
tokens.reverse();
|
|
||||||
// todo: performance optimization here: drain filter
|
|
||||||
tokens = tokens
|
|
||||||
.into_iter()
|
|
||||||
.filter(|x| !matches!(x.token, Token::CommentLine(_) | Token::CommentBlock(_)))
|
|
||||||
.collect();
|
|
||||||
Self {
|
|
||||||
handler,
|
|
||||||
end_span: tokens
|
|
||||||
.iter()
|
|
||||||
.find(|x| !x.span.content.trim().is_empty())
|
|
||||||
.map(|x| x.span.clone())
|
|
||||||
.unwrap_or_default(),
|
|
||||||
tokens,
|
|
||||||
fuzzy_struct_state: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the current token if there is one.
|
|
||||||
pub fn peek_option(&self) -> Option<&SpannedToken> {
|
|
||||||
self.tokens.last()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Emit the error `err`.
|
|
||||||
pub(crate) fn emit_err(&self, err: ParserError) {
|
|
||||||
self.handler.emit_err(err.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns an unexpected end of function [`SyntaxError`].
|
|
||||||
///
|
|
||||||
pub fn eof(&self) -> LeoError {
|
|
||||||
ParserError::unexpected_eof(&self.end_span).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns a reference to the next SpannedToken or error if it does not exist.
|
|
||||||
///
|
|
||||||
pub fn peek_next(&self) -> Result<&SpannedToken> {
|
|
||||||
self.tokens.get(self.tokens.len() - 2).ok_or_else(|| self.eof())
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns a reference to the current SpannedToken or error if it does not exist.
|
|
||||||
///
|
|
||||||
pub fn peek(&self) -> Result<&SpannedToken> {
|
|
||||||
self.tokens.last().ok_or_else(|| self.eof())
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns a reference to the next Token.
|
|
||||||
///
|
|
||||||
pub fn peek_token(&self) -> Cow<'_, Token> {
|
|
||||||
self.peek_option()
|
|
||||||
.map(|x| &x.token)
|
|
||||||
.map(Cow::Borrowed)
|
|
||||||
.unwrap_or_else(|| Cow::Owned(Token::Eof))
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns true if the next token exists.
|
|
||||||
///
|
|
||||||
pub fn has_next(&self) -> bool {
|
|
||||||
!self.tokens.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Advances the current token.
|
|
||||||
pub fn bump(&mut self) -> Option<SpannedToken> {
|
|
||||||
self.tokens.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes the next token if it exists and returns it, or [None] if
|
|
||||||
/// the next token does not exist.
|
|
||||||
///
|
|
||||||
pub fn eat(&mut self, token: Token) -> Option<SpannedToken> {
|
|
||||||
if let Some(SpannedToken { token: inner, .. }) = self.peek_option() {
|
|
||||||
if &token == inner {
|
|
||||||
return self.bump();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Appends a token to the back of the vector.
|
|
||||||
///
|
|
||||||
pub fn backtrack(&mut self, token: SpannedToken) {
|
|
||||||
self.tokens.push(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes the next token if it is a [`Token::Ident(_)`] and returns it, or [None] if
|
|
||||||
/// the next token is not a [`Token::Ident(_)`] or if the next token does not exist.
|
|
||||||
///
|
|
||||||
pub fn eat_identifier(&mut self) -> Option<Identifier> {
|
|
||||||
if let Some(SpannedToken {
|
|
||||||
token: Token::Ident(_), ..
|
|
||||||
}) = self.peek_option()
|
|
||||||
{
|
|
||||||
if let SpannedToken {
|
|
||||||
token: Token::Ident(name),
|
|
||||||
span,
|
|
||||||
} = self.bump().unwrap()
|
|
||||||
{
|
|
||||||
return Some(Identifier { name, span });
|
|
||||||
} else {
|
|
||||||
unreachable!("eat_identifier_ shouldn't produce this")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns a reference to the next token if it is a [`GroupCoordinate`], or [None] if
|
|
||||||
/// the next token is not a [`GroupCoordinate`].
|
|
||||||
///
|
|
||||||
fn peek_group_coordinate(&self, i: &mut usize) -> Option<GroupCoordinate> {
|
|
||||||
if *i < 1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let token = self.tokens.get(*i - 1)?;
|
|
||||||
*i -= 1;
|
|
||||||
Some(match &token.token {
|
|
||||||
Token::Add => GroupCoordinate::SignHigh,
|
|
||||||
Token::Minus if *i > 0 => match self.tokens.get(*i - 1) {
|
|
||||||
Some(SpannedToken {
|
|
||||||
token: Token::Int(value),
|
|
||||||
span,
|
|
||||||
}) => {
|
|
||||||
if *i < 1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
*i -= 1;
|
|
||||||
GroupCoordinate::Number(format_tendril!("-{}", value), span.clone())
|
|
||||||
}
|
|
||||||
_ => GroupCoordinate::SignLow,
|
|
||||||
},
|
|
||||||
Token::Underscore => GroupCoordinate::Inferred,
|
|
||||||
Token::Int(value) => GroupCoordinate::Number(value.clone(), token.span.clone()),
|
|
||||||
_ => return None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if the next token is Function or if it is a Const followed by Function.
|
|
||||||
/// Returns `false` otherwise.
|
|
||||||
pub fn peek_is_function(&self) -> Result<bool> {
|
|
||||||
let first = &self.peek()?.token;
|
|
||||||
let next = if self.tokens.len() >= 2 {
|
|
||||||
&self.peek_next()?.token
|
|
||||||
} else {
|
|
||||||
return Ok(false);
|
|
||||||
};
|
|
||||||
Ok(matches!(
|
|
||||||
(first, next),
|
|
||||||
(Token::Function | Token::At, _) | (Token::Const, Token::Function)
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes the next two tokens if they are a pair of [`GroupCoordinate`] and returns them,
|
|
||||||
/// or [None] if the next token is not a [`GroupCoordinate`].
|
|
||||||
///
|
|
||||||
pub fn eat_group_partial(&mut self) -> Option<Result<(GroupCoordinate, GroupCoordinate, Span)>> {
|
|
||||||
let mut i = self.tokens.len();
|
|
||||||
if i < 1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let start_span = self.tokens.get(i - 1)?.span.clone();
|
|
||||||
let first = self.peek_group_coordinate(&mut i)?;
|
|
||||||
if i < 1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
match self.tokens.get(i - 1) {
|
|
||||||
Some(SpannedToken {
|
|
||||||
token: Token::Comma, ..
|
|
||||||
}) => {
|
|
||||||
i -= 1;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let second = self.peek_group_coordinate(&mut i)?;
|
|
||||||
if i < 1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let right_paren_span;
|
|
||||||
match self.tokens.get(i - 1) {
|
|
||||||
Some(SpannedToken {
|
|
||||||
token: Token::RightParen,
|
|
||||||
span,
|
|
||||||
}) => {
|
|
||||||
right_paren_span = span.clone();
|
|
||||||
i -= 1;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i < 1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let end_span;
|
|
||||||
match self.tokens.get(i - 1) {
|
|
||||||
Some(SpannedToken {
|
|
||||||
token: Token::Group,
|
|
||||||
span,
|
|
||||||
}) => {
|
|
||||||
end_span = span.clone();
|
|
||||||
i -= 1;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.tokens.drain(i..);
|
|
||||||
if let Err(e) = assert_no_whitespace(
|
|
||||||
&right_paren_span,
|
|
||||||
&end_span,
|
|
||||||
&format!("({},{})", first, second),
|
|
||||||
"group",
|
|
||||||
) {
|
|
||||||
return Some(Err(e));
|
|
||||||
}
|
|
||||||
Some(Ok((first, second, start_span + end_span)))
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes the next token if it is a [`Token::Int(_)`] and returns it, or [None] if
|
|
||||||
/// the next token is not a [`Token::Int(_)`] or if the next token does not exist.
|
|
||||||
///
|
|
||||||
pub fn eat_int(&mut self) -> Option<(PositiveNumber, Span)> {
|
|
||||||
if let Some(SpannedToken {
|
|
||||||
token: Token::Int(_), ..
|
|
||||||
}) = self.peek_option()
|
|
||||||
{
|
|
||||||
if let SpannedToken {
|
|
||||||
token: Token::Int(value),
|
|
||||||
span,
|
|
||||||
} = self.bump().unwrap()
|
|
||||||
{
|
|
||||||
return Some((PositiveNumber { value }, span));
|
|
||||||
} else {
|
|
||||||
unreachable!("eat_int_ shouldn't produce this")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes the next token if it exists and returns it, or [None] if
|
|
||||||
/// the next token does not exist.
|
|
||||||
///
|
|
||||||
pub fn eat_any(&mut self, token: &[Token]) -> Option<SpannedToken> {
|
|
||||||
if let Some(SpannedToken { token: inner, .. }) = self.peek_option() {
|
|
||||||
if token.iter().any(|x| x == inner) {
|
|
||||||
return self.bump();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns the span of the next token if it is equal to the given [`Token`], or error.
|
|
||||||
///
|
|
||||||
pub fn expect(&mut self, token: Token) -> Result<Span> {
|
|
||||||
if let Some(SpannedToken { token: inner, span }) = self.peek_option() {
|
|
||||||
if &token == inner {
|
|
||||||
Ok(self.bump().unwrap().span)
|
|
||||||
} else {
|
|
||||||
Err(ParserError::unexpected(inner, token, span).into())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(self.eof())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns the span of the next token if it is equal to one of the given [`Token`]s, or error.
|
|
||||||
///
|
|
||||||
pub fn expect_oneof(&mut self, token: &[Token]) -> Result<SpannedToken> {
|
|
||||||
if let Some(SpannedToken { token: inner, span }) = self.peek_option() {
|
|
||||||
if token.iter().any(|x| x == inner) {
|
|
||||||
Ok(self.bump().unwrap())
|
|
||||||
} else {
|
|
||||||
return Err(ParserError::unexpected(
|
|
||||||
inner,
|
|
||||||
token.iter().map(|x| format!("'{}'", x)).collect::<Vec<_>>().join(", "),
|
|
||||||
span,
|
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(self.eof())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns the [`Identifier`] of the next token if it is a keyword,
|
|
||||||
/// [`Token::Int(_)`], or an [`Identifier`], or error.
|
|
||||||
///
|
|
||||||
pub fn expect_loose_identifier(&mut self) -> Result<Identifier> {
|
|
||||||
if let Some(token) = self.eat_any(KEYWORD_TOKENS) {
|
|
||||||
return Ok(Identifier {
|
|
||||||
name: token.token.keyword_to_symbol().unwrap(),
|
|
||||||
span: token.span,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if let Some((int, span)) = self.eat_int() {
|
|
||||||
let name = Symbol::intern(&int.value);
|
|
||||||
return Ok(Identifier { name, span });
|
|
||||||
}
|
|
||||||
self.expect_ident()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the [`Identifier`] of the next token if it is an [`Identifier`], or error.
|
|
||||||
pub fn expect_ident(&mut self) -> Result<Identifier> {
|
|
||||||
if let Some(SpannedToken { token: inner, span }) = self.peek_option() {
|
|
||||||
if let Token::Ident(_) = inner {
|
|
||||||
if let SpannedToken {
|
|
||||||
token: Token::Ident(name),
|
|
||||||
span,
|
|
||||||
} = self.bump().unwrap()
|
|
||||||
{
|
|
||||||
Ok(Identifier { name, span })
|
|
||||||
} else {
|
|
||||||
unreachable!("expect_ident_ shouldn't produce this")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(ParserError::unexpected_str(inner, "ident", span).into())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(self.eof())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns the next token if it exists or return end of function.
|
|
||||||
///
|
|
||||||
pub fn expect_any(&mut self) -> Result<SpannedToken> {
|
|
||||||
if let Some(x) = self.tokens.pop() {
|
|
||||||
Ok(x)
|
|
||||||
} else {
|
|
||||||
Err(self.eof())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parses a list of `T`s using `inner`
|
|
||||||
/// The opening and closing delimiters are `bra` and `ket`,
|
|
||||||
/// and elements in the list are separated by `sep`.
|
|
||||||
/// When `(list, true)` is returned, `sep` was a terminator.
|
|
||||||
pub(crate) fn parse_list<T>(
|
|
||||||
&mut self,
|
|
||||||
open: Token,
|
|
||||||
close: Token,
|
|
||||||
sep: Token,
|
|
||||||
mut inner: impl FnMut(&mut Self) -> Result<Option<T>>,
|
|
||||||
) -> Result<(Vec<T>, bool, Span)> {
|
|
||||||
let mut list = Vec::new();
|
|
||||||
let mut trailing = false;
|
|
||||||
|
|
||||||
// Parse opening delimiter.
|
|
||||||
let open_span = self.expect(open)?;
|
|
||||||
|
|
||||||
while self.peek()?.token != close {
|
|
||||||
// Parse the element. We allow inner parser recovery through the `Option`.
|
|
||||||
if let Some(elem) = inner(self)? {
|
|
||||||
list.push(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the separator.
|
|
||||||
if self.eat(sep.clone()).is_none() {
|
|
||||||
trailing = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
trailing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse closing delimiter.
|
|
||||||
let close_span = self.expect(close)?;
|
|
||||||
|
|
||||||
Ok((list, trailing, open_span + close_span))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse a list separated by `,` and delimited by parens.
|
|
||||||
pub(crate) fn parse_paren_comma_list<T>(
|
|
||||||
&mut self,
|
|
||||||
f: impl FnMut(&mut Self) -> Result<Option<T>>,
|
|
||||||
) -> Result<(Vec<T>, bool, Span)> {
|
|
||||||
self.parse_list(Token::LeftParen, Token::RightParen, Token::Comma, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the current token is `(`.
|
|
||||||
pub(crate) fn peek_is_left_par(&self) -> bool {
|
|
||||||
matches!(self.peek_option().map(|t| &t.token), Some(Token::LeftParen))
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,14 +14,14 @@
|
|||||||
// 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_no_whitespace, tokenizer::*, Token, KEYWORD_TOKENS};
|
use crate::{assert_no_whitespace, tokenizer::*, Token};
|
||||||
|
|
||||||
use leo_ast::*;
|
use leo_ast::*;
|
||||||
use leo_errors::emitter::Handler;
|
use leo_errors::emitter::Handler;
|
||||||
use leo_errors::{LeoError, ParserError, Result};
|
use leo_errors::{LeoError, ParserError, Result};
|
||||||
use leo_span::{Span, Symbol};
|
use leo_span::{Span, Symbol};
|
||||||
|
|
||||||
use std::{borrow::Cow, unreachable};
|
use std::unreachable;
|
||||||
use tendril::format_tendril;
|
use tendril::format_tendril;
|
||||||
|
|
||||||
/// Stores a program in tokenized format plus additional context.
|
/// Stores a program in tokenized format plus additional context.
|
||||||
@ -31,8 +31,6 @@ pub struct InputParserContext<'a> {
|
|||||||
pub(crate) handler: &'a Handler,
|
pub(crate) handler: &'a Handler,
|
||||||
tokens: Vec<SpannedToken>,
|
tokens: Vec<SpannedToken>,
|
||||||
end_span: Span,
|
end_span: Span,
|
||||||
// true if parsing an expression for an if statement -- means circuit inits are not legal
|
|
||||||
pub(crate) fuzzy_struct_state: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for InputParserContext<'_> {
|
impl Iterator for InputParserContext<'_> {
|
||||||
@ -62,7 +60,7 @@ impl<'a> InputParserContext<'a> {
|
|||||||
.map(|x| x.span.clone())
|
.map(|x| x.span.clone())
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
tokens,
|
tokens,
|
||||||
fuzzy_struct_state: false,
|
// fuzzy_struct_state: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,9 +84,9 @@ impl<'a> InputParserContext<'a> {
|
|||||||
///
|
///
|
||||||
/// Returns a reference to the next SpannedToken or error if it does not exist.
|
/// Returns a reference to the next SpannedToken or error if it does not exist.
|
||||||
///
|
///
|
||||||
pub fn peek_next(&self) -> Result<&SpannedToken> {
|
// pub fn peek_next(&self) -> Result<&SpannedToken> {
|
||||||
self.tokens.get(self.tokens.len() - 2).ok_or_else(|| self.eof())
|
// self.tokens.get(self.tokens.len() - 2).ok_or_else(|| self.eof())
|
||||||
}
|
// }
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a reference to the current SpannedToken or error if it does not exist.
|
/// Returns a reference to the current SpannedToken or error if it does not exist.
|
||||||
@ -100,12 +98,12 @@ impl<'a> InputParserContext<'a> {
|
|||||||
///
|
///
|
||||||
/// Returns a reference to the next Token.
|
/// Returns a reference to the next Token.
|
||||||
///
|
///
|
||||||
pub fn peek_token(&self) -> Cow<'_, Token> {
|
// pub fn peek_token(&self) -> Cow<'_, Token> {
|
||||||
self.peek_option()
|
// self.peek_option()
|
||||||
.map(|x| &x.token)
|
// .map(|x| &x.token)
|
||||||
.map(Cow::Borrowed)
|
// .map(Cow::Borrowed)
|
||||||
.unwrap_or_else(|| Cow::Owned(Token::Eof))
|
// .unwrap_or_else(|| Cow::Owned(Token::Eof))
|
||||||
}
|
// }
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns true if the next token exists.
|
/// Returns true if the next token exists.
|
||||||
@ -135,9 +133,9 @@ impl<'a> InputParserContext<'a> {
|
|||||||
///
|
///
|
||||||
/// Appends a token to the back of the vector.
|
/// Appends a token to the back of the vector.
|
||||||
///
|
///
|
||||||
pub fn backtrack(&mut self, token: SpannedToken) {
|
// pub fn backtrack(&mut self, token: SpannedToken) {
|
||||||
self.tokens.push(token);
|
// self.tokens.push(token);
|
||||||
}
|
// }
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Removes the next token if it is a [`Token::Ident(_)`] and returns it, or [None] if
|
/// Removes the next token if it is a [`Token::Ident(_)`] and returns it, or [None] if
|
||||||
@ -194,18 +192,18 @@ impl<'a> InputParserContext<'a> {
|
|||||||
|
|
||||||
/// Returns `true` if the next token is Function or if it is a Const followed by Function.
|
/// Returns `true` if the next token is Function or if it is a Const followed by Function.
|
||||||
/// Returns `false` otherwise.
|
/// Returns `false` otherwise.
|
||||||
pub fn peek_is_function(&self) -> Result<bool> {
|
// pub fn peek_is_function(&self) -> Result<bool> {
|
||||||
let first = &self.peek()?.token;
|
// let first = &self.peek()?.token;
|
||||||
let next = if self.tokens.len() >= 2 {
|
// let next = if self.tokens.len() >= 2 {
|
||||||
&self.peek_next()?.token
|
// &self.peek_next()?.token
|
||||||
} else {
|
// } else {
|
||||||
return Ok(false);
|
// return Ok(false);
|
||||||
};
|
// };
|
||||||
Ok(matches!(
|
// Ok(matches!(
|
||||||
(first, next),
|
// (first, next),
|
||||||
(Token::Function | Token::At, _) | (Token::Const, Token::Function)
|
// (Token::Function | Token::At, _) | (Token::Const, Token::Function)
|
||||||
))
|
// ))
|
||||||
}
|
// }
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Removes the next two tokens if they are a pair of [`GroupCoordinate`] and returns them,
|
/// Removes the next two tokens if they are a pair of [`GroupCoordinate`] and returns them,
|
||||||
@ -351,19 +349,19 @@ impl<'a> InputParserContext<'a> {
|
|||||||
/// Returns the [`Identifier`] of the next token if it is a keyword,
|
/// Returns the [`Identifier`] of the next token if it is a keyword,
|
||||||
/// [`Token::Int(_)`], or an [`Identifier`], or error.
|
/// [`Token::Int(_)`], or an [`Identifier`], or error.
|
||||||
///
|
///
|
||||||
pub fn expect_loose_identifier(&mut self) -> Result<Identifier> {
|
// pub fn expect_loose_identifier(&mut self) -> Result<Identifier> {
|
||||||
if let Some(token) = self.eat_any(KEYWORD_TOKENS) {
|
// if let Some(token) = self.eat_any(KEYWORD_TOKENS) {
|
||||||
return Ok(Identifier {
|
// return Ok(Identifier {
|
||||||
name: token.token.keyword_to_symbol().unwrap(),
|
// name: token.token.keyword_to_symbol().unwrap(),
|
||||||
span: token.span,
|
// span: token.span,
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
if let Some((int, span)) = self.eat_int() {
|
// if let Some((int, span)) = self.eat_int() {
|
||||||
let name = Symbol::intern(&int.value);
|
// let name = Symbol::intern(&int.value);
|
||||||
return Ok(Identifier { name, span });
|
// return Ok(Identifier { name, span });
|
||||||
}
|
// }
|
||||||
self.expect_ident()
|
// self.expect_ident()
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Returns the [`Identifier`] of the next token if it is an [`Identifier`], or error.
|
/// Returns the [`Identifier`] of the next token if it is an [`Identifier`], or error.
|
||||||
pub fn expect_ident(&mut self) -> Result<Identifier> {
|
pub fn expect_ident(&mut self) -> Result<Identifier> {
|
||||||
|
@ -15,13 +15,10 @@
|
|||||||
// 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 super::*;
|
use super::*;
|
||||||
use crate::KEYWORD_TOKENS;
|
use crate::{SpannedToken, Token};
|
||||||
|
use leo_errors::{ParserError, Result};
|
||||||
|
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
use leo_errors::{ParserError, Result};
|
|
||||||
use leo_span::sym;
|
|
||||||
use crate::{Token, SpannedToken};
|
|
||||||
use tendril::format_tendril;
|
|
||||||
|
|
||||||
const INT_TYPES: &[Token] = &[
|
const INT_TYPES: &[Token] = &[
|
||||||
Token::I8,
|
Token::I8,
|
||||||
@ -57,7 +54,6 @@ pub(crate) const TYPE_TOKENS: &[Token] = &[
|
|||||||
];
|
];
|
||||||
|
|
||||||
impl InputParserContext<'_> {
|
impl InputParserContext<'_> {
|
||||||
|
|
||||||
pub fn token_to_int_type(token: Token) -> Option<IntegerType> {
|
pub fn token_to_int_type(token: Token) -> Option<IntegerType> {
|
||||||
Some(match token {
|
Some(match token {
|
||||||
Token::I8 => IntegerType::I8,
|
Token::I8 => IntegerType::I8,
|
||||||
@ -74,27 +70,25 @@ impl InputParserContext<'_> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
/// Returns an [`Input`] struct filled with the data acquired in the file.
|
||||||
/// Returns a [`Program`] AST if all tokens can be consumed and represent a valid Leo program.
|
|
||||||
///
|
|
||||||
pub fn parse_input(&mut self) -> Result<Input> {
|
pub fn parse_input(&mut self) -> Result<Input> {
|
||||||
|
let mut values = IndexMap::new();
|
||||||
while self.has_next() {
|
while self.has_next() {
|
||||||
let token = self.peek()?;
|
let token = self.peek()?;
|
||||||
|
|
||||||
match token.token {
|
match token.token {
|
||||||
Token::LeftSquare => {
|
Token::LeftSquare => {
|
||||||
let (section, definitions) = self.parse_section()?;
|
let (section, definitions) = self.parse_section()?;
|
||||||
println!("Section: {}, Definitions (len): {}", section, definitions.len());
|
println!("Section: {}, Definitions (len): {}", section, definitions.len());
|
||||||
},
|
values.insert(section, definitions);
|
||||||
_ => ()
|
}
|
||||||
|
_ => return Err(ParserError::unexpected_token(token.token.clone(), &token.span).into()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(Input::new(values))
|
||||||
Ok(Input::new())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses particular section in the Input file or the State file.
|
||||||
pub fn parse_section(&mut self) -> Result<(Identifier, IndexMap<Identifier, (Type, Expression)>)> {
|
pub fn parse_section(&mut self) -> Result<(Identifier, IndexMap<Identifier, (Type, Expression)>)> {
|
||||||
self.expect(Token::LeftSquare)?;
|
self.expect(Token::LeftSquare)?;
|
||||||
let section = self.expect_ident()?;
|
let section = self.expect_ident()?;
|
||||||
@ -125,7 +119,6 @@ impl InputParserContext<'_> {
|
|||||||
Ok((var, (type_, value)))
|
Ok((var, (type_, value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type.
|
/// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type.
|
||||||
/// Also returns the span of the parsed token.
|
/// Also returns the span of the parsed token.
|
||||||
pub fn parse_type(&mut self) -> Result<(Type, Span)> {
|
pub fn parse_type(&mut self) -> Result<(Type, Span)> {
|
||||||
@ -246,12 +239,12 @@ impl InputParserContext<'_> {
|
|||||||
Token::StringLit(value) => Expression::Value(ValueExpression::String(value, span)),
|
Token::StringLit(value) => Expression::Value(ValueExpression::String(value, span)),
|
||||||
Token::LeftParen => self.parse_tuple_expression(&span)?,
|
Token::LeftParen => self.parse_tuple_expression(&span)?,
|
||||||
Token::LeftSquare => self.parse_array_expression(&span)?,
|
Token::LeftSquare => self.parse_array_expression(&span)?,
|
||||||
Token::Ident(name) => Expression::Identifier(Identifier { name, span }),
|
// Token::Ident(name) => Expression::Identifier(Identifier { name, span }),
|
||||||
Token::Input => Expression::Identifier(Identifier { name: sym::input, span }),
|
// Token::Input => Expression::Identifier(Identifier { name: sym::input, span }),
|
||||||
t if crate::type_::TYPE_TOKENS.contains(&t) => Expression::Identifier(Identifier {
|
// t if crate::type_::TYPE_TOKENS.contains(&t) => Expression::Identifier(Identifier {
|
||||||
name: t.keyword_to_symbol().unwrap(),
|
// name: t.keyword_to_symbol().unwrap(),
|
||||||
span,
|
// span,
|
||||||
}),
|
// }),
|
||||||
token => {
|
token => {
|
||||||
return Err(ParserError::unexpected_str(token, "expression", &span).into());
|
return Err(ParserError::unexpected_str(token, "expression", &span).into());
|
||||||
}
|
}
|
||||||
@ -337,7 +330,10 @@ impl InputParserContext<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Expression::ArrayInline(ArrayInlineExpression {
|
Ok(Expression::ArrayInline(ArrayInlineExpression {
|
||||||
elements: elements.into_iter().map(|expr| SpreadOrExpression::Expression(expr)).collect(),
|
elements: elements
|
||||||
|
.into_iter()
|
||||||
|
.map(|expr| SpreadOrExpression::Expression(expr))
|
||||||
|
.collect(),
|
||||||
span: span + &end_span,
|
span: span + &end_span,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,8 @@ pub mod file;
|
|||||||
|
|
||||||
use leo_ast::*;
|
use leo_ast::*;
|
||||||
use leo_errors::emitter::Handler;
|
use leo_errors::emitter::Handler;
|
||||||
use leo_errors::{ParserError, Result};
|
use leo_errors::Result;
|
||||||
use leo_span::{Span, Symbol};
|
use leo_span::Span;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
|
@ -53,8 +53,9 @@ pub fn parse_program_input<T: AsRef<str>, Y: AsRef<str>, T2: AsRef<str>, Y2: AsR
|
|||||||
_state_string: T2,
|
_state_string: T2,
|
||||||
_state_path: Y2,
|
_state_path: Y2,
|
||||||
) -> Result<Input> {
|
) -> Result<Input> {
|
||||||
|
let input = input_parser::parse(handler, input_path.as_ref(), input_string.as_ref())?;
|
||||||
|
|
||||||
input_parser::parse(handler, input_path.as_ref(), input_string.as_ref())
|
Ok(input)
|
||||||
|
|
||||||
// let input_syntax_tree = LeoInputParser::parse_file(input_string.as_ref()).map_err(|mut e| {
|
// let input_syntax_tree = LeoInputParser::parse_file(input_string.as_ref()).map_err(|mut e| {
|
||||||
// e.set_path(
|
// e.set_path(
|
||||||
|
Loading…
Reference in New Issue
Block a user