Merge pull request #41 from chriseth/more_operators

More operators.
This commit is contained in:
chriseth
2023-02-15 21:35:03 +01:00
committed by GitHub
8 changed files with 127 additions and 2 deletions

View File

@@ -611,7 +611,10 @@ impl Context {
let old_locals = std::mem::take(&mut self.local_variables);
let mac = &self.macros[name];
let mac = &self
.macros
.get(name)
.unwrap_or_else(|| panic!("Macro {name} not found."));
self.local_variables = mac
.parameters
.iter()
@@ -681,6 +684,11 @@ impl Context {
assert!(right <= u32::MAX.into());
left.pow(right as u32)
}
BinaryOperator::Mod => left % right,
BinaryOperator::BinaryAnd => left & right,
BinaryOperator::BinaryOr => left | right,
BinaryOperator::ShiftLeft => left << right,
BinaryOperator::ShiftRight => left >> right,
})
} else {
None

View File

@@ -196,6 +196,27 @@ impl<'a> Evaluator<'a> {
None
}
}
BinaryOperator::Mod
| BinaryOperator::BinaryAnd
| BinaryOperator::BinaryOr
| BinaryOperator::ShiftLeft
| BinaryOperator::ShiftRight => {
if let (Some(left), Some(right)) =
(left.constant_value(), right.constant_value())
{
let result = match op {
BinaryOperator::Mod => left % right,
BinaryOperator::BinaryAnd => left & right,
BinaryOperator::BinaryOr => left | right,
BinaryOperator::ShiftLeft => left << right,
BinaryOperator::ShiftRight => left >> right,
_ => panic!(),
};
Some(result.into())
} else {
panic!()
}
}
}
} else {
None

View File

@@ -87,6 +87,11 @@ impl<'a> Evaluator<'a> {
assert!(right <= u32::MAX.into());
left.pow(right as u32)
}
BinaryOperator::Mod => left % right,
BinaryOperator::BinaryAnd => left & right,
BinaryOperator::BinaryOr => left | right,
BinaryOperator::ShiftLeft => left << right,
BinaryOperator::ShiftRight => left >> right,
}
}

View File

@@ -263,6 +263,13 @@ impl<'a> Exporter<'a> {
);
("pow", deg_left + deg_right)
}
BinaryOperator::Mod
| BinaryOperator::BinaryAnd
| BinaryOperator::BinaryOr
| BinaryOperator::ShiftLeft
| BinaryOperator::ShiftRight => {
panic!("Operator {op:?} not supported on polynomials.")
}
};
(
degree,

View File

@@ -74,5 +74,10 @@ pub enum BinaryOperator {
Sub,
Mul,
Div,
Mod,
Pow,
BinaryAnd,
BinaryOr,
ShiftLeft,
ShiftRight,
}

View File

@@ -129,7 +129,39 @@ Expression: Expression = {
}
BoxedExpression: Box<Expression> = {
BoxedExpression SumOp Product => Box::new(Expression::BinaryOperation(<>)),
BinaryOr
}
BinaryOr: Box<Expression> = {
BinaryOr BinaryOrOp BinaryAnd => Box::new(Expression::BinaryOperation(<>)),
BinaryAnd,
}
BinaryOrOp: BinaryOperator = {
"|" => BinaryOperator::BinaryOr,
}
BinaryAnd: Box<Expression> = {
BinaryAnd BinaryAndOp BitShift => Box::new(Expression::BinaryOperation(<>)),
BitShift,
}
BinaryAndOp: BinaryOperator = {
"&" => BinaryOperator::BinaryAnd,
}
BitShift: Box<Expression> = {
BitShift BitShiftOp Sum => Box::new(Expression::BinaryOperation(<>)),
Sum,
}
BitShiftOp: BinaryOperator = {
"<<" => BinaryOperator::ShiftLeft,
">>" => BinaryOperator::ShiftRight,
}
Sum: Box<Expression> = {
Sum SumOp Product => Box::new(Expression::BinaryOperation(<>)),
Product,
}
@@ -146,6 +178,7 @@ Product: Box<Expression> = {
ProductOp: BinaryOperator = {
"*" => BinaryOperator::Mul,
"/" => BinaryOperator::Div,
"%" => BinaryOperator::Mod,
}
Power: Box<Expression> = {

41
tests/global.pil Normal file
View File

@@ -0,0 +1,41 @@
/*
* LICENSE WARNING
*
* These files are from the [polygon-hermez zkEVM project](https://github.com/0xPolygonHermez/zkevm-proverjs)
* and were developed by Polygon. They are not covered by the MIT license of this repository.
* All rights reserved by Polygon.
*/
constant %N = 2**20;
namespace Global(%N);
macro is_nonzero(X) { X / X }; // 0 / 0 == 0 makes this work...
macro is_zero(X) { 1 - is_nonzero(X) };
macro is_equal(A, B) { is_zero(A - B) };
macro is_one(X) { is_equal(X, 1) };
macro ite(C, A, B) { is_nonzero(C) * A + is_zero(C) * B};
macro one_hot(i, index) { ite(is_equal(i, index), 1, 0) };
col fixed L1(i) { one_hot(i, 0) };
col fixed LLAST(i) { one_hot(i, %N - 1) };
col fixed BYTE(i) { i & 0xff };
col fixed BYTE2(i) { i & 0xffff };
// col fixed BYTE_2A(i) { BYTE2(i) >> 8 };
col fixed BYTE_2A(i) { (i & 0xffff) >> 8 };
// TODO it might be confusing to remember which one is the array index
// and which one is the polynomial parameter.
// Here, k is the array index and i is the polynomial parameter.
// TODO
//col fixed CLK32[32](k, i) { one_hot(i, i % 32 == k) };
// TODO
// col fixed BYTE_FACTOR[8](k i) { ((i >> 2) & 0x07) == index ? [1n, 256n, 256n**2n, 256n**3n][i % 4]:0n };
// [0] = 1,256,256**2,256**3, 0:28 (cyclic)
// [1] = 0:4, 1,256,256**2,256**3, 0:24 (cyclic)
// [7] = 0:28, 1,256,256**2,256**3 (cyclic)
col fixed STEP(i) { i }; // 0, 1, 2, 3, ...... N-1
col fixed STEP32(i) { i % 32 };

View File

@@ -42,3 +42,8 @@ fn test_fibonacci() {
fn test_fibonacci_macro() {
verify("fib_macro.pil");
}
#[test]
fn test_global() {
verify("global.pil");
}