mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-11 16:10:09 +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",
|
||||
"indexmap",
|
||||
"leo-errors",
|
||||
"leo-input",
|
||||
"leo-span",
|
||||
"pest",
|
||||
"serde",
|
||||
@ -1140,7 +1139,6 @@ dependencies = [
|
||||
"colored",
|
||||
"derivative",
|
||||
"eyre",
|
||||
"leo-input",
|
||||
"leo-span",
|
||||
"pest",
|
||||
"serde",
|
||||
|
@ -21,9 +21,9 @@ rust-version = "1.56"
|
||||
[dependencies]
|
||||
smallvec = { version = "1.8.0", features = ["serde"] }
|
||||
|
||||
[dependencies.leo-input]
|
||||
path = "../input"
|
||||
version = "1.5.3"
|
||||
# [dependencies.leo-input]
|
||||
# path = "../input"
|
||||
# version = "1.5.3"
|
||||
|
||||
[dependencies.leo-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
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
mod context;
|
||||
pub use context::*;
|
||||
#![allow(clippy::module_inception)]
|
||||
|
||||
#[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 serde::{Deserialize, Serialize};
|
||||
// use serde::de::{Deserialize as SerDeserialize, Deserializer};
|
||||
use std::fmt;
|
||||
|
||||
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/>.
|
||||
|
||||
use crate::PositiveNumber;
|
||||
use leo_input::types::ArrayDimensions as InputArrayDimensions;
|
||||
|
||||
use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer};
|
||||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match &*self.0 {
|
||||
|
@ -14,7 +14,6 @@
|
||||
// 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 leo_input::common::Identifier as InputIdentifier;
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
|
@ -14,8 +14,6 @@
|
||||
// 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 leo_input::values::PositiveNumber as InputPositiveNumber;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
|
@ -14,10 +14,6 @@
|
||||
// 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 leo_input::values::{
|
||||
GroupCoordinate as InputGroupCoordinate, Inferred as InputInferred, NumberValue as InputNumberValue,
|
||||
SignHigh as InputSignHigh, SignLow as InputSignLow,
|
||||
};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -40,17 +36,6 @@ pub enum GroupCoordinate {
|
||||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
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/>.
|
||||
|
||||
use crate::groups::GroupCoordinate;
|
||||
use leo_input::values::{
|
||||
GroupRepresentation as InputGroupRepresentation, GroupTuple as InputGroupTuple, GroupValue as InputGroupValue,
|
||||
};
|
||||
use leo_span::Span;
|
||||
|
||||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@ -83,19 +69,6 @@ pub struct GroupTuple {
|
||||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
|
@ -15,15 +15,6 @@
|
||||
// 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;
|
||||
|
||||
@ -80,23 +71,23 @@ impl InputValue {
|
||||
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 {
|
||||
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())),
|
||||
Type::Address(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||
Type::Boolean(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||
Type::Char(_) => Err(InputParserError::implicit_type(data_type, implicit)),
|
||||
Type::Integer(integer_type) => Ok(InputValue::from_number(integer_type, implicit.to_string())),
|
||||
Type::Group(_) => Err(InputParserError::implicit_group(implicit)),
|
||||
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) {
|
||||
(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)) => {
|
||||
(Type::Address(_), Value::Address(address)) => Ok(InputValue::from_address_value(address)),
|
||||
(Type::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean),
|
||||
(Type::Char(_), Value::Char(character)) => InputValue::from_char(character),
|
||||
(Type::Integer(integer_type), Value::Integer(integer)) => {
|
||||
match integer.clone() {
|
||||
IntegerValue::Signed(signed) => {
|
||||
if let InputIntegerType::Signed(inner) = integer_type.clone() {
|
||||
@ -125,8 +116,8 @@ impl InputValue {
|
||||
}
|
||||
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)),
|
||||
(Type::Group(_), Value::Group(group)) => Ok(InputValue::from_group(group)),
|
||||
(Type::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)),
|
||||
}
|
||||
@ -155,7 +146,7 @@ impl InputValue {
|
||||
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 {}))));
|
||||
assert!(matches!(*array_type.type_, Type::Basic(Type::Char(CharType {}))));
|
||||
|
||||
// Convert the array dimensions to usize.
|
||||
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
|
||||
// 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]
|
||||
pub mod macros;
|
||||
pub use macros::*;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Input {
|
||||
values: IndexMap<Identifier, IndexMap<Identifier, (Type, Expression)>>,
|
||||
}
|
||||
|
||||
pub mod input;
|
||||
pub use input::*;
|
||||
impl 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;
|
||||
pub use input_value::*;
|
||||
Input { values }
|
||||
}
|
||||
}
|
||||
|
||||
pub mod parameters;
|
||||
pub use parameters::*;
|
||||
impl InputValue {
|
||||
pub fn create(type_: Type, expression: Expression) -> Result<Self> {
|
||||
dbg!(InputValue::try_from((type_, expression))?);
|
||||
Ok(InputValue::Boolean(true))
|
||||
}
|
||||
}
|
||||
|
||||
pub mod program_input;
|
||||
pub use program_input::*;
|
||||
#[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>),
|
||||
|
||||
pub mod program_state;
|
||||
pub use program_state::*;
|
||||
// Should be removed later
|
||||
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
|
||||
// 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 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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
@ -15,9 +15,6 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
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 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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
@ -1 +0,0 @@
|
||||
ok
|
@ -25,9 +25,9 @@ version = "0.3.62"
|
||||
path = "../span"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.leo-input]
|
||||
path = "../input"
|
||||
version = "1.5.3"
|
||||
# [dependencies.leo-input]
|
||||
# path = "../input"
|
||||
# version = "1.5.3"
|
||||
|
||||
[dependencies.colored]
|
||||
version = "2.0.0"
|
||||
|
@ -64,7 +64,7 @@ pub use self::state::*;
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
use leo_input::InputParserError;
|
||||
// use leo_input::InputParserError;
|
||||
|
||||
/// The LeoError type that contains all sub error types.
|
||||
/// This allows a unified error type throughout the Leo crates.
|
||||
@ -91,8 +91,8 @@ pub enum LeoError {
|
||||
ImportError(#[from] ImportError),
|
||||
|
||||
/// Represents an Input Error in a Leo Error.
|
||||
#[error(transparent)]
|
||||
InputError(#[from] InputParserError),
|
||||
// #[error(transparent)]
|
||||
// InputError(#[from] InputParserError),
|
||||
|
||||
/// Represents an Package Error in a Leo Error.
|
||||
#[error(transparent)]
|
||||
@ -122,7 +122,7 @@ impl LeoError {
|
||||
CliError(error) => error.error_code(),
|
||||
CompilerError(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(),
|
||||
ParserError(error) => error.error_code(),
|
||||
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(),
|
||||
CompilerError(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(),
|
||||
ParserError(error) => error.exit_code(),
|
||||
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_errors::{CliError, Result};
|
||||
use leo_package::{
|
||||
inputs::*,
|
||||
outputs::{ChecksumFile, CircuitFile, OutputsDirectory, OUTPUTS_DIRECTORY_NAME},
|
||||
// inputs::*,
|
||||
outputs::{ChecksumFile, /* CircuitFile, */ OutputsDirectory, OUTPUTS_DIRECTORY_NAME},
|
||||
source::{MainFile, MAIN_FILENAME, SOURCE_DIRECTORY_NAME},
|
||||
};
|
||||
|
||||
@ -93,8 +93,8 @@ pub struct BuildOptions {
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(setting = structopt::clap::AppSettings::ColoredHelp)]
|
||||
pub struct Build {
|
||||
#[structopt(flatten)]
|
||||
pub(crate) compiler_options: BuildOptions,
|
||||
// #[structopt(flatten)]
|
||||
// pub(crate) compiler_options: BuildOptions,
|
||||
}
|
||||
|
||||
impl Command for Build {
|
||||
|
@ -29,7 +29,7 @@ use commands::{
|
||||
// Deploy, Init, Lint, New, Prove, Run, Setup, Test, Update, Watch,
|
||||
};
|
||||
use leo_errors::Result;
|
||||
use snarkvm_utilities::Write;
|
||||
// use snarkvm_utilities::Write;
|
||||
|
||||
use std::{path::PathBuf, process::exit};
|
||||
use structopt::{clap::AppSettings, StructOpt};
|
||||
|
@ -14,7 +14,6 @@
|
||||
// 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 leo_ast::Input;
|
||||
use leo_errors::{emitter::Handler, Result};
|
||||
use leo_span::symbol::create_session_if_not_set_then;
|
||||
|
||||
@ -28,12 +27,12 @@ fn to_leo_tree(filepath: &Path) -> Result<String> {
|
||||
// Parses the Leo file constructing an ast which is then serialized.
|
||||
create_session_if_not_set_then(|_| {
|
||||
let handler = Handler::default();
|
||||
let _ast = leo_parser::parse_program_input(
|
||||
let _ast = leo_parser::parse_program_input(
|
||||
&handler,
|
||||
program_string.clone(),
|
||||
filepath.to_str().unwrap(),
|
||||
program_string,
|
||||
filepath.to_str().unwrap()
|
||||
program_string,
|
||||
filepath.to_str().unwrap(),
|
||||
)?;
|
||||
// Ok(Input::to_json_string(&ast).expect("serialization failed"))
|
||||
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
|
||||
// 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_errors::emitter::Handler;
|
||||
use leo_errors::{LeoError, ParserError, Result};
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
use std::{borrow::Cow, unreachable};
|
||||
use std::unreachable;
|
||||
use tendril::format_tendril;
|
||||
|
||||
/// Stores a program in tokenized format plus additional context.
|
||||
@ -31,8 +31,6 @@ pub struct InputParserContext<'a> {
|
||||
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 InputParserContext<'_> {
|
||||
@ -62,7 +60,7 @@ impl<'a> InputParserContext<'a> {
|
||||
.map(|x| x.span.clone())
|
||||
.unwrap_or_default(),
|
||||
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.
|
||||
///
|
||||
pub fn peek_next(&self) -> Result<&SpannedToken> {
|
||||
self.tokens.get(self.tokens.len() - 2).ok_or_else(|| self.eof())
|
||||
}
|
||||
// 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.
|
||||
@ -100,12 +98,12 @@ impl<'a> InputParserContext<'a> {
|
||||
///
|
||||
/// 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))
|
||||
}
|
||||
// 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.
|
||||
@ -135,9 +133,9 @@ impl<'a> InputParserContext<'a> {
|
||||
///
|
||||
/// Appends a token to the back of the vector.
|
||||
///
|
||||
pub fn backtrack(&mut self, token: SpannedToken) {
|
||||
self.tokens.push(token);
|
||||
}
|
||||
// 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
|
||||
@ -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 `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)
|
||||
))
|
||||
}
|
||||
// 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,
|
||||
@ -351,19 +349,19 @@ impl<'a> InputParserContext<'a> {
|
||||
/// 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()
|
||||
}
|
||||
// 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> {
|
||||
|
@ -15,13 +15,10 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
use crate::KEYWORD_TOKENS;
|
||||
use crate::{SpannedToken, Token};
|
||||
use leo_errors::{ParserError, Result};
|
||||
|
||||
use smallvec::smallvec;
|
||||
use leo_errors::{ParserError, Result};
|
||||
use leo_span::sym;
|
||||
use crate::{Token, SpannedToken};
|
||||
use tendril::format_tendril;
|
||||
|
||||
const INT_TYPES: &[Token] = &[
|
||||
Token::I8,
|
||||
@ -57,7 +54,6 @@ pub(crate) const TYPE_TOKENS: &[Token] = &[
|
||||
];
|
||||
|
||||
impl InputParserContext<'_> {
|
||||
|
||||
pub fn token_to_int_type(token: Token) -> Option<IntegerType> {
|
||||
Some(match token {
|
||||
Token::I8 => IntegerType::I8,
|
||||
@ -74,27 +70,25 @@ impl InputParserContext<'_> {
|
||||
})
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a [`Program`] AST if all tokens can be consumed and represent a valid Leo program.
|
||||
///
|
||||
/// Returns an [`Input`] struct filled with the data acquired in the file.
|
||||
pub fn parse_input(&mut self) -> Result<Input> {
|
||||
|
||||
let mut values = IndexMap::new();
|
||||
while self.has_next() {
|
||||
let token = self.peek()?;
|
||||
|
||||
match token.token {
|
||||
Token::LeftSquare => {
|
||||
let (section, definitions) = self.parse_section()?;
|
||||
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())
|
||||
Ok(Input::new(values))
|
||||
}
|
||||
|
||||
/// Parses particular section in the Input file or the State file.
|
||||
pub fn parse_section(&mut self) -> Result<(Identifier, IndexMap<Identifier, (Type, Expression)>)> {
|
||||
self.expect(Token::LeftSquare)?;
|
||||
let section = self.expect_ident()?;
|
||||
@ -110,8 +104,8 @@ impl InputParserContext<'_> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok((section, assignments))
|
||||
|
||||
Ok((section, assignments))
|
||||
}
|
||||
|
||||
pub fn parse_assignment(&mut self) -> Result<(Identifier, (Type, Expression))> {
|
||||
@ -125,7 +119,6 @@ impl InputParserContext<'_> {
|
||||
Ok((var, (type_, value)))
|
||||
}
|
||||
|
||||
|
||||
/// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type.
|
||||
/// Also returns the span of the parsed token.
|
||||
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::LeftParen => self.parse_tuple_expression(&span)?,
|
||||
Token::LeftSquare => self.parse_array_expression(&span)?,
|
||||
Token::Ident(name) => Expression::Identifier(Identifier { name, span }),
|
||||
Token::Input => Expression::Identifier(Identifier { name: sym::input, span }),
|
||||
t if crate::type_::TYPE_TOKENS.contains(&t) => Expression::Identifier(Identifier {
|
||||
name: t.keyword_to_symbol().unwrap(),
|
||||
span,
|
||||
}),
|
||||
// Token::Ident(name) => Expression::Identifier(Identifier { name, span }),
|
||||
// Token::Input => Expression::Identifier(Identifier { name: sym::input, span }),
|
||||
// t if crate::type_::TYPE_TOKENS.contains(&t) => Expression::Identifier(Identifier {
|
||||
// name: t.keyword_to_symbol().unwrap(),
|
||||
// span,
|
||||
// }),
|
||||
token => {
|
||||
return Err(ParserError::unexpected_str(token, "expression", &span).into());
|
||||
}
|
||||
@ -337,7 +330,10 @@ impl InputParserContext<'_> {
|
||||
}
|
||||
}
|
||||
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,
|
||||
}))
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ pub mod file;
|
||||
|
||||
use leo_ast::*;
|
||||
use leo_errors::emitter::Handler;
|
||||
use leo_errors::{ParserError, Result};
|
||||
use leo_span::{Span, Symbol};
|
||||
use leo_errors::Result;
|
||||
use leo_span::Span;
|
||||
|
||||
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_path: Y2,
|
||||
) -> Result<Input> {
|
||||
|
||||
input_parser::parse(handler, input_path.as_ref(), input_string.as_ref())
|
||||
let input = 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| {
|
||||
// e.set_path(
|
||||
|
Loading…
Reference in New Issue
Block a user