mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-28 12:45:26 +03:00
Reintroduce IntegerType
This commit is contained in:
parent
7ff7170c45
commit
dcbdb1bd85
@ -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::GroupLiteral;
|
||||
use crate::{GroupLiteral, IntegerType};
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -33,31 +33,13 @@ pub enum Literal {
|
||||
/// A group literal, either product or affine.
|
||||
/// For example, `42group` or `(12, 52)group`.
|
||||
Group(Box<GroupLiteral>),
|
||||
/// An integer literal, e.g., `42`.
|
||||
Integer(IntegerType, String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A scalar literal, e.g. `1scalar`.
|
||||
/// An unsigned number followed by the keyword `scalar`.
|
||||
Scalar(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A string literal, e.g., `"foobar"`.
|
||||
String(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// An 8-bit signed integer literal, e.g., `42i8`.
|
||||
I8(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 16-bit signed integer literal, e.g., `42i16`.
|
||||
I16(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 32-bit signed integer literal, e.g., `42i32`.
|
||||
I32(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 64-bit signed integer literal, e.g., `42i64`.
|
||||
I64(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 128-bit signed integer literal, e.g., `42i128`.
|
||||
I128(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 8-bit unsigned integer literal, e.g., `42u8`.
|
||||
U8(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 16-bit unsigned integer literal, e.g., `42u16`.
|
||||
U16(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 32-bit unsigned integer literal, e.g., `42u32`.
|
||||
U32(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 64-bit unsigned integer literal, e.g., `42u64`.
|
||||
U64(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A 128-bit unsigned integer literal, e.g., `42u128`.
|
||||
U128(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
}
|
||||
|
||||
impl fmt::Display for Literal {
|
||||
@ -65,20 +47,11 @@ impl fmt::Display for Literal {
|
||||
match &self {
|
||||
Self::Address(address, _) => write!(f, "{}", address),
|
||||
Self::Boolean(boolean, _) => write!(f, "{}", boolean),
|
||||
Self::I8(integer, _) => write!(f, "{}i8", integer),
|
||||
Self::I16(integer, _) => write!(f, "{}i16", integer),
|
||||
Self::I32(integer, _) => write!(f, "{}i32", integer),
|
||||
Self::I64(integer, _) => write!(f, "{}i64", integer),
|
||||
Self::I128(integer, _) => write!(f, "{}i128", integer),
|
||||
Self::Field(field, _) => write!(f, "{}field", field),
|
||||
Self::Group(group) => write!(f, "{}group", group),
|
||||
Self::Integer(type_, value, _) => write!(f, "{}{}", value, type_),
|
||||
Self::Scalar(scalar, _) => write!(f, "{}scalar", scalar),
|
||||
Self::String(string, _) => write!(f, "{}", string),
|
||||
Self::U8(integer, _) => write!(f, "{}u8", integer),
|
||||
Self::U16(integer, _) => write!(f, "{}u16", integer),
|
||||
Self::U32(integer, _) => write!(f, "{}u32", integer),
|
||||
Self::U64(integer, _) => write!(f, "{}u64", integer),
|
||||
Self::U128(integer, _) => write!(f, "{}u128", integer),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,18 +62,9 @@ impl Node for Literal {
|
||||
Self::Address(_, span)
|
||||
| Self::Boolean(_, span)
|
||||
| Self::Field(_, span)
|
||||
| Self::I8(_, span)
|
||||
| Self::I16(_, span)
|
||||
| Self::I32(_, span)
|
||||
| Self::I64(_, span)
|
||||
| Self::I128(_, span)
|
||||
| Self::Integer(_, _, span)
|
||||
| Self::Scalar(_, span)
|
||||
| Self::String(_, span)
|
||||
| Self::U8(_, span)
|
||||
| Self::U16(_, span)
|
||||
| Self::U32(_, span)
|
||||
| Self::U64(_, span)
|
||||
| Self::U128(_, span) => *span,
|
||||
| Self::String(_, span) => *span,
|
||||
Self::Group(group) => match &**group {
|
||||
GroupLiteral::Single(_, span) => *span,
|
||||
GroupLiteral::Tuple(tuple) => tuple.span,
|
||||
@ -113,18 +77,9 @@ impl Node for Literal {
|
||||
Self::Address(_, span)
|
||||
| Self::Boolean(_, span)
|
||||
| Self::Field(_, span)
|
||||
| Self::I8(_, span)
|
||||
| Self::I16(_, span)
|
||||
| Self::I32(_, span)
|
||||
| Self::I64(_, span)
|
||||
| Self::I128(_, span)
|
||||
| Self::Integer(_, _, span)
|
||||
| Self::Scalar(_, span)
|
||||
| Self::String(_, span)
|
||||
| Self::U8(_, span)
|
||||
| Self::U16(_, span)
|
||||
| Self::U32(_, span)
|
||||
| Self::U64(_, span)
|
||||
| Self::U128(_, span) => *span = new_span,
|
||||
| Self::String(_, span) => *span = new_span,
|
||||
Self::Group(group) => match &mut **group {
|
||||
GroupLiteral::Single(_, span) => *span = new_span,
|
||||
GroupLiteral::Tuple(tuple) => tuple.span = new_span,
|
||||
|
@ -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, GroupLiteral, Literal, Node, Type, UnaryOperation};
|
||||
use crate::{Expression, GroupLiteral, IntegerType, Literal, Node, Type, UnaryOperation};
|
||||
use leo_errors::{InputError, LeoError, Result};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -26,16 +26,7 @@ pub enum InputValue {
|
||||
Boolean(bool),
|
||||
Field(String),
|
||||
Group(GroupLiteral),
|
||||
I8(String),
|
||||
I16(String),
|
||||
I32(String),
|
||||
I64(String),
|
||||
I128(String),
|
||||
U8(String),
|
||||
U16(String),
|
||||
U32(String),
|
||||
U64(String),
|
||||
U128(String),
|
||||
Integer(IntegerType, String),
|
||||
}
|
||||
|
||||
impl TryFrom<(Type, Expression)> for InputValue {
|
||||
@ -47,16 +38,13 @@ impl TryFrom<(Type, Expression)> for InputValue {
|
||||
(Type::Boolean, Literal::Boolean(value, _)) => Self::Boolean(value),
|
||||
(Type::Field, Literal::Field(value, _)) => Self::Field(value),
|
||||
(Type::Group, Literal::Group(value)) => Self::Group(*value),
|
||||
(Type::I8, Literal::I8(value, _)) => Self::I8(value),
|
||||
(Type::I16, Literal::I16(value, _)) => Self::I16(value),
|
||||
(Type::I32, Literal::I32(value, _)) => Self::I32(value),
|
||||
(Type::I64, Literal::I64(value, _)) => Self::I64(value),
|
||||
(Type::I128, Literal::I128(value, _)) => Self::I128(value),
|
||||
(Type::U8, Literal::U8(value, _)) => Self::U8(value),
|
||||
(Type::U16, Literal::U16(value, _)) => Self::U16(value),
|
||||
(Type::U32, Literal::U32(value, _)) => Self::U32(value),
|
||||
(Type::U64, Literal::U64(value, _)) => Self::U64(value),
|
||||
(Type::U128, Literal::U128(value, _)) => Self::U128(value),
|
||||
(Type::Integer(expected), Literal::Integer(actual, value, span)) => {
|
||||
if expected == actual {
|
||||
Self::Integer(expected, value)
|
||||
} else {
|
||||
return Err(InputError::unexpected_type(expected.to_string(), actual, span).into());
|
||||
}
|
||||
}
|
||||
(x, y) => {
|
||||
return Err(InputError::unexpected_type(x, &y, y.span()).into());
|
||||
}
|
||||
@ -76,16 +64,7 @@ impl fmt::Display for InputValue {
|
||||
InputValue::Boolean(ref boolean) => write!(f, "{}", boolean),
|
||||
InputValue::Group(ref group) => write!(f, "{}", group),
|
||||
InputValue::Field(ref field) => write!(f, "{}", field),
|
||||
InputValue::I8(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::I16(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::I32(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::I64(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::I128(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::U8(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::U16(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::U32(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::U64(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::U128(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::Integer(ref type_, ref number) => write!(f, "{}{:?}", number, type_),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
78
compiler/ast/src/types/integer_type.rs
Normal file
78
compiler/ast/src/types/integer_type.rs
Normal file
@ -0,0 +1,78 @@
|
||||
// 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 leo_span::{sym, Symbol};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// Explicit integer type.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum IntegerType {
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
U128,
|
||||
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
I128,
|
||||
}
|
||||
|
||||
impl IntegerType {
|
||||
/// Is the integer type a signed one?
|
||||
pub fn is_signed(&self) -> bool {
|
||||
use IntegerType::*;
|
||||
matches!(self, I8 | I16 | I32 | I64 | I128)
|
||||
}
|
||||
|
||||
/// Returns the symbol for the integer type.
|
||||
pub fn symbol(self) -> Symbol {
|
||||
match self {
|
||||
Self::I8 => sym::i8,
|
||||
Self::I16 => sym::i16,
|
||||
Self::I32 => sym::i32,
|
||||
Self::I64 => sym::i64,
|
||||
Self::I128 => sym::i128,
|
||||
Self::U8 => sym::u8,
|
||||
Self::U16 => sym::u16,
|
||||
Self::U32 => sym::u32,
|
||||
Self::U64 => sym::u64,
|
||||
Self::U128 => sym::u128,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for IntegerType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
IntegerType::U8 => write!(f, "u8"),
|
||||
IntegerType::U16 => write!(f, "u16"),
|
||||
IntegerType::U32 => write!(f, "u32"),
|
||||
IntegerType::U64 => write!(f, "u64"),
|
||||
IntegerType::U128 => write!(f, "u128"),
|
||||
|
||||
IntegerType::I8 => write!(f, "i8"),
|
||||
IntegerType::I16 => write!(f, "i16"),
|
||||
IntegerType::I32 => write!(f, "i32"),
|
||||
IntegerType::I64 => write!(f, "i64"),
|
||||
IntegerType::I128 => write!(f, "i128"),
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod integer_type;
|
||||
pub use integer_type::*;
|
||||
|
||||
pub mod tuple;
|
||||
pub use tuple::*;
|
||||
|
||||
|
@ -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::{Identifier, Tuple};
|
||||
use crate::{Identifier, IntegerType, Tuple};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
@ -31,35 +31,16 @@ pub enum Type {
|
||||
Field,
|
||||
/// The `group` type.
|
||||
Group,
|
||||
/// The 8-bit signed integer type.
|
||||
I8,
|
||||
/// The 16-bit signed integer type.
|
||||
I16,
|
||||
/// The 32-bit signed integer type.
|
||||
I32,
|
||||
/// The 64-bit signed integer type.
|
||||
I64,
|
||||
/// The 128-bit signed integer type.
|
||||
I128,
|
||||
/// A reference to a built in type.
|
||||
Identifier(Identifier),
|
||||
/// An integer type.
|
||||
Integer(IntegerType),
|
||||
/// The `scalar` type.
|
||||
Scalar,
|
||||
/// The `string` type.
|
||||
String,
|
||||
/// The 8-bit unsigned integer type.
|
||||
U8,
|
||||
/// The 16-bit unsigned integer type.
|
||||
U16,
|
||||
/// The 32-bit unsigned integer type.
|
||||
U32,
|
||||
/// The 64-bit unsigned integer type.
|
||||
U64,
|
||||
/// The 128-bit unsigned integer type.
|
||||
U128,
|
||||
/// A static tuple of at least one type.
|
||||
Tuple(Tuple),
|
||||
|
||||
/// Placeholder for a type that could not be resolved or was not well-formed.
|
||||
/// Will eventually lead to a compile error.
|
||||
Err,
|
||||
@ -77,18 +58,9 @@ impl Type {
|
||||
| (Type::Boolean, Type::Boolean)
|
||||
| (Type::Field, Type::Field)
|
||||
| (Type::Group, Type::Group)
|
||||
| (Type::I8, Type::I8)
|
||||
| (Type::I16, Type::I16)
|
||||
| (Type::I32, Type::I32)
|
||||
| (Type::I64, Type::I64)
|
||||
| (Type::I128, Type::I128)
|
||||
| (Type::Scalar, Type::Scalar)
|
||||
| (Type::String, Type::String)
|
||||
| (Type::U8, Type::U8)
|
||||
| (Type::U16, Type::U16)
|
||||
| (Type::U32, Type::U32)
|
||||
| (Type::U64, Type::U64)
|
||||
| (Type::U128, Type::U128) => true,
|
||||
| (Type::String, Type::String) => true,
|
||||
(Type::Integer(left), Type::Integer(right)) => left.eq(right),
|
||||
(Type::Tuple(left), Type::Tuple(right)) => left
|
||||
.iter()
|
||||
.zip(right.iter())
|
||||
@ -106,19 +78,10 @@ impl fmt::Display for Type {
|
||||
Type::Boolean => write!(f, "boolean"),
|
||||
Type::Field => write!(f, "field"),
|
||||
Type::Group => write!(f, "group"),
|
||||
Type::I8 => write!(f, "i8"),
|
||||
Type::I16 => write!(f, "i16"),
|
||||
Type::I32 => write!(f, "i32"),
|
||||
Type::I64 => write!(f, "i64"),
|
||||
Type::I128 => write!(f, "i128"),
|
||||
Type::Identifier(ref variable) => write!(f, "circuit {}", variable),
|
||||
Type::Integer(ref integer_type) => write!(f, "{}", integer_type),
|
||||
Type::Scalar => write!(f, "scalar"),
|
||||
Type::String => write!(f, "string"),
|
||||
Type::U8 => write!(f, "u8"),
|
||||
Type::U16 => write!(f, "u16"),
|
||||
Type::U32 => write!(f, "u32"),
|
||||
Type::U64 => write!(f, "u64"),
|
||||
Type::U128 => write!(f, "u128"),
|
||||
Type::Tuple(ref tuple) => write!(f, "{}", tuple),
|
||||
Type::Err => write!(f, "error"),
|
||||
}
|
||||
|
@ -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::{GroupLiteral, Identifier, Literal, Type};
|
||||
use crate::{GroupLiteral, Identifier, IntegerType, Literal, Type};
|
||||
|
||||
use leo_errors::{type_name, FlattenError, LeoError, Result};
|
||||
use leo_span::{Span, Symbol};
|
||||
@ -848,16 +848,16 @@ impl From<&Value> for Type {
|
||||
Circuit(ident, _) => Type::Identifier(*ident),
|
||||
Field(_, _) => Type::Field,
|
||||
Group(_) => Type::Group,
|
||||
I8(_, _) => Type::I8,
|
||||
I16(_, _) => Type::I16,
|
||||
I32(_, _) => Type::I32,
|
||||
I64(_, _) => Type::I64,
|
||||
I128(_, _) => Type::I128,
|
||||
U8(_, _) => Type::U8,
|
||||
U16(_, _) => Type::U16,
|
||||
U32(_, _) => Type::U32,
|
||||
U64(_, _) => Type::U64,
|
||||
U128(_, _) => Type::U128,
|
||||
I8(_, _) => Type::Integer(IntegerType::I8),
|
||||
I16(_, _) => Type::Integer(IntegerType::I16),
|
||||
I32(_, _) => Type::Integer(IntegerType::I32),
|
||||
I64(_, _) => Type::Integer(IntegerType::I64),
|
||||
I128(_, _) => Type::Integer(IntegerType::I128),
|
||||
U8(_, _) => Type::Integer(IntegerType::U8),
|
||||
U16(_, _) => Type::Integer(IntegerType::U16),
|
||||
U32(_, _) => Type::Integer(IntegerType::U32),
|
||||
U64(_, _) => Type::Integer(IntegerType::U64),
|
||||
U128(_, _) => Type::Integer(IntegerType::U128),
|
||||
Scalar(_, _) => Type::Scalar,
|
||||
String(_, _) => Type::String,
|
||||
}
|
||||
@ -876,16 +876,18 @@ impl From<&Literal> for Value {
|
||||
Literal::Group(group_literal) => Self::Group(group_literal.clone()),
|
||||
Literal::Scalar(string, span) => Self::Scalar(string.clone(), *span),
|
||||
Literal::String(string, span) => Self::String(string.clone(), *span),
|
||||
Literal::I8(string, span) => Self::I8(string.parse::<i8>().unwrap(), *span),
|
||||
Literal::I16(string, span) => Self::I16(string.parse::<i16>().unwrap(), *span),
|
||||
Literal::I32(string, span) => Self::I32(string.parse::<i32>().unwrap(), *span),
|
||||
Literal::I64(string, span) => Self::I64(string.parse::<i64>().unwrap(), *span),
|
||||
Literal::I128(string, span) => Self::I128(string.parse::<i128>().unwrap(), *span),
|
||||
Literal::U8(string, span) => Self::U8(string.parse::<u8>().unwrap(), *span),
|
||||
Literal::U16(string, span) => Self::U16(string.parse::<u16>().unwrap(), *span),
|
||||
Literal::U32(string, span) => Self::U32(string.parse::<u32>().unwrap(), *span),
|
||||
Literal::U64(string, span) => Self::U64(string.parse::<u64>().unwrap(), *span),
|
||||
Literal::U128(string, span) => Self::U128(string.parse::<u128>().unwrap(), *span),
|
||||
Literal::Integer(integer_type, string, span) => match integer_type {
|
||||
IntegerType::U8 => Self::U8(string.parse().unwrap(), *span),
|
||||
IntegerType::U16 => Self::U16(string.parse().unwrap(), *span),
|
||||
IntegerType::U32 => Self::U32(string.parse().unwrap(), *span),
|
||||
IntegerType::U64 => Self::U64(string.parse().unwrap(), *span),
|
||||
IntegerType::U128 => Self::U128(string.parse().unwrap(), *span),
|
||||
IntegerType::I8 => Self::I8(string.parse().unwrap(), *span),
|
||||
IntegerType::I16 => Self::I16(string.parse().unwrap(), *span),
|
||||
IntegerType::I32 => Self::I32(string.parse().unwrap(), *span),
|
||||
IntegerType::I64 => Self::I64(string.parse().unwrap(), *span),
|
||||
IntegerType::I128 => Self::I128(string.parse().unwrap(), *span),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -900,16 +902,16 @@ impl From<Value> for Literal {
|
||||
Circuit(_ident, _values) => todo!("We need to test if this is hittable"),
|
||||
Field(v, span) => Literal::Field(v, span),
|
||||
Group(v) => Literal::Group(v),
|
||||
I8(v, span) => Literal::I8(v.to_string(), span),
|
||||
I16(v, span) => Literal::I16(v.to_string(), span),
|
||||
I32(v, span) => Literal::I32(v.to_string(), span),
|
||||
I64(v, span) => Literal::I64(v.to_string(), span),
|
||||
I128(v, span) => Literal::I128(v.to_string(), span),
|
||||
U8(v, span) => Literal::U8(v.to_string(), span),
|
||||
U16(v, span) => Literal::U16(v.to_string(), span),
|
||||
U32(v, span) => Literal::U32(v.to_string(), span),
|
||||
U64(v, span) => Literal::U64(v.to_string(), span),
|
||||
U128(v, span) => Literal::U128(v.to_string(), span),
|
||||
I8(v, span) => Literal::Integer(IntegerType::I8, v.to_string(), span),
|
||||
I16(v, span) => Literal::Integer(IntegerType::I16, v.to_string(), span),
|
||||
I32(v, span) => Literal::Integer(IntegerType::I32, v.to_string(), span),
|
||||
I64(v, span) => Literal::Integer(IntegerType::I64, v.to_string(), span),
|
||||
I128(v, span) => Literal::Integer(IntegerType::I128, v.to_string(), span),
|
||||
U8(v, span) => Literal::Integer(IntegerType::U8, v.to_string(), span),
|
||||
U16(v, span) => Literal::Integer(IntegerType::U16, v.to_string(), span),
|
||||
U32(v, span) => Literal::Integer(IntegerType::U32, v.to_string(), span),
|
||||
U64(v, span) => Literal::Integer(IntegerType::U64, v.to_string(), span),
|
||||
U128(v, span) => Literal::Integer(IntegerType::U128, v.to_string(), span),
|
||||
Scalar(v, span) => Literal::Scalar(v, span),
|
||||
String(v, span) => Literal::String(v, span),
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ pub use pedersen::*;
|
||||
mod poseidon;
|
||||
pub use poseidon::*;
|
||||
|
||||
use leo_ast::Type;
|
||||
use leo_ast::{IntegerType, Type};
|
||||
use leo_span::{sym, Symbol};
|
||||
|
||||
/// A core instruction that maps directly to an AVM bytecode instruction.
|
||||
@ -188,44 +188,44 @@ const ALL_TYPES: [Type; 16] = [
|
||||
Type::Boolean,
|
||||
Type::Field,
|
||||
Type::Group,
|
||||
Type::I8,
|
||||
Type::I16,
|
||||
Type::I32,
|
||||
Type::I64,
|
||||
Type::I128,
|
||||
Type::U8,
|
||||
Type::U16,
|
||||
Type::U32,
|
||||
Type::U64,
|
||||
Type::U128,
|
||||
Type::Integer(IntegerType::I8),
|
||||
Type::Integer(IntegerType::I16),
|
||||
Type::Integer(IntegerType::I32),
|
||||
Type::Integer(IntegerType::I64),
|
||||
Type::Integer(IntegerType::I128),
|
||||
Type::Integer(IntegerType::U8),
|
||||
Type::Integer(IntegerType::U16),
|
||||
Type::Integer(IntegerType::U32),
|
||||
Type::Integer(IntegerType::U64),
|
||||
Type::Integer(IntegerType::U128),
|
||||
Type::Scalar,
|
||||
Type::String,
|
||||
];
|
||||
|
||||
const BOOL_INT_STRING_TYPES: [Type; 12] = [
|
||||
Type::Boolean,
|
||||
Type::I8,
|
||||
Type::I16,
|
||||
Type::I32,
|
||||
Type::I64,
|
||||
Type::I128,
|
||||
Type::U8,
|
||||
Type::U16,
|
||||
Type::U32,
|
||||
Type::U64,
|
||||
Type::U128,
|
||||
Type::Integer(IntegerType::I8),
|
||||
Type::Integer(IntegerType::I16),
|
||||
Type::Integer(IntegerType::I32),
|
||||
Type::Integer(IntegerType::I64),
|
||||
Type::Integer(IntegerType::I128),
|
||||
Type::Integer(IntegerType::U8),
|
||||
Type::Integer(IntegerType::U16),
|
||||
Type::Integer(IntegerType::U32),
|
||||
Type::Integer(IntegerType::U64),
|
||||
Type::Integer(IntegerType::U128),
|
||||
Type::String,
|
||||
];
|
||||
|
||||
const BOOL_INT64_STRING_TYPES: [Type; 10] = [
|
||||
Type::Boolean,
|
||||
Type::I8,
|
||||
Type::I16,
|
||||
Type::I32,
|
||||
Type::I64,
|
||||
Type::U8,
|
||||
Type::U16,
|
||||
Type::U32,
|
||||
Type::U64,
|
||||
Type::Integer(IntegerType::I8),
|
||||
Type::Integer(IntegerType::I16),
|
||||
Type::Integer(IntegerType::I32),
|
||||
Type::Integer(IntegerType::I64),
|
||||
Type::Integer(IntegerType::U8),
|
||||
Type::Integer(IntegerType::U16),
|
||||
Type::Integer(IntegerType::U32),
|
||||
Type::Integer(IntegerType::U64),
|
||||
Type::String,
|
||||
];
|
||||
|
@ -260,22 +260,10 @@ impl ParserContext<'_> {
|
||||
// If the unary operation is a negate, and the inner expression is a signed integer literal,
|
||||
// then produce a negative integer literal.
|
||||
// This helps handle a special case where -128i8, treated as a unary expression, overflows, but -128i8, treated as an integer literal doesn't.
|
||||
Expression::Literal(Literal::I8(string, span)) if op == UnaryOperation::Negate && inner_is_integer => {
|
||||
Expression::Literal(Literal::I8(format!("-{}", string), op_span + span))
|
||||
}
|
||||
Expression::Literal(Literal::I16(string, span)) if op == UnaryOperation::Negate && inner_is_integer => {
|
||||
Expression::Literal(Literal::I16(format!("-{}", string), op_span + span))
|
||||
}
|
||||
Expression::Literal(Literal::I32(string, span)) if op == UnaryOperation::Negate && inner_is_integer => {
|
||||
Expression::Literal(Literal::I32(format!("-{}", string), op_span + span))
|
||||
}
|
||||
Expression::Literal(Literal::I64(string, span)) if op == UnaryOperation::Negate && inner_is_integer => {
|
||||
Expression::Literal(Literal::I64(format!("-{}", string), op_span + span))
|
||||
}
|
||||
Expression::Literal(Literal::I128(string, span))
|
||||
Expression::Literal(Literal::Integer(integer_type, string, span))
|
||||
if op == UnaryOperation::Negate && inner_is_integer =>
|
||||
{
|
||||
Expression::Literal(Literal::I128(format!("-{}", string), op_span + span))
|
||||
Expression::Literal(Literal::Integer(integer_type, format!("-{}", string), op_span + span))
|
||||
}
|
||||
// Otherwise, produce a unary expression.
|
||||
_ => Expression::Unary(UnaryExpression {
|
||||
@ -563,19 +551,8 @@ impl ParserContext<'_> {
|
||||
// Literal followed by other type suffix, e.g., `42u8`.
|
||||
Some(suffix) => {
|
||||
assert_no_whitespace(&suffix.to_string())?;
|
||||
match suffix {
|
||||
Token::I8 => Expression::Literal(Literal::I8(value, full_span)),
|
||||
Token::I16 => Expression::Literal(Literal::I16(value, full_span)),
|
||||
Token::I32 => Expression::Literal(Literal::I32(value, full_span)),
|
||||
Token::I64 => Expression::Literal(Literal::I64(value, full_span)),
|
||||
Token::I128 => Expression::Literal(Literal::I128(value, full_span)),
|
||||
Token::U8 => Expression::Literal(Literal::U8(value, full_span)),
|
||||
Token::U16 => Expression::Literal(Literal::U16(value, full_span)),
|
||||
Token::U32 => Expression::Literal(Literal::U32(value, full_span)),
|
||||
Token::U64 => Expression::Literal(Literal::U64(value, full_span)),
|
||||
Token::U128 => Expression::Literal(Literal::U128(value, full_span)),
|
||||
_ => return Err(ParserError::unexpected_token("Expected integer type suffix", span).into()),
|
||||
}
|
||||
let int_ty = Self::token_to_int_type(suffix).expect("unknown int type token");
|
||||
Expression::Literal(Literal::Integer(int_ty, value, full_span))
|
||||
}
|
||||
None => return Err(ParserError::implicit_values_not_allowed(value, span).into()),
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use super::*;
|
||||
|
||||
use leo_errors::{ParserError, Result};
|
||||
use leo_errors::Result;
|
||||
|
||||
pub(super) const TYPE_TOKENS: &[Token] = &[
|
||||
Token::Address,
|
||||
@ -38,29 +38,39 @@ pub(super) const TYPE_TOKENS: &[Token] = &[
|
||||
];
|
||||
|
||||
impl ParserContext<'_> {
|
||||
/// Returns a [`IntegerType`] AST node if the given token is a supported integer type, or [`None`].
|
||||
pub(super) fn token_to_int_type(token: &Token) -> Option<IntegerType> {
|
||||
Some(match token {
|
||||
Token::I8 => IntegerType::I8,
|
||||
Token::I16 => IntegerType::I16,
|
||||
Token::I32 => IntegerType::I32,
|
||||
Token::I64 => IntegerType::I64,
|
||||
Token::I128 => IntegerType::I128,
|
||||
Token::U8 => IntegerType::U8,
|
||||
Token::U16 => IntegerType::U16,
|
||||
Token::U32 => IntegerType::U32,
|
||||
Token::U64 => IntegerType::U64,
|
||||
Token::U128 => IntegerType::U128,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a primitive type.
|
||||
/// Also returns the span of the parsed token.
|
||||
pub fn parse_primitive_type(&mut self) -> Result<(Type, Span)> {
|
||||
let span = self.expect_any(TYPE_TOKENS)?;
|
||||
match &self.prev_token.token {
|
||||
Token::Address => Ok((Type::Address, span)),
|
||||
Token::Bool => Ok((Type::Boolean, span)),
|
||||
Token::Field => Ok((Type::Field, span)),
|
||||
Token::Group => Ok((Type::Group, span)),
|
||||
Token::I8 => Ok((Type::I8, span)),
|
||||
Token::I16 => Ok((Type::I16, span)),
|
||||
Token::I32 => Ok((Type::I32, span)),
|
||||
Token::I64 => Ok((Type::I64, span)),
|
||||
Token::I128 => Ok((Type::I128, span)),
|
||||
Token::Scalar => Ok((Type::Scalar, span)),
|
||||
Token::String => Ok((Type::String, span)),
|
||||
Token::U8 => Ok((Type::U8, span)),
|
||||
Token::U16 => Ok((Type::U16, span)),
|
||||
Token::U32 => Ok((Type::U32, span)),
|
||||
Token::U64 => Ok((Type::U64, span)),
|
||||
Token::U128 => Ok((Type::U128, span)),
|
||||
_ => Err(ParserError::unexpected_token("Expected a primitive type.", span).into()),
|
||||
}
|
||||
Ok((
|
||||
match &self.prev_token.token {
|
||||
Token::Address => Type::Address,
|
||||
Token::Bool => Type::Boolean,
|
||||
Token::Field => Type::Field,
|
||||
Token::Group => Type::Group,
|
||||
Token::Scalar => Type::Scalar,
|
||||
Token::String => Type::String,
|
||||
x => Type::Integer(Self::token_to_int_type(x).expect("invalid int type")),
|
||||
},
|
||||
span,
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type.
|
||||
|
@ -28,16 +28,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
| Type::Group
|
||||
| Type::Scalar
|
||||
| Type::String
|
||||
| Type::I8
|
||||
| Type::I16
|
||||
| Type::I32
|
||||
| Type::I64
|
||||
| Type::I128
|
||||
| Type::U8
|
||||
| Type::U16
|
||||
| Type::U32
|
||||
| Type::U64
|
||||
| Type::U128 => format!("{}", input),
|
||||
| Type::Integer(..) => format!("{}", input),
|
||||
Type::Identifier(ident) => {
|
||||
if let Some((_, type_)) = self.composite_mapping.get(&ident.name) {
|
||||
format!("{}.{}", ident.to_string().to_lowercase(), type_)
|
||||
|
@ -51,16 +51,20 @@ impl StatementReconstructor for Unroller<'_> {
|
||||
input.stop_value.clone().into_inner(),
|
||||
) {
|
||||
(Some(start), Some(stop)) => match (Type::from(&start), Type::from(&stop)) {
|
||||
(Type::I8, Type::I8)
|
||||
| (Type::I16, Type::I16)
|
||||
| (Type::I32, Type::I32)
|
||||
| (Type::I64, Type::I64)
|
||||
| (Type::I128, Type::I128) => self.unroll_iteration_statement::<i128>(input, start, stop),
|
||||
(Type::U8, Type::U8)
|
||||
| (Type::U16, Type::U16)
|
||||
| (Type::U32, Type::U32)
|
||||
| (Type::U64, Type::U64)
|
||||
| (Type::U128, Type::U128) => self.unroll_iteration_statement::<u128>(input, start, stop),
|
||||
(Type::Integer(IntegerType::I8), Type::Integer(IntegerType::I8))
|
||||
| (Type::Integer(IntegerType::I16), Type::Integer(IntegerType::I16))
|
||||
| (Type::Integer(IntegerType::I32), Type::Integer(IntegerType::I32))
|
||||
| (Type::Integer(IntegerType::I64), Type::Integer(IntegerType::I64))
|
||||
| (Type::Integer(IntegerType::I128), Type::Integer(IntegerType::I128)) => {
|
||||
self.unroll_iteration_statement::<i128>(input, start, stop)
|
||||
}
|
||||
(Type::Integer(IntegerType::U8), Type::Integer(IntegerType::U8))
|
||||
| (Type::Integer(IntegerType::U16), Type::Integer(IntegerType::U16))
|
||||
| (Type::Integer(IntegerType::U32), Type::Integer(IntegerType::U32))
|
||||
| (Type::Integer(IntegerType::U64), Type::Integer(IntegerType::U64))
|
||||
| (Type::Integer(IntegerType::U128), Type::Integer(IntegerType::U128)) => {
|
||||
self.unroll_iteration_statement::<u128>(input, start, stop)
|
||||
}
|
||||
_ => unreachable!("Type checking ensures that `start` and `stop` have the same type."),
|
||||
},
|
||||
// If both loop bounds are not constant, then the loop is not unrolled.
|
||||
|
@ -15,7 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_ast::{
|
||||
Block, DeclarationType, DefinitionStatement, Expression, IterationStatement, Literal, Statement,
|
||||
Block, DeclarationType, DefinitionStatement, Expression, IntegerType, IterationStatement, Literal, Statement,
|
||||
StatementReconstructor, Type, Value,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
@ -149,16 +149,36 @@ impl<'a> Unroller<'a> {
|
||||
|
||||
// Reconstruct `iteration_count` as a `Literal`.
|
||||
let value = match input.type_ {
|
||||
Type::I8 => Literal::I8(iteration_count.to_string(), Default::default()),
|
||||
Type::I16 => Literal::I16(iteration_count.to_string(), Default::default()),
|
||||
Type::I32 => Literal::I32(iteration_count.to_string(), Default::default()),
|
||||
Type::I64 => Literal::I64(iteration_count.to_string(), Default::default()),
|
||||
Type::I128 => Literal::I128(iteration_count.to_string(), Default::default()),
|
||||
Type::U8 => Literal::U8(iteration_count.to_string(), Default::default()),
|
||||
Type::U16 => Literal::U16(iteration_count.to_string(), Default::default()),
|
||||
Type::U32 => Literal::U32(iteration_count.to_string(), Default::default()),
|
||||
Type::U64 => Literal::U64(iteration_count.to_string(), Default::default()),
|
||||
Type::U128 => Literal::U128(iteration_count.to_string(), Default::default()),
|
||||
Type::Integer(IntegerType::I8) => {
|
||||
Literal::Integer(IntegerType::I8, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I16) => {
|
||||
Literal::Integer(IntegerType::I16, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I32) => {
|
||||
Literal::Integer(IntegerType::I32, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I64) => {
|
||||
Literal::Integer(IntegerType::I64, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::I128) => {
|
||||
Literal::Integer(IntegerType::I128, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U8) => {
|
||||
Literal::Integer(IntegerType::U8, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U16) => {
|
||||
Literal::Integer(IntegerType::U16, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U32) => {
|
||||
Literal::Integer(IntegerType::U32, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U64) => {
|
||||
Literal::Integer(IntegerType::U64, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
Type::Integer(IntegerType::U128) => {
|
||||
Literal::Integer(IntegerType::U128, iteration_count.to_string(), Default::default())
|
||||
}
|
||||
_ => unreachable!(
|
||||
"The iteration variable must be an integer type. This should be enforced by type checking."
|
||||
),
|
||||
|
@ -480,46 +480,48 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
Literal::Address(_, _) => self.assert_and_return_type(Type::Address, expected, input.span()),
|
||||
Literal::Boolean(_, _) => self.assert_and_return_type(Type::Boolean, expected, input.span()),
|
||||
Literal::Field(_, _) => self.assert_and_return_type(Type::Field, expected, input.span()),
|
||||
Literal::I8(string, _) => {
|
||||
parse_integer_literal::<i8>(self.handler, string, input.span(), "i8");
|
||||
self.assert_and_return_type(Type::I8, expected, input.span())
|
||||
}
|
||||
Literal::I16(string, _) => {
|
||||
parse_integer_literal::<i16>(self.handler, string, input.span(), "i16");
|
||||
self.assert_and_return_type(Type::I16, expected, input.span())
|
||||
}
|
||||
Literal::I32(string, _) => {
|
||||
parse_integer_literal::<i32>(self.handler, string, input.span(), "i32");
|
||||
self.assert_and_return_type(Type::I32, expected, input.span())
|
||||
}
|
||||
Literal::I64(string, _) => {
|
||||
parse_integer_literal::<i64>(self.handler, string, input.span(), "i64");
|
||||
self.assert_and_return_type(Type::I64, expected, input.span())
|
||||
}
|
||||
Literal::I128(string, _) => {
|
||||
parse_integer_literal::<i128>(self.handler, string, input.span(), "i128");
|
||||
self.assert_and_return_type(Type::I128, expected, input.span())
|
||||
}
|
||||
Literal::U8(string, _) => {
|
||||
parse_integer_literal::<u8>(self.handler, string, input.span(), "u8");
|
||||
self.assert_and_return_type(Type::U8, expected, input.span())
|
||||
}
|
||||
Literal::U16(string, _) => {
|
||||
parse_integer_literal::<u16>(self.handler, string, input.span(), "u16");
|
||||
self.assert_and_return_type(Type::U16, expected, input.span())
|
||||
}
|
||||
Literal::U32(string, _) => {
|
||||
parse_integer_literal::<u32>(self.handler, string, input.span(), "u32");
|
||||
self.assert_and_return_type(Type::U32, expected, input.span())
|
||||
}
|
||||
Literal::U64(string, _) => {
|
||||
parse_integer_literal::<u64>(self.handler, string, input.span(), "u64");
|
||||
self.assert_and_return_type(Type::U64, expected, input.span())
|
||||
}
|
||||
Literal::U128(string, _) => {
|
||||
parse_integer_literal::<u128>(self.handler, string, input.span(), "u128");
|
||||
self.assert_and_return_type(Type::U128, expected, input.span())
|
||||
}
|
||||
Literal::Integer(integer_type, string, _) => match integer_type {
|
||||
IntegerType::U8 => {
|
||||
parse_integer_literal::<u8>(self.handler, string, input.span(), "u8");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::U8), expected, input.span())
|
||||
}
|
||||
IntegerType::U16 => {
|
||||
parse_integer_literal::<u16>(self.handler, string, input.span(), "u16");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::U16), expected, input.span())
|
||||
}
|
||||
IntegerType::U32 => {
|
||||
parse_integer_literal::<u32>(self.handler, string, input.span(), "u32");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::U32), expected, input.span())
|
||||
}
|
||||
IntegerType::U64 => {
|
||||
parse_integer_literal::<u64>(self.handler, string, input.span(), "u64");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::U64), expected, input.span())
|
||||
}
|
||||
IntegerType::U128 => {
|
||||
parse_integer_literal::<u128>(self.handler, string, input.span(), "u128");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::U128), expected, input.span())
|
||||
}
|
||||
IntegerType::I8 => {
|
||||
parse_integer_literal::<i8>(self.handler, string, input.span(), "i8");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::I8), expected, input.span())
|
||||
}
|
||||
IntegerType::I16 => {
|
||||
parse_integer_literal::<i16>(self.handler, string, input.span(), "i16");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::I16), expected, input.span())
|
||||
}
|
||||
IntegerType::I32 => {
|
||||
parse_integer_literal::<i32>(self.handler, string, input.span(), "i32");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::I32), expected, input.span())
|
||||
}
|
||||
IntegerType::I64 => {
|
||||
parse_integer_literal::<i64>(self.handler, string, input.span(), "i64");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::I64), expected, input.span())
|
||||
}
|
||||
IntegerType::I128 => {
|
||||
parse_integer_literal::<i128>(self.handler, string, input.span(), "i128");
|
||||
self.assert_and_return_type(Type::Integer(IntegerType::I128), expected, input.span())
|
||||
}
|
||||
},
|
||||
Literal::Group(_) => self.assert_and_return_type(Type::Group, expected, input.span()),
|
||||
Literal::Scalar(_, _) => self.assert_and_return_type(Type::Scalar, expected, input.span()),
|
||||
Literal::String(_, _) => self.assert_and_return_type(Type::String, expected, input.span()),
|
||||
|
@ -120,7 +120,7 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
}
|
||||
};
|
||||
check_has_field(sym::owner, Type::Address);
|
||||
check_has_field(sym::gates, Type::U64);
|
||||
check_has_field(sym::gates, Type::Integer(IntegerType::U64));
|
||||
}
|
||||
|
||||
// Ensure there are no tuple typed members.
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::SymbolTable;
|
||||
|
||||
use leo_ast::{Identifier, Node, Type};
|
||||
use leo_ast::{Identifier, IntegerType, Node, Type};
|
||||
use leo_core::*;
|
||||
use leo_errors::{emitter::Handler, TypeCheckerError};
|
||||
use leo_span::{Span, Symbol};
|
||||
@ -43,23 +43,39 @@ const GROUP_TYPE: Type = Type::Group;
|
||||
const SCALAR_TYPE: Type = Type::Scalar;
|
||||
|
||||
const INT_TYPES: [Type; 10] = [
|
||||
Type::I8,
|
||||
Type::I16,
|
||||
Type::I32,
|
||||
Type::I64,
|
||||
Type::I128,
|
||||
Type::U8,
|
||||
Type::U16,
|
||||
Type::U32,
|
||||
Type::U64,
|
||||
Type::U128,
|
||||
Type::Integer(IntegerType::I8),
|
||||
Type::Integer(IntegerType::I16),
|
||||
Type::Integer(IntegerType::I32),
|
||||
Type::Integer(IntegerType::I64),
|
||||
Type::Integer(IntegerType::I128),
|
||||
Type::Integer(IntegerType::U8),
|
||||
Type::Integer(IntegerType::U16),
|
||||
Type::Integer(IntegerType::U32),
|
||||
Type::Integer(IntegerType::U64),
|
||||
Type::Integer(IntegerType::U128),
|
||||
];
|
||||
|
||||
const SIGNED_INT_TYPES: [Type; 5] = [Type::I8, Type::I16, Type::I32, Type::I64, Type::I128];
|
||||
const SIGNED_INT_TYPES: [Type; 5] = [
|
||||
Type::Integer(IntegerType::I8),
|
||||
Type::Integer(IntegerType::I16),
|
||||
Type::Integer(IntegerType::I32),
|
||||
Type::Integer(IntegerType::I64),
|
||||
Type::Integer(IntegerType::I128),
|
||||
];
|
||||
|
||||
const UNSIGNED_INT_TYPES: [Type; 5] = [Type::U8, Type::U16, Type::U32, Type::U64, Type::U128];
|
||||
const UNSIGNED_INT_TYPES: [Type; 5] = [
|
||||
Type::Integer(IntegerType::U8),
|
||||
Type::Integer(IntegerType::U16),
|
||||
Type::Integer(IntegerType::U32),
|
||||
Type::Integer(IntegerType::U64),
|
||||
Type::Integer(IntegerType::U128),
|
||||
];
|
||||
|
||||
const MAGNITUDE_TYPES: [Type; 3] = [Type::U8, Type::U16, Type::U32];
|
||||
const MAGNITUDE_TYPES: [Type; 3] = [
|
||||
Type::Integer(IntegerType::U8),
|
||||
Type::Integer(IntegerType::U16),
|
||||
Type::Integer(IntegerType::U32),
|
||||
];
|
||||
|
||||
impl<'a> TypeChecker<'a> {
|
||||
/// Returns a new type checker given a symbol table and error handler.
|
||||
|
Loading…
Reference in New Issue
Block a user