Change PositiveNumber to NonzeroNumber

This commit is contained in:
Pranav Gaddamadugu 2023-10-09 14:51:26 -04:00 committed by Pranav Gaddamadugu
parent 7e471b7748
commit 072ab7b930
5 changed files with 43 additions and 23 deletions

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{Expression, Node, NodeID, PositiveNumber};
use crate::{Expression, Node, NodeID, NonzeroNumber};
use leo_span::Span;
use serde::{Deserialize, Serialize};
@ -26,7 +26,7 @@ pub struct TupleAccess {
/// An expression evaluating to some tuple type, e.g., `(5, 2)`.
pub tuple: Box<Expression>,
/// The index to access in the tuple expression. E.g., `0` for `(5, 2)` would yield `5`.
pub index: PositiveNumber,
pub index: NonzeroNumber,
/// The span for the entire expression `tuple.index`.
pub span: Span,
/// The ID of the node.

View File

@ -17,27 +17,47 @@
use serde::{Deserialize, Serialize};
use std::{fmt, str::FromStr};
/// A number string guaranteed to be positive.
/// A number string guaranteed to be nonzero.
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
pub struct PositiveNumber {
/// The string representation of the positive number.
// FIXME(Centril): This should become an `u128`.
pub value: String,
pub struct NonzeroNumber {
/// The string representation of the nonzero number.
string: String,
/// The numeric value of the nonzero number.
value: usize,
}
impl PositiveNumber {
impl NonzeroNumber {
/// Returns the string representation of the nonzero number.
pub fn string(&self) -> &str {
&self.string
}
/// Returns the numeric value of the nonzero number.
pub fn value(&self) -> usize {
self.value
}
/// Returns `true` if this number is zero.
pub fn is_zero(&self) -> bool {
self.value.eq("0")
}
/// Converts the positive number into a `usize` or panics if it was malformed.
pub fn to_usize(&self) -> usize {
usize::from_str(&self.value).expect("failed to parse positive number")
self.value == 0
}
}
impl fmt::Display for PositiveNumber {
impl From<String> for NonzeroNumber {
fn from(string: String) -> Self {
let value = usize::from_str(&string).unwrap();
Self { string, value }
}
}
impl From<usize> for NonzeroNumber {
fn from(value: usize) -> Self {
let string = value.to_string();
Self { string, value }
}
}
impl fmt::Display for NonzeroNumber {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{PositiveNumber, Type};
use crate::{NonzeroNumber, Type};
use serde::{Deserialize, Serialize};
use std::fmt;
@ -23,12 +23,12 @@ use std::fmt;
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ArrayType {
element_type: Box<Type>,
length: PositiveNumber,
length: NonzeroNumber,
}
impl ArrayType {
/// Creates a new array type.
pub fn new(element: Type, length: PositiveNumber) -> Self {
pub fn new(element: Type, length: NonzeroNumber) -> Self {
Self { element_type: Box::new(element), length }
}
@ -39,7 +39,7 @@ impl ArrayType {
/// Returns the length of the array.
pub fn length(&self) -> usize {
self.length.to_usize()
self.length.value()
}
/// Returns the base element type of the array.

View File

@ -156,7 +156,7 @@ impl<'a> ParserContext<'a> {
/// Removes the next token if it is a [`Token::Integer(_)`] and returns it, or [None] if
/// the next token is not a [`Token::Integer(_)`] or if the next token does not exist.
///
pub fn eat_whole_number(&mut self) -> Result<(PositiveNumber, Span)> {
pub fn eat_whole_number(&mut self) -> Result<(NonzeroNumber, Span)> {
if let Token::Integer(value) = &self.token.token {
let value = value.clone();
self.bump();
@ -165,7 +165,7 @@ impl<'a> ParserContext<'a> {
return Err(ParserError::tuple_index_must_be_whole_number(&self.token.token, self.token.span).into());
}
Ok((PositiveNumber { value }, self.prev_token.span))
Ok((NonzeroNumber::from(value), self.prev_token.span))
} else {
Err(ParserError::unexpected(&self.token.token, "integer literal", self.token.span).into())
}

View File

@ -100,7 +100,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
match type_ {
Type::Tuple(tuple) => {
// Check out of range access.
let index = access.index.to_usize();
let index = access.index.value();
if index > tuple.len() - 1 {
self.emit_err(TypeCheckerError::tuple_out_of_range(index, tuple.len(), access.span()));
} else {
@ -255,7 +255,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
self.assert_type(&element_type, &first_type, element.span());
}
// Return the array type.
Type::Array(ArrayType::new(first_type, PositiveNumber { value: input.elements.len().to_string() }))
Type::Array(ArrayType::new(first_type, NonzeroNumber::from(input.elements.len())))
})
}
// The array cannot have more than `MAX_ARRAY_ELEMENTS` elements.