Skip to content

Commit

Permalink
test: add more tests for edge cases for const parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
tohrnii committed Dec 3, 2022
1 parent 2e43644 commit c1b9bd0
Show file tree
Hide file tree
Showing 14 changed files with 229 additions and 92 deletions.
4 changes: 2 additions & 2 deletions codegen/winterfell/src/air/boundary_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl Codegen for BoundaryExpr {
format!("Felt::new({})", value)
}
}
Self::VecElem(vector_access) => {
Self::VectorAccess(vector_access) => {
format!("self.{}[{}]", vector_access.name(), vector_access.idx())
}
Self::Rand(index) => {
Expand Down Expand Up @@ -133,7 +133,7 @@ impl Codegen for BoundaryExpr {
Self::Exp(lhs, rhs) => {
format!("({}).exp({})", lhs.to_string(is_aux_constraint), rhs)
}
BoundaryExpr::Elem(_) | BoundaryExpr::MatrixElem(_) => todo!(),
BoundaryExpr::Elem(_) | BoundaryExpr::MatrixAccess(_) => todo!(),
}
}
}
4 changes: 2 additions & 2 deletions ir/src/boundary_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ fn validate_expression(
expr: &ast::BoundaryExpr,
) -> Result<(), SemanticError> {
match expr {
BoundaryExpr::VecElem(vector_access) => {
symbol_table.validate_public_input(vector_access.name(), vector_access.idx() as usize)
BoundaryExpr::VectorAccess(vector_access) => {
symbol_table.validate_public_input(vector_access.name(), vector_access.idx())
}
BoundaryExpr::Add(lhs, rhs) | BoundaryExpr::Sub(lhs, rhs) => {
validate_expression(symbol_table, lhs)?;
Expand Down
2 changes: 1 addition & 1 deletion ir/src/transition_constraints/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl AlgebraicGraph {
let node_index = self.insert_op(Operation::Exp(lhs, rhs as usize));
Ok((constraint_type, node_index))
}
TransitionExpr::VecElem(_) | TransitionExpr::MatrixElem(_) => todo!(),
TransitionExpr::VectorAccess(_) | TransitionExpr::MatrixAccess(_) => todo!(),
}
}

Expand Down
12 changes: 6 additions & 6 deletions parser/src/ast/boundary_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ pub enum BoundaryExpr {
Const(u64),
/// Represents any named constant or variable.
Elem(Identifier),
/// Represents an element inside a constant or variable vector. The index is the index of
/// this value inside the vector.
VecElem(VectorAccess),
/// Represents an element inside a constant or variable matrix. Indices idx_row and idx_col
/// are the indices of this value inside the matrix.
MatrixElem(MatrixAccess),
/// Represents an element inside a constant or variable vector. [VectorAccess] contains the
/// name of the vector and the index of the element to access.
VectorAccess(VectorAccess),
/// Represents an element inside a constant or variable matrix. [MatrixAccess] contains the
/// name of the matrix and indices of the element to access.
MatrixAccess(MatrixAccess),
/// Represents a random value provided by the verifier. The inner value is the index of this
/// random value in the array of all random values.
Rand(usize),
Expand Down
42 changes: 28 additions & 14 deletions parser/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ pub struct TraceCols {
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct Identifier(pub String);

impl Identifier {
/// Returns the name of the identifier.
pub fn name(&self) -> &str {
&self.0
}
}

impl fmt::Display for Identifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", &self.0)
Expand All @@ -74,50 +81,57 @@ impl fmt::Display for Identifier {
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct VectorAccess {
name: Identifier,
idx: u64,
idx: usize,
}

impl VectorAccess {
pub fn new(name: Identifier, idx: u64) -> Self {
/// Creates a new [VectorAccess] instance with the specified identifier name and index.
pub fn new(name: Identifier, idx: usize) -> Self {
Self { name, idx }
}

/// Returns the name of the vector.
pub fn name(&self) -> &str {
&self.name.0
self.name.name()
}

pub fn idx(&self) -> u64 {
/// Returns the index of the vector access.
pub fn idx(&self) -> usize {
self.idx
}
}

/// [MatrixAccess] is used to represent an element inside vector at the specified row and column
/// [MatrixAccess] is used to represent an element inside a matrix at the specified row and column
/// indices.
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct MatrixAccess {
name: Identifier,
col_idx: u64,
row_idx: u64,
row_idx: usize,
col_idx: usize,
}

impl MatrixAccess {
pub fn new(name: Identifier, col_idx: u64, row_idx: u64) -> Self {
/// Creates a new [MatrixAccess] instance with the specified identifier name and indices.
pub fn new(name: Identifier, col_idx: usize, row_idx: usize) -> Self {
Self {
name,
col_idx,
row_idx,
col_idx,
}
}

/// Returns the name of the matrix.
pub fn name(&self) -> &str {
&self.name.0
self.name.name()
}

pub fn col_idx(&self) -> u64 {
self.col_idx
/// Returns the row index of the matrix access.
pub fn row_idx(&self) -> usize {
self.row_idx
}

pub fn row_idx(&self) -> u64 {
self.row_idx
/// Returns the column index of the matrix access.
pub fn col_idx(&self) -> usize {
self.col_idx
}
}
9 changes: 7 additions & 2 deletions parser/src/ast/transition_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ impl TransitionConstraint {
#[derive(Debug, PartialEq, Clone)]
pub enum TransitionExpr {
Const(u64),
/// Represents any named constant or variable.
Elem(Identifier),
VecElem(VectorAccess),
MatrixElem(MatrixAccess),
/// Represents an element inside a constant or variable vector. [VectorAccess] contains the
/// name of the vector and the index of the element to access.
VectorAccess(VectorAccess),
/// Represents an element inside a constant or variable matrix. [MatrixAccess] contains the
/// name of the matrix and indices of the element to access.
MatrixAccess(MatrixAccess),
Next(Identifier),
/// Represents a random value provided by the verifier. The inner value is the index of this
/// random value in the array of all random values.
Expand Down
2 changes: 1 addition & 1 deletion parser/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ pub enum ParseError {
InvalidInt(String),
InvalidTraceCols(String),
MissingMainTraceCols(String),
LowercaseConstName(String),
InvalidConst(String),
}
101 changes: 84 additions & 17 deletions parser/src/lexer/tests/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ use super::{expect_valid_tokenization, Token};
fn constants_scalar() {
let source = "
constants:
a: 1
b: 2";
A: 1
B: 2";

let tokens = vec![
Token::Constants,
Token::Colon,
Token::Ident("a".to_string()),
Token::Ident("A".to_string()),
Token::Colon,
Token::Num("1".to_string()),
Token::Ident("b".to_string()),
Token::Ident("B".to_string()),
Token::Colon,
Token::Num("2".to_string()),
];
Expand All @@ -24,13 +24,13 @@ constants:
fn constants_vector() {
let source = "
constants:
a: [1, 2, 3, 4]
b: [5, 6, 7, 8]";
A: [1, 2, 3, 4]
B: [5, 6, 7, 8]";

let tokens = vec![
Token::Constants,
Token::Colon,
Token::Ident("a".to_string()),
Token::Ident("A".to_string()),
Token::Colon,
Token::Lsqb,
Token::Num("1".to_string()),
Expand All @@ -41,7 +41,7 @@ constants:
Token::Comma,
Token::Num("4".to_string()),
Token::Rsqb,
Token::Ident("b".to_string()),
Token::Ident("B".to_string()),
Token::Colon,
Token::Lsqb,
Token::Num("5".to_string()),
Expand All @@ -60,13 +60,13 @@ constants:
fn constants_matrix() {
let source = "
constants:
a: [[1, 2], [3, 4]]
b: [[5, 6], [7, 8]]";
A: [[1, 2], [3, 4]]
B: [[5, 6], [7, 8]]";

let tokens = vec![
Token::Constants,
Token::Colon,
Token::Ident("a".to_string()),
Token::Ident("A".to_string()),
Token::Colon,
Token::Lsqb,
Token::Lsqb,
Expand All @@ -81,7 +81,7 @@ fn constants_matrix() {
Token::Num("4".to_string()),
Token::Rsqb,
Token::Rsqb,
Token::Ident("b".to_string()),
Token::Ident("B".to_string()),
Token::Colon,
Token::Lsqb,
Token::Lsqb,
Expand All @@ -102,10 +102,12 @@ fn constants_matrix() {

#[test]
fn constants_access_inside_boundary_expr() {
// This is invalid since the constants are not declared but this error will be thrown at the
// IR level.
let source = "
boundary_constraints:
enf clk.first = a + b[0]
enf clk.last = c[0][1]
enf clk.first = A + B[0]
enf clk.last = C[0][1]
";

let tokens = vec![
Expand All @@ -116,9 +118,9 @@ fn constants_access_inside_boundary_expr() {
Token::Dot,
Token::First,
Token::Equal,
Token::Ident("a".to_string()),
Token::Ident("A".to_string()),
Token::Plus,
Token::Ident("b".to_string()),
Token::Ident("B".to_string()),
Token::Lsqb,
Token::Num("0".to_string()),
Token::Rsqb,
Expand All @@ -127,7 +129,7 @@ fn constants_access_inside_boundary_expr() {
Token::Dot,
Token::Last,
Token::Equal,
Token::Ident("c".to_string()),
Token::Ident("C".to_string()),
Token::Lsqb,
Token::Num("0".to_string()),
Token::Rsqb,
Expand All @@ -140,6 +142,71 @@ fn constants_access_inside_boundary_expr() {

#[test]
fn constants_access_inside_transition_expr() {
let source = "
constants:
A: 1
B: [1, 0]
C: [[1, 0], [0, 1]]
transition_constraints:
enf clk * 2^A = B[0] + C[0][1]
";
let tokens = vec![
Token::Constants,
Token::Colon,
Token::Ident("A".to_string()),
Token::Colon,
Token::Num("1".to_string()),
Token::Ident("B".to_string()),
Token::Colon,
Token::Lsqb,
Token::Num("1".to_string()),
Token::Comma,
Token::Num("0".to_string()),
Token::Rsqb,
Token::Ident("C".to_string()),
Token::Colon,
Token::Lsqb,
Token::Lsqb,
Token::Num("1".to_string()),
Token::Comma,
Token::Num("0".to_string()),
Token::Rsqb,
Token::Comma,
Token::Lsqb,
Token::Num("0".to_string()),
Token::Comma,
Token::Num("1".to_string()),
Token::Rsqb,
Token::Rsqb,
Token::TransitionConstraints,
Token::Colon,
Token::Enf,
Token::Ident("clk".to_string()),
Token::Mul,
Token::Num("2".to_string()),
Token::Exp,
Token::Ident("A".to_string()),
Token::Equal,
Token::Ident("B".to_string()),
Token::Lsqb,
Token::Num("0".to_string()),
Token::Rsqb,
Token::Plus,
Token::Ident("C".to_string()),
Token::Lsqb,
Token::Num("0".to_string()),
Token::Rsqb,
Token::Lsqb,
Token::Num("1".to_string()),
Token::Rsqb,
];
expect_valid_tokenization(source, tokens);
}

#[test]
fn constants_access_inside_transition_expr_invalid() {
// This is invalid since the constants are not declared and the constant names should be
// capitalized but these errors will be thrown at the IR level and parsing level respectively.
let source = "
transition_constraints:
enf clk * 2^a = b[0] + c[0][1]
Expand Down
Loading

0 comments on commit c1b9bd0

Please sign in to comment.