mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 10:12:21 +03:00
regenerate readme after pulling upstream
This commit is contained in:
commit
c9612625d1
3
.gitignore
vendored
3
.gitignore
vendored
@ -18,3 +18,6 @@ sccache*/
|
|||||||
*~
|
*~
|
||||||
\#*\#
|
\#*\#
|
||||||
.\#*
|
.\#*
|
||||||
|
|
||||||
|
# code coverage scripts
|
||||||
|
*.bat
|
@ -21,20 +21,23 @@ use crate::{Char, CharValue};
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum ValueExpression {
|
pub enum ValueExpression {
|
||||||
// todo: deserialize values here
|
// todo: deserialize values here
|
||||||
/// An address literal, e.g., `aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8`.
|
/// An address literal, e.g., `aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8s7pyjh9`.
|
||||||
Address(String, #[serde(with = "leo_span::span_json")] Span),
|
Address(String, #[serde(with = "leo_span::span_json")] Span),
|
||||||
/// A boolean literal, either `true` or `false`.
|
/// A boolean literal, either `true` or `false`.
|
||||||
Boolean(String, #[serde(with = "leo_span::span_json")] Span),
|
Boolean(String, #[serde(with = "leo_span::span_json")] Span),
|
||||||
/// A char literal, e.g., `'a'`, representing a single unicode code point.
|
/// A char literal, e.g., `'a'`, representing a single unicode code point.
|
||||||
Char(CharValue),
|
Char(CharValue),
|
||||||
/// A field literal, e.g., `42field`.
|
/// A field literal, e.g., `42field`.
|
||||||
/// That is, a signed number followed by the keyword `field`.
|
/// A signed number followed by the keyword `field`.
|
||||||
Field(String, #[serde(with = "leo_span::span_json")] Span),
|
Field(String, #[serde(with = "leo_span::span_json")] Span),
|
||||||
/// A group literal, either product or affine.
|
/// A group literal, either product or affine.
|
||||||
/// For example, `42group` or `(12, 52)group`.
|
/// For example, `42group` or `(12, 52)group`.
|
||||||
Group(Box<GroupValue>),
|
Group(Box<GroupValue>),
|
||||||
/// An integer literal, e.g., `42`.
|
/// An integer literal, e.g., `42`.
|
||||||
Integer(IntegerType, String, #[serde(with = "leo_span::span_json")] Span),
|
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"`.
|
/// A string literal, e.g., `"foobar"`.
|
||||||
String(Vec<Char>, #[serde(with = "leo_span::span_json")] Span),
|
String(Vec<Char>, #[serde(with = "leo_span::span_json")] Span),
|
||||||
}
|
}
|
||||||
@ -47,8 +50,9 @@ impl fmt::Display for ValueExpression {
|
|||||||
Boolean(boolean, _) => write!(f, "{}", boolean),
|
Boolean(boolean, _) => write!(f, "{}", boolean),
|
||||||
Char(character) => write!(f, "{}", character),
|
Char(character) => write!(f, "{}", character),
|
||||||
Field(field, _) => write!(f, "{}", field),
|
Field(field, _) => write!(f, "{}", field),
|
||||||
Integer(type_, value, _) => write!(f, "{}{}", value, type_),
|
|
||||||
Group(group) => write!(f, "{}", group),
|
Group(group) => write!(f, "{}", group),
|
||||||
|
Integer(type_, value, _) => write!(f, "{}{}", value, type_),
|
||||||
|
Scalar(scalar, _) => write!(f, "{}", scalar),
|
||||||
String(string, _) => {
|
String(string, _) => {
|
||||||
for character in string.iter() {
|
for character in string.iter() {
|
||||||
write!(f, "{}", character)?;
|
write!(f, "{}", character)?;
|
||||||
@ -63,7 +67,12 @@ impl Node for ValueExpression {
|
|||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
use ValueExpression::*;
|
use ValueExpression::*;
|
||||||
match &self {
|
match &self {
|
||||||
Address(_, span) | Boolean(_, span) | Field(_, span) | Integer(_, _, span) | String(_, span) => *span,
|
Address(_, span)
|
||||||
|
| Boolean(_, span)
|
||||||
|
| Field(_, span)
|
||||||
|
| Integer(_, _, span)
|
||||||
|
| Scalar(_, span)
|
||||||
|
| String(_, span) => *span,
|
||||||
Char(character) => character.span,
|
Char(character) => character.span,
|
||||||
Group(group) => match &**group {
|
Group(group) => match &**group {
|
||||||
GroupValue::Single(_, span) => *span,
|
GroupValue::Single(_, span) => *span,
|
||||||
@ -75,9 +84,12 @@ impl Node for ValueExpression {
|
|||||||
fn set_span(&mut self, new_span: Span) {
|
fn set_span(&mut self, new_span: Span) {
|
||||||
use ValueExpression::*;
|
use ValueExpression::*;
|
||||||
match self {
|
match self {
|
||||||
Address(_, span) | Boolean(_, span) | Field(_, span) | Integer(_, _, span) | String(_, span) => {
|
Address(_, span)
|
||||||
*span = new_span
|
| Boolean(_, span)
|
||||||
}
|
| Field(_, span)
|
||||||
|
| Integer(_, _, span)
|
||||||
|
| Scalar(_, span)
|
||||||
|
| String(_, span) => *span = new_span,
|
||||||
Char(character) => character.span = new_span,
|
Char(character) => character.span = new_span,
|
||||||
Group(group) => match &mut **group {
|
Group(group) => match &mut **group {
|
||||||
GroupValue::Single(_, span) => *span = new_span,
|
GroupValue::Single(_, span) => *span = new_span,
|
||||||
|
@ -34,7 +34,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn reduce_type(&mut self, type_: &Type, span: &Span) -> Result<Type> {
|
pub fn reduce_type(&mut self, type_: &Type, span: &Span) -> Result<Type> {
|
||||||
self.reducer.reduce_type(type_, type_.clone(), span)
|
self.reducer.reduce_type(type_, *type_, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
|
@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// Explicit type used for defining a variable or expression type
|
/// Explicit type used for defining a variable or expression type
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
// Data types
|
// Data types
|
||||||
/// The `address` type.
|
/// The `address` type.
|
||||||
@ -33,6 +33,8 @@ pub enum Type {
|
|||||||
Field,
|
Field,
|
||||||
/// The `group` type.
|
/// The `group` type.
|
||||||
Group,
|
Group,
|
||||||
|
/// The `scalar` type.
|
||||||
|
Scalar,
|
||||||
/// An integer type.
|
/// An integer type.
|
||||||
IntegerType(IntegerType),
|
IntegerType(IntegerType),
|
||||||
|
|
||||||
@ -49,11 +51,12 @@ impl Type {
|
|||||||
///
|
///
|
||||||
pub fn eq_flat(&self, other: &Self) -> bool {
|
pub fn eq_flat(&self, other: &Self) -> bool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Type::Address, Type::Address) => true,
|
(Type::Address, Type::Address)
|
||||||
(Type::Boolean, Type::Boolean) => true,
|
| (Type::Boolean, Type::Boolean)
|
||||||
(Type::Char, Type::Char) => true,
|
| (Type::Char, Type::Char)
|
||||||
(Type::Field, Type::Field) => true,
|
| (Type::Field, Type::Field)
|
||||||
(Type::Group, Type::Group) => true,
|
| (Type::Group, Type::Group)
|
||||||
|
| (Type::Scalar, Type::Scalar) => true,
|
||||||
(Type::IntegerType(left), Type::IntegerType(right)) => left.eq(right),
|
(Type::IntegerType(left), Type::IntegerType(right)) => left.eq(right),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -65,9 +68,10 @@ impl fmt::Display for Type {
|
|||||||
match *self {
|
match *self {
|
||||||
Type::Address => write!(f, "address"),
|
Type::Address => write!(f, "address"),
|
||||||
Type::Boolean => write!(f, "bool"),
|
Type::Boolean => write!(f, "bool"),
|
||||||
Type::Char => write!(f, "char"),
|
|
||||||
Type::Field => write!(f, "field"),
|
Type::Field => write!(f, "field"),
|
||||||
Type::Group => write!(f, "group"),
|
Type::Group => write!(f, "group"),
|
||||||
|
Type::Char => write!(f, "char"),
|
||||||
|
Type::Scalar => write!(f, "scalar"),
|
||||||
Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type),
|
Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type),
|
||||||
Type::Err => write!(f, "error"),
|
Type::Err => write!(f, "error"),
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ const INT_TYPES: &[Token] = &[
|
|||||||
Token::U128,
|
Token::U128,
|
||||||
Token::Field,
|
Token::Field,
|
||||||
Token::Group,
|
Token::Group,
|
||||||
|
Token::Scalar,
|
||||||
];
|
];
|
||||||
|
|
||||||
impl ParserContext<'_> {
|
impl ParserContext<'_> {
|
||||||
@ -164,7 +165,7 @@ impl ParserContext<'_> {
|
|||||||
/// Returns an [`Expression`] AST node if the next tokens represent a
|
/// Returns an [`Expression`] AST node if the next tokens represent a
|
||||||
/// binary addition or subtraction expression.
|
/// binary addition or subtraction expression.
|
||||||
///
|
///
|
||||||
/// Otherwise, tries to parse the next token using [`parse_mul_div_pow_expression`].
|
/// Otherwise, tries to parse the next token using [`parse_multiplicative_expression`].
|
||||||
pub fn parse_additive_expression(&mut self) -> Result<Expression> {
|
pub fn parse_additive_expression(&mut self) -> Result<Expression> {
|
||||||
self.parse_bin_expr(&[Token::Add, Token::Minus], Self::parse_multiplicative_expression)
|
self.parse_bin_expr(&[Token::Add, Token::Minus], Self::parse_multiplicative_expression)
|
||||||
}
|
}
|
||||||
@ -295,6 +296,11 @@ impl ParserContext<'_> {
|
|||||||
assert_no_whitespace("group")?;
|
assert_no_whitespace("group")?;
|
||||||
Expression::Value(ValueExpression::Group(Box::new(GroupValue::Single(value, full_span))))
|
Expression::Value(ValueExpression::Group(Box::new(GroupValue::Single(value, full_span))))
|
||||||
}
|
}
|
||||||
|
// Literal followed by `scalar` e.g., `42scalar`.
|
||||||
|
Some(Token::Scalar) => {
|
||||||
|
assert_no_whitespace("scalar")?;
|
||||||
|
Expression::Value(ValueExpression::Scalar(value, full_span))
|
||||||
|
}
|
||||||
// Literal followed by other type suffix, e.g., `42u8`.
|
// Literal followed by other type suffix, e.g., `42u8`.
|
||||||
Some(suffix) => {
|
Some(suffix) => {
|
||||||
assert_no_whitespace(&suffix.to_string())?;
|
assert_no_whitespace(&suffix.to_string())?;
|
||||||
|
@ -18,6 +18,10 @@ use super::*;
|
|||||||
use leo_errors::Result;
|
use leo_errors::Result;
|
||||||
|
|
||||||
pub(crate) const TYPE_TOKENS: &[Token] = &[
|
pub(crate) const TYPE_TOKENS: &[Token] = &[
|
||||||
|
Token::Address,
|
||||||
|
Token::Bool,
|
||||||
|
Token::Field,
|
||||||
|
Token::Group,
|
||||||
Token::I8,
|
Token::I8,
|
||||||
Token::I16,
|
Token::I16,
|
||||||
Token::I32,
|
Token::I32,
|
||||||
@ -28,11 +32,8 @@ pub(crate) const TYPE_TOKENS: &[Token] = &[
|
|||||||
Token::U32,
|
Token::U32,
|
||||||
Token::U64,
|
Token::U64,
|
||||||
Token::U128,
|
Token::U128,
|
||||||
Token::Field,
|
|
||||||
Token::Group,
|
|
||||||
Token::Address,
|
|
||||||
Token::Bool,
|
|
||||||
Token::Char,
|
Token::Char,
|
||||||
|
Token::Scalar,
|
||||||
];
|
];
|
||||||
|
|
||||||
impl ParserContext<'_> {
|
impl ParserContext<'_> {
|
||||||
@ -59,11 +60,12 @@ impl ParserContext<'_> {
|
|||||||
let span = self.expect_any(TYPE_TOKENS)?;
|
let span = self.expect_any(TYPE_TOKENS)?;
|
||||||
Ok((
|
Ok((
|
||||||
match &self.prev_token.token {
|
match &self.prev_token.token {
|
||||||
Token::Field => Type::Field,
|
|
||||||
Token::Group => Type::Group,
|
|
||||||
Token::Address => Type::Address,
|
Token::Address => Type::Address,
|
||||||
Token::Bool => Type::Boolean,
|
Token::Bool => Type::Boolean,
|
||||||
|
Token::Field => Type::Field,
|
||||||
|
Token::Group => Type::Group,
|
||||||
Token::Char => Type::Char,
|
Token::Char => Type::Char,
|
||||||
|
Token::Scalar => Type::Scalar,
|
||||||
x => Type::IntegerType(Self::token_to_int_type(x).expect("invalid int type")),
|
x => Type::IntegerType(Self::token_to_int_type(x).expect("invalid int type")),
|
||||||
},
|
},
|
||||||
span,
|
span,
|
||||||
|
@ -423,6 +423,7 @@ impl Token {
|
|||||||
"let" => Token::Let,
|
"let" => Token::Let,
|
||||||
"public" => Token::Public,
|
"public" => Token::Public,
|
||||||
"return" => Token::Return,
|
"return" => Token::Return,
|
||||||
|
"scalar" => Token::Scalar,
|
||||||
"true" => Token::True,
|
"true" => Token::True,
|
||||||
"u8" => Token::U8,
|
"u8" => Token::U8,
|
||||||
"u16" => Token::U16,
|
"u16" => Token::U16,
|
||||||
|
@ -111,6 +111,7 @@ mod tests {
|
|||||||
let
|
let
|
||||||
mut
|
mut
|
||||||
return
|
return
|
||||||
|
scalar
|
||||||
string
|
string
|
||||||
test
|
test
|
||||||
true
|
true
|
||||||
@ -161,7 +162,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
output,
|
output,
|
||||||
r#"'a' '😭' "test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8 test_ident 12345 address bool const else false field for function group i128 i64 i32 i16 i8 if in input let mut return string test true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> _ . .. / : ; < <= = == > >= [ ] { { } } || ? // test
|
r#"'a' '😭' "test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8 test_ident 12345 address bool const else false field for function group i128 i64 i32 i16 i8 if in input let mut return scalar string test true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> _ . .. / : ; < <= = == > >= [ ] { { } } || ? // test
|
||||||
/* test */ // "#
|
/* test */ // "#
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -91,23 +91,24 @@ pub enum Token {
|
|||||||
Arrow,
|
Arrow,
|
||||||
Underscore,
|
Underscore,
|
||||||
|
|
||||||
// Syntactic Grammr
|
// Syntactic Grammar
|
||||||
// Types
|
// Types
|
||||||
U8,
|
|
||||||
U16,
|
|
||||||
U32,
|
|
||||||
U64,
|
|
||||||
U128,
|
|
||||||
I8,
|
I8,
|
||||||
I16,
|
I16,
|
||||||
I32,
|
I32,
|
||||||
I64,
|
I64,
|
||||||
I128,
|
I128,
|
||||||
|
Address,
|
||||||
|
Bool,
|
||||||
Field,
|
Field,
|
||||||
Group,
|
Group,
|
||||||
Bool,
|
U8,
|
||||||
Address,
|
U16,
|
||||||
|
U32,
|
||||||
|
U64,
|
||||||
|
U128,
|
||||||
Char,
|
Char,
|
||||||
|
Scalar,
|
||||||
|
|
||||||
// Regular Keywords
|
// Regular Keywords
|
||||||
Console,
|
Console,
|
||||||
@ -152,6 +153,7 @@ pub const KEYWORD_TOKENS: &[Token] = &[
|
|||||||
Token::Let,
|
Token::Let,
|
||||||
Token::Public,
|
Token::Public,
|
||||||
Token::Return,
|
Token::Return,
|
||||||
|
Token::Scalar,
|
||||||
Token::True,
|
Token::True,
|
||||||
Token::U8,
|
Token::U8,
|
||||||
Token::U16,
|
Token::U16,
|
||||||
@ -191,6 +193,7 @@ impl Token {
|
|||||||
Token::Let => sym::Let,
|
Token::Let => sym::Let,
|
||||||
Token::Public => sym::Public,
|
Token::Public => sym::Public,
|
||||||
Token::Return => sym::Return,
|
Token::Return => sym::Return,
|
||||||
|
Token::Scalar => sym::scalar,
|
||||||
Token::True => sym::True,
|
Token::True => sym::True,
|
||||||
Token::U8 => sym::u8,
|
Token::U8 => sym::u8,
|
||||||
Token::U16 => sym::u16,
|
Token::U16 => sym::u16,
|
||||||
@ -253,21 +256,22 @@ impl fmt::Display for Token {
|
|||||||
Arrow => write!(f, "->"),
|
Arrow => write!(f, "->"),
|
||||||
Underscore => write!(f, "_"),
|
Underscore => write!(f, "_"),
|
||||||
|
|
||||||
U8 => write!(f, "u8"),
|
|
||||||
U16 => write!(f, "u16"),
|
|
||||||
U32 => write!(f, "u32"),
|
|
||||||
U64 => write!(f, "u64"),
|
|
||||||
U128 => write!(f, "u128"),
|
|
||||||
I8 => write!(f, "i8"),
|
I8 => write!(f, "i8"),
|
||||||
I16 => write!(f, "i16"),
|
I16 => write!(f, "i16"),
|
||||||
I32 => write!(f, "i32"),
|
I32 => write!(f, "i32"),
|
||||||
I64 => write!(f, "i64"),
|
I64 => write!(f, "i64"),
|
||||||
I128 => write!(f, "i128"),
|
I128 => write!(f, "i128"),
|
||||||
|
Address => write!(f, "address"),
|
||||||
|
Bool => write!(f, "bool"),
|
||||||
Field => write!(f, "field"),
|
Field => write!(f, "field"),
|
||||||
Group => write!(f, "group"),
|
Group => write!(f, "group"),
|
||||||
Bool => write!(f, "bool"),
|
U8 => write!(f, "u8"),
|
||||||
Address => write!(f, "address"),
|
U16 => write!(f, "u16"),
|
||||||
|
U32 => write!(f, "u32"),
|
||||||
|
U64 => write!(f, "u64"),
|
||||||
|
U128 => write!(f, "u128"),
|
||||||
Char => write!(f, "char"),
|
Char => write!(f, "char"),
|
||||||
|
Scalar => write!(f, "scalar"),
|
||||||
|
|
||||||
Console => write!(f, "console"),
|
Console => write!(f, "console"),
|
||||||
Const => write!(f, "const"),
|
Const => write!(f, "const"),
|
||||||
|
@ -43,7 +43,7 @@ impl<'a> TypeChecker<'a> {
|
|||||||
match expr {
|
match expr {
|
||||||
Expression::Identifier(ident) => {
|
Expression::Identifier(ident) => {
|
||||||
if let Some(var) = self.symbol_table.lookup_variable(&ident.name) {
|
if let Some(var) = self.symbol_table.lookup_variable(&ident.name) {
|
||||||
Some(self.assert_type(var.type_.clone(), expected, span))
|
Some(self.assert_type(*var.type_, expected, span))
|
||||||
} else {
|
} else {
|
||||||
self.handler
|
self.handler
|
||||||
.emit_err(TypeCheckerError::unknown_sym("variable", ident.name, span).into());
|
.emit_err(TypeCheckerError::unknown_sym("variable", ident.name, span).into());
|
||||||
@ -143,42 +143,51 @@ impl<'a> TypeChecker<'a> {
|
|||||||
Some(self.assert_type(Type::IntegerType(*type_), expected, value.span()))
|
Some(self.assert_type(Type::IntegerType(*type_), expected, value.span()))
|
||||||
}
|
}
|
||||||
ValueExpression::Group(_) => Some(self.assert_type(Type::Group, expected, value.span())),
|
ValueExpression::Group(_) => Some(self.assert_type(Type::Group, expected, value.span())),
|
||||||
|
ValueExpression::Scalar(_, _) => Some(self.assert_type(Type::Scalar, expected, value.span())),
|
||||||
ValueExpression::String(_, _) => unreachable!("String types are not reachable"),
|
ValueExpression::String(_, _) => unreachable!("String types are not reachable"),
|
||||||
},
|
},
|
||||||
Expression::Binary(binary) => match binary.op {
|
Expression::Binary(binary) => match binary.op {
|
||||||
BinaryOperation::And | BinaryOperation::Or => {
|
BinaryOperation::And | BinaryOperation::Or => {
|
||||||
self.assert_type(Type::Boolean, expected.clone(), binary.span());
|
self.assert_type(Type::Boolean, expected, binary.span());
|
||||||
let t1 = self.compare_expr_type(&binary.left, expected.clone(), binary.left.span());
|
let t1 = self.compare_expr_type(&binary.left, expected, binary.left.span());
|
||||||
let t2 = self.compare_expr_type(&binary.right, expected.clone(), binary.right.span());
|
let t2 = self.compare_expr_type(&binary.right, expected, binary.right.span());
|
||||||
|
|
||||||
return_incorrect_type(t1, t2, expected)
|
return_incorrect_type(t1, t2, expected)
|
||||||
}
|
}
|
||||||
BinaryOperation::Add | BinaryOperation::Sub => {
|
BinaryOperation::Add => {
|
||||||
self.assert_arith_type(expected.clone(), binary.span());
|
self.assert_field_group_scalar_int_type(expected, binary.span());
|
||||||
let t1 = self.compare_expr_type(&binary.left, expected.clone(), binary.left.span());
|
let t1 = self.compare_expr_type(&binary.left, expected, binary.left.span());
|
||||||
let t2 = self.compare_expr_type(&binary.right, expected.clone(), binary.right.span());
|
let t2 = self.compare_expr_type(&binary.right, expected, binary.right.span());
|
||||||
|
|
||||||
|
return_incorrect_type(t1, t2, expected)
|
||||||
|
}
|
||||||
|
BinaryOperation::Sub => {
|
||||||
|
self.assert_field_group_int_type(expected, binary.span());
|
||||||
|
let t1 = self.compare_expr_type(&binary.left, expected, binary.left.span());
|
||||||
|
let t2 = self.compare_expr_type(&binary.right, expected, binary.right.span());
|
||||||
|
|
||||||
return_incorrect_type(t1, t2, expected)
|
return_incorrect_type(t1, t2, expected)
|
||||||
}
|
}
|
||||||
BinaryOperation::Mul => {
|
BinaryOperation::Mul => {
|
||||||
self.assert_arith_type(expected.clone(), binary.span());
|
self.assert_field_group_int_type(expected, binary.span());
|
||||||
|
|
||||||
let t1 = self.compare_expr_type(&binary.left, None, binary.left.span());
|
let t1 = self.compare_expr_type(&binary.left, None, binary.left.span());
|
||||||
let t2 = self.compare_expr_type(&binary.right, None, binary.right.span());
|
let t2 = self.compare_expr_type(&binary.right, None, binary.right.span());
|
||||||
|
|
||||||
|
// Allow `group` * `scalar` multiplication.
|
||||||
match (t1.as_ref(), t2.as_ref()) {
|
match (t1.as_ref(), t2.as_ref()) {
|
||||||
(Some(Type::Group), Some(other)) | (Some(other), Some(Type::Group)) => {
|
(Some(Type::Group), Some(other)) | (Some(other), Some(Type::Group)) => {
|
||||||
self.assert_int_type(Some(other.clone()), binary.span());
|
self.assert_type(*other, Some(Type::Scalar), binary.span());
|
||||||
Some(Type::Group)
|
Some(Type::Group)
|
||||||
}
|
}
|
||||||
_ => return_incorrect_type(t1, t2, expected),
|
_ => return_incorrect_type(t1, t2, expected),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BinaryOperation::Div => {
|
BinaryOperation::Div => {
|
||||||
self.assert_field_or_int_type(expected.clone(), binary.span());
|
self.assert_field_int_type(expected, binary.span());
|
||||||
|
|
||||||
let t1 = self.compare_expr_type(&binary.left, expected.clone(), binary.left.span());
|
let t1 = self.compare_expr_type(&binary.left, expected, binary.left.span());
|
||||||
let t2 = self.compare_expr_type(&binary.right, expected.clone(), binary.right.span());
|
let t2 = self.compare_expr_type(&binary.right, expected, binary.right.span());
|
||||||
return_incorrect_type(t1, t2, expected)
|
return_incorrect_type(t1, t2, expected)
|
||||||
}
|
}
|
||||||
BinaryOperation::Pow => {
|
BinaryOperation::Pow => {
|
||||||
@ -189,7 +198,7 @@ impl<'a> TypeChecker<'a> {
|
|||||||
// Type A must be an int.
|
// Type A must be an int.
|
||||||
// Type B must be a unsigned int.
|
// Type B must be a unsigned int.
|
||||||
(Some(Type::IntegerType(_)), Some(Type::IntegerType(itype))) if !itype.is_signed() => {
|
(Some(Type::IntegerType(_)), Some(Type::IntegerType(itype))) if !itype.is_signed() => {
|
||||||
self.assert_type(t1.clone().unwrap(), expected, binary.span());
|
self.assert_type(t1.unwrap(), expected, binary.span());
|
||||||
}
|
}
|
||||||
// Type A was an int.
|
// Type A was an int.
|
||||||
// But Type B was not a unsigned int.
|
// But Type B was not a unsigned int.
|
||||||
@ -222,7 +231,7 @@ impl<'a> TypeChecker<'a> {
|
|||||||
t1
|
t1
|
||||||
}
|
}
|
||||||
BinaryOperation::Eq | BinaryOperation::Ne => {
|
BinaryOperation::Eq | BinaryOperation::Ne => {
|
||||||
self.assert_type(Type::Boolean, expected.clone(), binary.span());
|
self.assert_type(Type::Boolean, expected, binary.span());
|
||||||
|
|
||||||
let t1 = self.compare_expr_type(&binary.left, None, binary.left.span());
|
let t1 = self.compare_expr_type(&binary.left, None, binary.left.span());
|
||||||
let t2 = self.compare_expr_type(&binary.right, None, binary.right.span());
|
let t2 = self.compare_expr_type(&binary.right, None, binary.right.span());
|
||||||
@ -230,20 +239,20 @@ impl<'a> TypeChecker<'a> {
|
|||||||
return_incorrect_type(t1, t2, expected)
|
return_incorrect_type(t1, t2, expected)
|
||||||
}
|
}
|
||||||
BinaryOperation::Lt | BinaryOperation::Gt | BinaryOperation::Le | BinaryOperation::Ge => {
|
BinaryOperation::Lt | BinaryOperation::Gt | BinaryOperation::Le | BinaryOperation::Ge => {
|
||||||
self.assert_type(Type::Boolean, expected.clone(), binary.span());
|
self.assert_type(Type::Boolean, expected, binary.span());
|
||||||
|
|
||||||
let t1 = self.compare_expr_type(&binary.left, None, binary.left.span());
|
let t1 = self.compare_expr_type(&binary.left, None, binary.left.span());
|
||||||
self.assert_int_type(t1.clone(), binary.left.span());
|
self.assert_field_scalar_int_type(t1, binary.left.span());
|
||||||
|
|
||||||
let t2 = self.compare_expr_type(&binary.right, None, binary.right.span());
|
let t2 = self.compare_expr_type(&binary.right, None, binary.right.span());
|
||||||
self.assert_int_type(t2.clone(), binary.right.span());
|
self.assert_field_scalar_int_type(t2, binary.right.span());
|
||||||
|
|
||||||
return_incorrect_type(t1, t2, expected)
|
return_incorrect_type(t1, t2, expected)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Expression::Unary(unary) => match unary.op {
|
Expression::Unary(unary) => match unary.op {
|
||||||
UnaryOperation::Not => {
|
UnaryOperation::Not => {
|
||||||
self.assert_type(Type::Boolean, expected.clone(), unary.span());
|
self.assert_type(Type::Boolean, expected, unary.span());
|
||||||
self.compare_expr_type(&unary.inner, expected, unary.inner.span())
|
self.compare_expr_type(&unary.inner, expected, unary.inner.span())
|
||||||
}
|
}
|
||||||
UnaryOperation::Negate => {
|
UnaryOperation::Negate => {
|
||||||
@ -269,14 +278,14 @@ impl<'a> TypeChecker<'a> {
|
|||||||
},
|
},
|
||||||
Expression::Ternary(ternary) => {
|
Expression::Ternary(ternary) => {
|
||||||
self.compare_expr_type(&ternary.condition, Some(Type::Boolean), ternary.condition.span());
|
self.compare_expr_type(&ternary.condition, Some(Type::Boolean), ternary.condition.span());
|
||||||
let t1 = self.compare_expr_type(&ternary.if_true, expected.clone(), ternary.if_true.span());
|
let t1 = self.compare_expr_type(&ternary.if_true, expected, ternary.if_true.span());
|
||||||
let t2 = self.compare_expr_type(&ternary.if_false, expected.clone(), ternary.if_false.span());
|
let t2 = self.compare_expr_type(&ternary.if_false, expected, ternary.if_false.span());
|
||||||
return_incorrect_type(t1, t2, expected)
|
return_incorrect_type(t1, t2, expected)
|
||||||
}
|
}
|
||||||
Expression::Call(call) => match &*call.function {
|
Expression::Call(call) => match &*call.function {
|
||||||
Expression::Identifier(ident) => {
|
Expression::Identifier(ident) => {
|
||||||
if let Some(func) = self.symbol_table.lookup_fn(&ident.name) {
|
if let Some(func) = self.symbol_table.lookup_fn(&ident.name) {
|
||||||
let ret = self.assert_type(func.output.clone(), expected, ident.span());
|
let ret = self.assert_type(func.output, expected, ident.span());
|
||||||
|
|
||||||
if func.input.len() != call.arguments.len() {
|
if func.input.len() != call.arguments.len() {
|
||||||
self.handler.emit_err(
|
self.handler.emit_err(
|
||||||
@ -293,11 +302,7 @@ impl<'a> TypeChecker<'a> {
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(call.arguments.iter())
|
.zip(call.arguments.iter())
|
||||||
.for_each(|(expected, argument)| {
|
.for_each(|(expected, argument)| {
|
||||||
self.compare_expr_type(
|
self.compare_expr_type(argument, Some(expected.get_variable().type_), argument.span());
|
||||||
argument,
|
|
||||||
Some(expected.get_variable().type_.clone()),
|
|
||||||
argument.span(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(ret)
|
Some(ret)
|
||||||
|
@ -26,7 +26,7 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
let parent = self.parent.unwrap();
|
let parent = self.parent.unwrap();
|
||||||
|
|
||||||
// Would never be None.
|
// Would never be None.
|
||||||
let func_output_type = self.symbol_table.lookup_fn(&parent).map(|f| f.output.clone());
|
let func_output_type = self.symbol_table.lookup_fn(&parent).map(|f| f.output);
|
||||||
self.compare_expr_type(&input.expression, func_output_type, input.expression.span());
|
self.compare_expr_type(&input.expression, func_output_type, input.expression.span());
|
||||||
|
|
||||||
VisitResult::VisitChildren
|
VisitResult::VisitChildren
|
||||||
@ -51,7 +51,7 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
self.handler.emit_err(err);
|
self.handler.emit_err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.compare_expr_type(&input.value, Some(input.type_.clone()), input.value.span());
|
self.compare_expr_type(&input.value, Some(input.type_), input.value.span());
|
||||||
});
|
});
|
||||||
|
|
||||||
VisitResult::VisitChildren
|
VisitResult::VisitChildren
|
||||||
@ -70,7 +70,7 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(var.type_.clone())
|
Some(*var.type_)
|
||||||
} else {
|
} else {
|
||||||
self.handler.emit_err(
|
self.handler.emit_err(
|
||||||
TypeCheckerError::unknown_sym("variable", &input.assignee.identifier.name, input.assignee.span).into(),
|
TypeCheckerError::unknown_sym("variable", &input.assignee.identifier.name, input.assignee.span).into(),
|
||||||
@ -104,8 +104,8 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
self.handler.emit_err(err);
|
self.handler.emit_err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.compare_expr_type(&input.start, Some(input.type_.clone()), input.start.span());
|
self.compare_expr_type(&input.start, Some(input.type_), input.start.span());
|
||||||
self.compare_expr_type(&input.stop, Some(input.type_.clone()), input.stop.span());
|
self.compare_expr_type(&input.stop, Some(input.type_), input.stop.span());
|
||||||
|
|
||||||
VisitResult::VisitChildren
|
VisitResult::VisitChildren
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,7 @@ pub struct TypeChecker<'a> {
|
|||||||
pub(crate) negate: bool,
|
pub(crate) negate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
const ARITHMETIC_TYPES: &[Type] = &[
|
const INT_TYPES: [Type; 10] = [
|
||||||
Type::Field,
|
|
||||||
Type::Group,
|
|
||||||
Type::IntegerType(IntegerType::I8),
|
Type::IntegerType(IntegerType::I8),
|
||||||
Type::IntegerType(IntegerType::I16),
|
Type::IntegerType(IntegerType::I16),
|
||||||
Type::IntegerType(IntegerType::I32),
|
Type::IntegerType(IntegerType::I32),
|
||||||
@ -42,34 +40,34 @@ const ARITHMETIC_TYPES: &[Type] = &[
|
|||||||
Type::IntegerType(IntegerType::U128),
|
Type::IntegerType(IntegerType::U128),
|
||||||
];
|
];
|
||||||
|
|
||||||
const FIELD_AND_INT_TYPES: &[Type] = &[
|
const fn create_type_superset<const S: usize, const A: usize, const O: usize>(
|
||||||
Type::Field,
|
subset: [Type; S],
|
||||||
Type::IntegerType(IntegerType::I8),
|
additional: [Type; A],
|
||||||
Type::IntegerType(IntegerType::I16),
|
) -> [Type; O] {
|
||||||
Type::IntegerType(IntegerType::I32),
|
let mut superset: [Type; O] = [Type::IntegerType(IntegerType::U8); O];
|
||||||
Type::IntegerType(IntegerType::I64),
|
let mut i = 0;
|
||||||
Type::IntegerType(IntegerType::I128),
|
while i < S {
|
||||||
Type::IntegerType(IntegerType::U8),
|
superset[i] = subset[i];
|
||||||
Type::IntegerType(IntegerType::U16),
|
i += 1;
|
||||||
Type::IntegerType(IntegerType::U32),
|
}
|
||||||
Type::IntegerType(IntegerType::U64),
|
let mut j = 0;
|
||||||
Type::IntegerType(IntegerType::U128),
|
while j < A {
|
||||||
];
|
superset[i + j] = additional[j];
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
superset
|
||||||
|
}
|
||||||
|
|
||||||
const INT_TYPES: &[Type] = &[
|
const FIELD_INT_TYPES: [Type; 11] = create_type_superset(INT_TYPES, [Type::Field]);
|
||||||
Type::IntegerType(IntegerType::I8),
|
|
||||||
Type::IntegerType(IntegerType::I16),
|
const FIELD_SCALAR_INT_TYPES: [Type; 12] = create_type_superset(FIELD_INT_TYPES, [Type::Scalar]);
|
||||||
Type::IntegerType(IntegerType::I32),
|
|
||||||
Type::IntegerType(IntegerType::I64),
|
const FIELD_GROUP_INT_TYPES: [Type; 12] = create_type_superset(FIELD_INT_TYPES, [Type::Group]);
|
||||||
Type::IntegerType(IntegerType::I128),
|
|
||||||
Type::IntegerType(IntegerType::U8),
|
const FIELD_GROUP_SCALAR_INT_TYPES: [Type; 13] = create_type_superset(FIELD_GROUP_INT_TYPES, [Type::Scalar]);
|
||||||
Type::IntegerType(IntegerType::U16),
|
|
||||||
Type::IntegerType(IntegerType::U32),
|
|
||||||
Type::IntegerType(IntegerType::U64),
|
|
||||||
Type::IntegerType(IntegerType::U128),
|
|
||||||
];
|
|
||||||
|
|
||||||
impl<'a> TypeChecker<'a> {
|
impl<'a> TypeChecker<'a> {
|
||||||
|
/// Returns a new type checker given a symbol table and error handler.
|
||||||
pub fn new(symbol_table: &'a mut SymbolTable<'a>, handler: &'a Handler) -> Self {
|
pub fn new(symbol_table: &'a mut SymbolTable<'a>, handler: &'a Handler) -> Self {
|
||||||
Self {
|
Self {
|
||||||
symbol_table,
|
symbol_table,
|
||||||
@ -79,47 +77,51 @@ impl<'a> TypeChecker<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the given type if it equals the expected type or the expected type is none.
|
||||||
pub(crate) fn assert_type(&self, type_: Type, expected: Option<Type>, span: Span) -> Type {
|
pub(crate) fn assert_type(&self, type_: Type, expected: Option<Type>, span: Span) -> Type {
|
||||||
if let Some(expected) = expected {
|
if let Some(expected) = expected {
|
||||||
if type_ != expected {
|
if type_ != expected {
|
||||||
self.handler
|
self.handler
|
||||||
.emit_err(TypeCheckerError::type_should_be(type_.clone(), expected, span).into());
|
.emit_err(TypeCheckerError::type_should_be(type_, expected, span).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type_
|
type_
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn assert_one_of_types(&self, type_: Option<Type>, expected: &[Type], span: Span) -> Option<Type> {
|
/// Emits an error to the error handler if the given type is not equal to any of the expected types.
|
||||||
if let Some(type_) = type_.clone() {
|
pub(crate) fn assert_one_of_types(&self, type_: Option<Type>, expected: &[Type], span: Span) {
|
||||||
for t in expected.iter() {
|
if let Some(type_) = type_ {
|
||||||
if &type_ == t {
|
if !expected.iter().any(|t: &Type| t == &type_) {
|
||||||
return Some(type_);
|
self.handler.emit_err(
|
||||||
}
|
TypeCheckerError::expected_one_type_of(
|
||||||
|
expected.iter().map(|t| t.to_string() + ",").collect::<String>(),
|
||||||
|
type_,
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.handler.emit_err(
|
|
||||||
TypeCheckerError::expected_one_type_of(
|
|
||||||
expected.iter().map(|t| t.to_string() + ",").collect::<String>(),
|
|
||||||
type_,
|
|
||||||
span,
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type_
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn assert_arith_type(&self, type_: Option<Type>, span: Span) -> Option<Type> {
|
/// Emits an error to the handler if the given type is not a field or integer.
|
||||||
self.assert_one_of_types(type_, ARITHMETIC_TYPES, span)
|
pub(crate) fn assert_field_int_type(&self, type_: Option<Type>, span: Span) {
|
||||||
|
self.assert_one_of_types(type_, &FIELD_INT_TYPES, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn assert_field_or_int_type(&self, type_: Option<Type>, span: Span) -> Option<Type> {
|
/// Emits an error to the handler if the given type is not a field, scalar, or integer.
|
||||||
self.assert_one_of_types(type_, FIELD_AND_INT_TYPES, span)
|
pub(crate) fn assert_field_scalar_int_type(&self, type_: Option<Type>, span: Span) {
|
||||||
|
self.assert_one_of_types(type_, &FIELD_SCALAR_INT_TYPES, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn assert_int_type(&self, type_: Option<Type>, span: Span) -> Option<Type> {
|
/// Emits an error to the handler if the given type is not a field, group, or integer.
|
||||||
self.assert_one_of_types(type_, INT_TYPES, span)
|
pub(crate) fn assert_field_group_int_type(&self, type_: Option<Type>, span: Span) {
|
||||||
|
self.assert_one_of_types(type_, &FIELD_GROUP_INT_TYPES, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emits an error to the handler if the given type is not a field, group, scalar or integer.
|
||||||
|
pub(crate) fn assert_field_group_scalar_int_type(&self, type_: Option<Type>, span: Span) {
|
||||||
|
self.assert_one_of_types(type_, &FIELD_GROUP_SCALAR_INT_TYPES, span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -91,6 +91,7 @@ keyword = %s"address"
|
|||||||
/ %s"let"
|
/ %s"let"
|
||||||
/ %s"public"
|
/ %s"public"
|
||||||
/ %s"return"
|
/ %s"return"
|
||||||
|
/ %s"scalar"
|
||||||
/ %s"u8"
|
/ %s"u8"
|
||||||
/ %s"u16"
|
/ %s"u16"
|
||||||
/ %s"u32"
|
/ %s"u32"
|
||||||
@ -122,6 +123,8 @@ field-literal = numeral %s"field"
|
|||||||
|
|
||||||
product-group-literal = numeral %s"group"
|
product-group-literal = numeral %s"group"
|
||||||
|
|
||||||
|
scalar-literal = numeral %s"scalar"
|
||||||
|
|
||||||
boolean-literal = %s"true" / %s"false"
|
boolean-literal = %s"true" / %s"false"
|
||||||
|
|
||||||
address-literal = %s"aleo1" 58( lowercase-letter / decimal-digit )
|
address-literal = %s"aleo1" 58( lowercase-letter / decimal-digit )
|
||||||
@ -172,6 +175,7 @@ integer-literal = unsigned-literal
|
|||||||
numeric-literal = integer-literal
|
numeric-literal = integer-literal
|
||||||
/ field-literal
|
/ field-literal
|
||||||
/ product-group-literal
|
/ product-group-literal
|
||||||
|
/ scalar-literal
|
||||||
|
|
||||||
atomic-literal = numeric-literal
|
atomic-literal = numeric-literal
|
||||||
/ boolean-literal
|
/ boolean-literal
|
||||||
@ -214,7 +218,9 @@ field-type = %s"field"
|
|||||||
|
|
||||||
group-type = %s"group"
|
group-type = %s"group"
|
||||||
|
|
||||||
arithmetic-type = integer-type / field-type / group-type
|
scalar-type = %s"scalar"
|
||||||
|
|
||||||
|
arithmetic-type = integer-type / field-type / group-type / scalar-type
|
||||||
|
|
||||||
boolean-type = %s"bool"
|
boolean-type = %s"bool"
|
||||||
|
|
||||||
|
@ -135,6 +135,7 @@ symbols! {
|
|||||||
prelude,
|
prelude,
|
||||||
Public,
|
Public,
|
||||||
Return: "return",
|
Return: "return",
|
||||||
|
scalar,
|
||||||
Star: "*",
|
Star: "*",
|
||||||
std,
|
std,
|
||||||
Struct: "struct",
|
Struct: "struct",
|
||||||
|
@ -45,27 +45,32 @@ generated instead. A PR should contain changes to expectations as well as to tes
|
|||||||
|
|
||||||
Here is the list of all possible configuration options for compiler and parser tests.
|
Here is the list of all possible configuration options for compiler and parser tests.
|
||||||
|
|
||||||
#### namespace
|
### namespace
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
- Mandatory: yes
|
- Mandatory: yes
|
||||||
- Namespace: all
|
- Namespace: all
|
||||||
- Values: Compile / Parse
|
- Values: ...
|
||||||
```
|
```
|
||||||
|
|
||||||
Only two values are supported: `Parse` and `Compile`. The former is meant to be a parser test, the latter
|
Several values are supported, but they vary depending on the directory you are in.
|
||||||
is a full compiler test.
|
|
||||||
|
|
||||||
Besides the `Parse` value,
|
Parser Directory namespaces:
|
||||||
there are actually additional possible values for this field:
|
|
||||||
`ParseStatement`, `ParseExpression`, and `Token`.
|
|
||||||
Each one of them allows testing Leo parser on different levels - lexer tokens or just expressions/statements.
|
|
||||||
|
|
||||||
Compiler tests always include complete Leo programs.
|
- `Parse` - Test a file to check that it is a valid Leo program.
|
||||||
|
- `ParseExpression` - Test a file line by line to check that each line is a valid Leo expression.
|
||||||
|
- `ParseStatement` - Test a file consuming multiple lines till a blank line to check that it contains a valid Leo statement.
|
||||||
|
- `Serialize` - Test a file to check that it can be serialized to JSON.
|
||||||
|
- `Input` - Test an input file to check that it is a valid Leo input file.
|
||||||
|
- `Token` - Test a file line by line to check that it contains zero or more valid Leo parser tokens.
|
||||||
|
|
||||||
|
Compiler Directory namespaces:
|
||||||
|
|
||||||
|
- `Compiler` - Test a file to check that it is a valid Leo program, and it can be compiled without errors.
|
||||||
|
|
||||||
### expectation
|
### expectation
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
- Mandatory: yes
|
- Mandatory: yes
|
||||||
- Namespace: all
|
- Namespace: all
|
||||||
- Values: Pass / Fail
|
- Values: Pass / Fail
|
||||||
@ -77,7 +82,7 @@ you'll know that something went wrong and the test or the compiler/parser needs
|
|||||||
|
|
||||||
### input_file (Compile)
|
### input_file (Compile)
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
- Mandatory: no
|
- Mandatory: no
|
||||||
- Namespace: Compile
|
- Namespace: Compile
|
||||||
- Values: <input file path>, ...
|
- Values: <input file path>, ...
|
||||||
@ -87,7 +92,7 @@ This setting allows using one or more input files for the Leo program.
|
|||||||
The program will be run with every provided input.
|
The program will be run with every provided input.
|
||||||
See this example:
|
See this example:
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
/*
|
/*
|
||||||
namespace: Compile
|
namespace: Compile
|
||||||
expectation: Pass
|
expectation: Pass
|
||||||
|
@ -5,5 +5,5 @@ input_file: inputs/one.in
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function main(a: group) -> group {
|
function main(a: group) -> group {
|
||||||
return 1u8 * a;
|
return 1scalar * a;
|
||||||
}
|
}
|
10
tests/compiler/scalar/add.leo
Normal file
10
tests/compiler/scalar/add.leo
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
input_file:
|
||||||
|
- inputs/scalars.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main(a: scalar, b: scalar, c: scalar) -> bool {
|
||||||
|
return a + b == c;
|
||||||
|
}
|
14
tests/compiler/scalar/cmp.leo
Normal file
14
tests/compiler/scalar/cmp.leo
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
input_file:
|
||||||
|
- inputs/scalars.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main(a: scalar, b: scalar) -> bool {
|
||||||
|
let c: bool = a > b;
|
||||||
|
let d: bool = a < b;
|
||||||
|
let e: bool = a >= b;
|
||||||
|
let f: bool = a <= b;
|
||||||
|
return f;
|
||||||
|
}
|
10
tests/compiler/scalar/div.leo
Normal file
10
tests/compiler/scalar/div.leo
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
input_file:
|
||||||
|
- inputs/scalars.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main(a: scalar, b: scalar, c: scalar) -> bool {
|
||||||
|
return a / b != c;
|
||||||
|
}
|
12
tests/compiler/scalar/eq.leo
Normal file
12
tests/compiler/scalar/eq.leo
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
input_file:
|
||||||
|
- inputs/scalars.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main(a: scalar, b: scalar) -> bool {
|
||||||
|
let c: bool = a == b;
|
||||||
|
let d: bool = a != b;
|
||||||
|
return d;
|
||||||
|
}
|
15
tests/compiler/scalar/group_mul.leo
Normal file
15
tests/compiler/scalar/group_mul.leo
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
input_file:
|
||||||
|
- inputs/scalar_group.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main(a: scalar, b: group, c: scalar) -> bool {
|
||||||
|
let d: group = 1group * a;
|
||||||
|
let e: group = a * 1group;
|
||||||
|
let f: group = b * a;
|
||||||
|
let g: group = a * b;
|
||||||
|
|
||||||
|
return a * g == d;
|
||||||
|
}
|
7
tests/compiler/scalar/inputs/scalar_group.in
Normal file
7
tests/compiler/scalar/inputs/scalar_group.in
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[main]
|
||||||
|
a: scalar = 1scalar;
|
||||||
|
b: group = 1group;
|
||||||
|
c: scalar = 2scalar;
|
||||||
|
|
||||||
|
[registers]
|
||||||
|
r: bool = false;
|
7
tests/compiler/scalar/inputs/scalars.in
Normal file
7
tests/compiler/scalar/inputs/scalars.in
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[main]
|
||||||
|
a: scalar = 1scalar;
|
||||||
|
b: scalar = 1scalar;
|
||||||
|
c: scalar = 2scalar;
|
||||||
|
|
||||||
|
[registers]
|
||||||
|
r: bool = false;
|
10
tests/compiler/scalar/mul.leo
Normal file
10
tests/compiler/scalar/mul.leo
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
input_file:
|
||||||
|
- inputs/scalars.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main(a: scalar, b: scalar, c: scalar) -> bool {
|
||||||
|
return a * b == c;
|
||||||
|
}
|
8
tests/compiler/scalar/no_space_between_literal.leo
Normal file
8
tests/compiler/scalar/no_space_between_literal.leo
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Fail
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const f = 1 scalar;
|
||||||
|
}
|
11
tests/compiler/scalar/scalar.leo
Normal file
11
tests/compiler/scalar/scalar.leo
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
input_file:
|
||||||
|
- inputs/scalars.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main(a: scalar) -> bool {
|
||||||
|
const s: scalar = 1scalar;
|
||||||
|
return s + a == 0scalar;
|
||||||
|
}
|
10
tests/compiler/scalar/ternary.leo
Normal file
10
tests/compiler/scalar/ternary.leo
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
input_file:
|
||||||
|
- inputs/scalars.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
function main(a: scalar, b: scalar, c: scalar) -> bool {
|
||||||
|
return b == 1scalar ? a == 1scalar : c == 2scalar;
|
||||||
|
}
|
@ -2,4 +2,4 @@
|
|||||||
namespace: Compile
|
namespace: Compile
|
||||||
expectation: Fail
|
expectation: Fail
|
||||||
outputs:
|
outputs:
|
||||||
- "Error [ETYC0372007]: Expected one type from `i8,i16,i32,i64,i128,u8,u16,u32,u64,u128,`, but got `group`\n --> compiler-test:4:12\n |\n 4 | return (_, _)group * a;\n | ^^^^^^^^^^^^^^^\nError [ETYC0372007]: Expected one type from `i8,i16,i32,i64,i128,u8,u16,u32,u64,u128,`, but got `group`\n --> compiler-test:4:12\n |\n 4 | return (_, _)group * a;\n | ^^^^^^^^^^^^^^^"
|
- "Error [ETYC0372002]: Found type `group` but type `scalar` was expected\n --> compiler-test:4:12\n |\n 4 | return (_, _)group * a;\n | ^^^^^^^^^^^^^^^\nError [ETYC0372002]: Found type `group` but type `scalar` was expected\n --> compiler-test:4:12\n |\n 4 | return (_, _)group * a;\n | ^^^^^^^^^^^^^^^"
|
||||||
|
@ -3,6 +3,6 @@ namespace: Compile
|
|||||||
expectation: Pass
|
expectation: Pass
|
||||||
outputs:
|
outputs:
|
||||||
- output:
|
- output:
|
||||||
- initial_input_ast: 4a7d722c26d55d9c1c3067f6d2ef891b2afde9cee26a1043ac78ae2f6ce2e8c1
|
- initial_input_ast: 1c07a704862cbf7d7938c51d6d840c9ee713f3b6f661a60cca2a81ef3e55efa2
|
||||||
initial_ast: 0c31dfc043a0f27d955558a8c97370a490309e59c4de6f228b491a02475b6384
|
initial_ast: da7d4b5638893ec9b4b7320749934b632d179d7a99c6efcae3897609f666e419
|
||||||
symbol_table: 8e39b2bdad6276a42437b673faa0d1dd4f762a9778de1a1e2c8f8edbe5002be4
|
symbol_table: ac787ea8268badd26320c55d7d1b808ca7bfdaac3994570a28e605d637f1cdaf
|
||||||
|
8
tests/expectations/compiler/compiler/scalar/add.leo.out
Normal file
8
tests/expectations/compiler/compiler/scalar/add.leo.out
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: 4f141316ffe2f84865d36d0d28d361fdaa90bacf05ff62678d32f901a235ed74
|
||||||
|
initial_ast: fd4126b8ea19b5afd542aa1c1ad269656d3bf24297470cbdb64b675184f6e698
|
||||||
|
symbol_table: 892d93d278cb7a474cdf2dfd4a40294a748165ebeeb47cba6dbee3f31d7fd586
|
8
tests/expectations/compiler/compiler/scalar/cmp.leo.out
Normal file
8
tests/expectations/compiler/compiler/scalar/cmp.leo.out
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: 85349bd16d49ff31c5ed3aeacf84ee6278d4d951409f8b055849eb41481e612e
|
||||||
|
initial_ast: f9d6d5d94f9aead249bf86205884b49eff222937842973864758c01757d3eafa
|
||||||
|
symbol_table: 240729bf3dd32b0ff548d132bc74bc91e42a8677f98d5fa1e388259e6a407d95
|
8
tests/expectations/compiler/compiler/scalar/div.leo.out
Normal file
8
tests/expectations/compiler/compiler/scalar/div.leo.out
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: 2fdded6208cca2d992178f1ebce1ad848f09f0e7bc5b5a01ee767fafd992737f
|
||||||
|
initial_ast: c20c79fbafd514aadf1887dea23f564f5e9bbd7c26caf9408bf664a495bfd6aa
|
||||||
|
symbol_table: eef6184d8de08329af65525b860dea76d00957bbd099b98cb35cc9e22a5c568c
|
8
tests/expectations/compiler/compiler/scalar/eq.leo.out
Normal file
8
tests/expectations/compiler/compiler/scalar/eq.leo.out
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: 33bfdc8b1c15b79c4df536c93be684108ac3f031e23b2a4359f5cdc780ebe6e9
|
||||||
|
initial_ast: 73e323d6a21198a304ce5691a6cd8a7c1bd449fff01afad7ea83aa57c31a3554
|
||||||
|
symbol_table: 08cd46bf33b7d8cc59bb80d5716911598c0479cd25e30e00a1b47b175d8e7c0f
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: cf06fc39ca04a486855a4df808362d7a950ecd6fee1bde05bc28011c33404726
|
||||||
|
initial_ast: 504a536d2f70bff90e1e941b0c30fd95195757c69326e9d168a224c3f9590de5
|
||||||
|
symbol_table: cb5c8eb4006c52c0092effc2219dbd03b90ab1baf39f345f838ada8a57d1158c
|
8
tests/expectations/compiler/compiler/scalar/mul.leo.out
Normal file
8
tests/expectations/compiler/compiler/scalar/mul.leo.out
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: 4f141316ffe2f84865d36d0d28d361fdaa90bacf05ff62678d32f901a235ed74
|
||||||
|
initial_ast: c2fe013362376acd540235900ae220eef966bb7a870e6bac2efdcdb66bf96aaa
|
||||||
|
symbol_table: 1c43e99020a8214e8a0a8ff037a79dc12b597c0801642f5a564e8e4b3e42b679
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Fail
|
||||||
|
outputs:
|
||||||
|
- "Error [EPAR0370005]: expected -> -- got '{'\n --> compiler-test:3:17\n |\n 3 | function main() {\n | ^"
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: f074f67a7d4028112cee3c14d6fa831ac71e0776db4f4f793df9dbfc6bd921c3
|
||||||
|
initial_ast: d6a1be88337def873777e4296959ced20e923c27736200993a3e86992d15eb6e
|
||||||
|
symbol_table: 85a8380cbcefab3e365d6d3f7acbb54125afedb9b8ff98e4513b147ffe0ccf14
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- output:
|
||||||
|
- initial_input_ast: 33bfdc8b1c15b79c4df536c93be684108ac3f031e23b2a4359f5cdc780ebe6e9
|
||||||
|
initial_ast: 0d139bfef33401468cd0ee0591fc2fbb5ddfcc977e4006e6ae8013c73434bbf4
|
||||||
|
symbol_table: 3044db73279e2416a04d470427a0f319f13ac1dfbe36706b238e1fa2fb068538
|
@ -0,0 +1,634 @@
|
|||||||
|
---
|
||||||
|
namespace: ParseExpression
|
||||||
|
expectation: Pass
|
||||||
|
outputs:
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "123"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 9
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "123"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 9
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "456"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 9
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "87377802873778028737780287377802873778028737780287377802873778028737780287377802"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 86
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "8737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 406
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "340130024"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "158951116"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "155529659"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "642023166"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "228481736"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "469712960"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "929437719"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "721072814"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "363254789"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "906732565"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "288246391"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "724940549"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "487101620"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "261373583"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "891163927"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "743967544"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "8372586"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 13
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "461793278"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "806307045"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "122764546"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "356336181"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "158370903"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "774460877"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "557174131"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "492401267"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "893445620"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "957757048"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "721540649"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "390746493"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "211251725"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "938266114"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "156985870"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "703831126"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "729964155"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "988151305"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "320872435"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "719287167"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "152289486"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "740067975"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "728627816"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "385008978"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "553967635"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "71980713"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 14
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "519444716"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "116499965"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "717422268"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "18966279"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 14
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "22458638"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 14
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "857282620"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "920675898"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "762235516"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "469018377"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "199986521"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "536679358"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "591399452"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "83083158"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 14
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "599449051"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "445442318"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "585486590"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "209278800"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "873568117"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "664470940"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "465262783"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "605652874"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "376803940"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "965247040"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "598474509"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "845119918"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "648159133"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "669051032"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "800600261"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "434689764"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "520060080"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "804659385"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "537828058"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "716600292"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "387020273"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "199375617"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "680337189"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "818479931"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "893693281"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "87377802"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 14
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "84699261"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 14
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "292826090"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "569171405"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "387436237"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "150682190"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "888770419"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "824696431"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "765659803"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "270163693"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "427940240"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "504997332"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "337808338"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "907200008"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "757177889"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "696697188"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "41376051"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 14
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "496293518"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
||||||
|
- Value:
|
||||||
|
Scalar:
|
||||||
|
- "251218820"
|
||||||
|
- span:
|
||||||
|
lo: 0
|
||||||
|
hi: 15
|
@ -25,23 +25,23 @@ outputs:
|
|||||||
- "Error [EPAR0370009]: unexpected string: expected 'ident', got ','\n --> test:1:10\n |\n 1 | let (x,y,,) = ();\n | ^"
|
- "Error [EPAR0370009]: unexpected string: expected 'ident', got ','\n --> test:1:10\n |\n 1 | let (x,y,,) = ();\n | ^"
|
||||||
- "Error [EPAR0370009]: unexpected string: expected 'ident', got ','\n --> test:1:6\n |\n 1 | let (,x,y) = ();\n | ^"
|
- "Error [EPAR0370009]: unexpected string: expected 'ident', got ','\n --> test:1:6\n |\n 1 | let (,x,y) = ();\n | ^"
|
||||||
- "Error [EPAR0370009]: unexpected string: expected 'ident', got ','\n --> test:1:8\n |\n 1 | let (x,,y) = ();\n | ^"
|
- "Error [EPAR0370009]: unexpected string: expected 'ident', got ','\n --> test:1:8\n |\n 1 | let (x,,y) = ();\n | ^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got '['\n --> test:1:8\n |\n 1 | let x: [u8; (2,,)] = [[0,0], [0,0]];\n | ^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got '['\n --> test:1:8\n |\n 1 | let x: [u8; (2,,)] = [[0,0], [0,0]];\n | ^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got 'const'\n --> test:1:8\n |\n 1 | let x: const = expr;\n | ^^^^^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got 'const'\n --> test:1:8\n |\n 1 | let x: const = expr;\n | ^^^^^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got 'let'\n --> test:1:10\n |\n 1 | const x: let = expr;\n | ^^^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got 'let'\n --> test:1:10\n |\n 1 | const x: let = expr;\n | ^^^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got 'mut'\n --> test:1:8\n |\n 1 | let x: mut = expr;\n | ^^^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got 'mut'\n --> test:1:8\n |\n 1 | let x: mut = expr;\n | ^^^"
|
||||||
- "Error [EPAR0370009]: unexpected string: expected 'ident', got '<eof>'\n --> test:1:1\n |\n 1 | let\n | ^^^"
|
- "Error [EPAR0370009]: unexpected string: expected 'ident', got '<eof>'\n --> test:1:1\n |\n 1 | let\n | ^^^"
|
||||||
- "Error [EPAR0370005]: expected : -- got '<eof>'\n --> test:1:5\n |\n 1 | let x\n | ^"
|
- "Error [EPAR0370005]: expected : -- got '<eof>'\n --> test:1:5\n |\n 1 | let x\n | ^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got '<eof>'\n --> test:1:6\n |\n 1 | let x:\n | ^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got '<eof>'\n --> test:1:6\n |\n 1 | let x:\n | ^"
|
||||||
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = (a, y]);\n | ^"
|
- "Error [EPAR0370005]: expected : -- got '='\n --> test:1:7\n |\n 1 | let x = (a, y]);\n | ^"
|
||||||
- "Error [EPAR0370009]: unexpected string: expected 'ident', got '='\n --> test:1:5\n |\n 1 | let = 1u8;\n | ^"
|
- "Error [EPAR0370009]: unexpected string: expected 'ident', got '='\n --> test:1:5\n |\n 1 | let = 1u8;\n | ^"
|
||||||
- "Error [EPAR0370009]: unexpected string: expected 'ident', got ';'\n --> test:1:4\n |\n 1 | let;\n | ^"
|
- "Error [EPAR0370009]: unexpected string: expected 'ident', got ';'\n --> test:1:4\n |\n 1 | let;\n | ^"
|
||||||
- "Error [EPAR0370005]: expected : -- got '1'\n --> test:1:7\n |\n 1 | let x 1u8;\n | ^"
|
- "Error [EPAR0370005]: expected : -- got '1'\n --> test:1:7\n |\n 1 | let x 1u8;\n | ^"
|
||||||
- "Error [EPAR0370005]: expected = -- got ';'\n --> test:1:10\n |\n 1 | let x: u8;\n | ^"
|
- "Error [EPAR0370005]: expected = -- got ';'\n --> test:1:10\n |\n 1 | let x: u8;\n | ^"
|
||||||
- "Error [EPAR0370005]: expected = -- got '<eof>'\n --> test:1:8\n |\n 1 | let x: u8\n | ^^"
|
- "Error [EPAR0370005]: expected = -- got '<eof>'\n --> test:1:8\n |\n 1 | let x: u8\n | ^^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got '='\n --> test:1:8\n |\n 1 | let x: = 1;\n | ^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got '='\n --> test:1:8\n |\n 1 | let x: = 1;\n | ^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got '['\n --> test:1:8\n |\n 1 | let x: [u8] = 1;\n | ^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got '['\n --> test:1:8\n |\n 1 | let x: [u8] = 1;\n | ^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got '['\n --> test:1:8\n |\n 1 | let x: [u8;\n | ^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got '['\n --> test:1:8\n |\n 1 | let x: [u8;\n | ^"
|
||||||
- "Error [EPAR0370005]: expected 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'field', 'group', 'address', 'bool', 'char' -- got '['\n --> test:1:8\n |\n 1 | let x: [u8; 1u8] = [1,\n | ^"
|
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128', 'char', 'scalar' -- got '['\n --> test:1:8\n |\n 1 | let x: [u8; 1u8] = [1,\n | ^"
|
||||||
- "Error [EPAR0370009]: unexpected string: expected 'expression', got ']'\n --> test:1:15\n |\n 1 | let dbg: u8 = ];\n | ^"
|
- "Error [EPAR0370009]: unexpected string: expected 'expression', got ']'\n --> test:1:15\n |\n 1 | let dbg: u8 = ];\n | ^"
|
||||||
- "Error [EPAR0370028]: Could not lex the following content: `🦀: u8 = 0;`."
|
- "Error [EPAR0370028]: Could not lex the following content: `🦀: u8 = 0;`."
|
||||||
- "Error [EPAR0370037]: do not put parens around single variable names\n --> test:1:6\n |\n 1 | let (x) = ...;\n | ^\nError [EPAR0370005]: expected : -- got '='\n --> test:1:9\n |\n 1 | let (x) = ...;\n | ^"
|
- "Error [EPAR0370037]: do not put parens around single variable names\n --> test:1:6\n |\n 1 | let (x) = ...;\n | ^\nError [EPAR0370005]: expected : -- got '='\n --> test:1:9\n |\n 1 | let (x) = ...;\n | ^"
|
||||||
|
114
tests/parser/expression/literal/int_parse/scalar.leo
Normal file
114
tests/parser/expression/literal/int_parse/scalar.leo
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
namespace: ParseExpression
|
||||||
|
expectation: Pass
|
||||||
|
*/
|
||||||
|
|
||||||
|
123scalar
|
||||||
|
|
||||||
|
123scalar
|
||||||
|
456scalar
|
||||||
|
|
||||||
|
87377802873778028737780287377802873778028737780287377802873778028737780287377802scalar
|
||||||
|
|
||||||
|
8737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802873778028737780287377802scalar
|
||||||
|
|
||||||
|
340130024scalar
|
||||||
|
158951116scalar
|
||||||
|
155529659scalar
|
||||||
|
642023166scalar
|
||||||
|
228481736scalar
|
||||||
|
469712960scalar
|
||||||
|
929437719scalar
|
||||||
|
721072814scalar
|
||||||
|
363254789scalar
|
||||||
|
906732565scalar
|
||||||
|
288246391scalar
|
||||||
|
724940549scalar
|
||||||
|
487101620scalar
|
||||||
|
261373583scalar
|
||||||
|
891163927scalar
|
||||||
|
743967544scalar
|
||||||
|
8372586scalar
|
||||||
|
461793278scalar
|
||||||
|
806307045scalar
|
||||||
|
122764546scalar
|
||||||
|
356336181scalar
|
||||||
|
158370903scalar
|
||||||
|
774460877scalar
|
||||||
|
557174131scalar
|
||||||
|
492401267scalar
|
||||||
|
893445620scalar
|
||||||
|
957757048scalar
|
||||||
|
721540649scalar
|
||||||
|
390746493scalar
|
||||||
|
211251725scalar
|
||||||
|
938266114scalar
|
||||||
|
156985870scalar
|
||||||
|
703831126scalar
|
||||||
|
729964155scalar
|
||||||
|
988151305scalar
|
||||||
|
320872435scalar
|
||||||
|
719287167scalar
|
||||||
|
152289486scalar
|
||||||
|
740067975scalar
|
||||||
|
728627816scalar
|
||||||
|
385008978scalar
|
||||||
|
553967635scalar
|
||||||
|
71980713scalar
|
||||||
|
519444716scalar
|
||||||
|
116499965scalar
|
||||||
|
717422268scalar
|
||||||
|
18966279scalar
|
||||||
|
22458638scalar
|
||||||
|
857282620scalar
|
||||||
|
920675898scalar
|
||||||
|
762235516scalar
|
||||||
|
469018377scalar
|
||||||
|
199986521scalar
|
||||||
|
536679358scalar
|
||||||
|
591399452scalar
|
||||||
|
83083158scalar
|
||||||
|
599449051scalar
|
||||||
|
445442318scalar
|
||||||
|
585486590scalar
|
||||||
|
209278800scalar
|
||||||
|
873568117scalar
|
||||||
|
664470940scalar
|
||||||
|
465262783scalar
|
||||||
|
605652874scalar
|
||||||
|
376803940scalar
|
||||||
|
965247040scalar
|
||||||
|
598474509scalar
|
||||||
|
845119918scalar
|
||||||
|
648159133scalar
|
||||||
|
669051032scalar
|
||||||
|
800600261scalar
|
||||||
|
434689764scalar
|
||||||
|
520060080scalar
|
||||||
|
804659385scalar
|
||||||
|
537828058scalar
|
||||||
|
716600292scalar
|
||||||
|
387020273scalar
|
||||||
|
199375617scalar
|
||||||
|
680337189scalar
|
||||||
|
818479931scalar
|
||||||
|
893693281scalar
|
||||||
|
87377802scalar
|
||||||
|
84699261scalar
|
||||||
|
292826090scalar
|
||||||
|
569171405scalar
|
||||||
|
387436237scalar
|
||||||
|
150682190scalar
|
||||||
|
888770419scalar
|
||||||
|
824696431scalar
|
||||||
|
765659803scalar
|
||||||
|
270163693scalar
|
||||||
|
427940240scalar
|
||||||
|
504997332scalar
|
||||||
|
337808338scalar
|
||||||
|
907200008scalar
|
||||||
|
757177889scalar
|
||||||
|
696697188scalar
|
||||||
|
41376051scalar
|
||||||
|
496293518scalar
|
||||||
|
251218820scalar
|
@ -0,0 +1,82 @@
|
|||||||
|
# Leo Test Framework
|
||||||
|
|
||||||
|
This directory includes the code for the Leo Test Framework.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
You would first create a rust test file inside the folder of some part of the compiler, as the test framework tests are run by the rust test framework.
|
||||||
|
|
||||||
|
### Namespaces
|
||||||
|
|
||||||
|
Then you would create a `struct` that represents a `Namespace` where you have to implement the following:
|
||||||
|
|
||||||
|
#### Parse Type
|
||||||
|
|
||||||
|
Each `namespace` must have a function, `parse_type` that returns a `ParseType`. There are several kinds of `ParseTypes`:
|
||||||
|
|
||||||
|
- Line - Parses the File line one by one.
|
||||||
|
- ContinuousLines - Parses lines continuously as one item until an empty line is encountered.
|
||||||
|
- Whole - Parses the whole file.
|
||||||
|
|
||||||
|
#### Run Test
|
||||||
|
|
||||||
|
Each `namespace` must have a function, that runs and dictates how you want the tests for that namespace to work. To make running a test possible you are given information about the test file, like its name, content, path, etc. It allows you to return any type of output to be written to an expectation file as long as it's serializable.
|
||||||
|
|
||||||
|
### Runner
|
||||||
|
|
||||||
|
Then you would create a `struct` that represents a `Runner` where you have to implement the following:
|
||||||
|
|
||||||
|
#### Resolve Namespace
|
||||||
|
|
||||||
|
Each test file only needs one runner that represents the namespace resolution to which type of test should be run with a given string.
|
||||||
|
|
||||||
|
i.e.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
struct ParseTestRunner;
|
||||||
|
|
||||||
|
impl Runner for ParseTestRunner {
|
||||||
|
fn resolve_namespace(&self, name: &str) -> Option<Box<dyn Namespace>> {
|
||||||
|
Some(match name {
|
||||||
|
"Parse" => Box::new(ParseNamespace),
|
||||||
|
"ParseExpression" => Box::new(ParseExpressionNamespace),
|
||||||
|
"ParseStatement" => Box::new(ParseStatementNamespace),
|
||||||
|
"Serialize" => Box::new(SerializeNamespace),
|
||||||
|
"Input" => Box::new(InputNamespace),
|
||||||
|
"Token" => Box::new(TokenNamespace),
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rust test Function
|
||||||
|
|
||||||
|
A rust test function that calls the framework over the runner, as well as the name of the directory, is the last thing necessary.
|
||||||
|
|
||||||
|
i.e.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[test]
|
||||||
|
pub fn parser_tests() {
|
||||||
|
// The second argument indicates the directory where tests(.leo files)
|
||||||
|
// would be found(tests/parser).
|
||||||
|
leo_test_framework::run_tests(&ParseTestRunner, "parser");
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Clearing Expectations
|
||||||
|
|
||||||
|
To do so you can simply remove the corresponding `.out` file in the `tests/expectations` directory. Doing so will cause the output to be regenerated. There is an easier way to mass change them as well discussed in the next section.
|
||||||
|
|
||||||
|
### Test Framework Environment Variables
|
||||||
|
|
||||||
|
To make several aspects of the test framework easier to work with there are several environment variables:
|
||||||
|
|
||||||
|
- `TEST_FILTER` - runs all tests that contain the specified name.
|
||||||
|
- `CLEAR_LEO_TEST_EXPECTATIONS` - which if set clears all current expectations and regenerates them all.
|
||||||
|
|
||||||
|
To set environment variables please look at your Shell(bash/powershell/cmd/fish/etc) specific implementation for doing so
|
||||||
|
|
||||||
|
**NOTE**: Don't forget to clear the environment variable after running it with that setting, or set a temporary env variable if your shell supports it.
|
@ -22,6 +22,7 @@
|
|||||||
//! To regenerate the tests after a syntax change or failing test, delete the [`tests/expectations/`]
|
//! To regenerate the tests after a syntax change or failing test, delete the [`tests/expectations/`]
|
||||||
//! directory and run the [`parser_tests()`] test in [`parser/src/test.rs`].
|
//! directory and run the [`parser_tests()`] test in [`parser/src/test.rs`].
|
||||||
|
|
||||||
|
#![cfg(not(doctest))] // Don't doctest the markdown.
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
Loading…
Reference in New Issue
Block a user