Skip to content

Commit

Permalink
Merge pull request #13 from distributed-lab/feature/parenthesis
Browse files Browse the repository at this point in the history
Add support for parentheses and QUO operation
  • Loading branch information
Arvolear authored Dec 25, 2024
2 parents b426bac + 9f8d106 commit 2b0ab23
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 7 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@distributedlab/circom-parser",
"description": "Circom circuit parser built with ANTLR4",
"version": "0.2.4",
"version": "0.2.5",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
Expand Down
13 changes: 9 additions & 4 deletions src/utils/ExpressionHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,13 @@ class ExpressionVisitor extends ExtendedCircomVisitor<CircomValueType | null> {
};

visitPParentheses = (ctx: PParenthesesContext): CircomValueType | null => {
this.addError("Parentheses are not supported", ctx);
return null;
let expressions = ctx.expressionList().expression_list();
if (expressions.length !== 1) {
this.addError("Parentheses can only contain one expression", ctx);
return null;
}

return this.visit(expressions[0]);
};

visitPArray = (ctx: PArrayContext): CircomValueType | null => {
Expand Down Expand Up @@ -283,8 +288,8 @@ class ExpressionVisitor extends ExtendedCircomVisitor<CircomValueType | null> {
case CircomParser.DIV:
return firstExpression / secondExpression;
case CircomParser.QUO:
this.addError("QUO operation is not supported", ctx);
return null;
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division
return firstExpression / secondExpression;
case CircomParser.MOD:
return firstExpression % secondExpression;
case CircomParser.ADD:
Expand Down
40 changes: 40 additions & 0 deletions test/circom-template-inputs-visitor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,44 @@ describe("Circom Template Inputs Visitor", () => {
expect(visitor.templateInputs.out.type).to.equal("output");
expect(visitor.templateInputs.out.dimension).to.deep.equal([2, 4]);
});

it("should analyse the Math.circom circuit", () => {
const data = getData("Math.circom");

const visitor = new CircomTemplateInputsVisitor(
"Math.circom",
data.templates[data.mainComponentInfo.templateName!].context,
buildVariableContext(
data.templates[data.mainComponentInfo.templateName!].parameters,
data.mainComponentInfo.parameters,
),
);

visitor.startParse();

expect(visitor.errors.length).to.equal(0);

expect(visitor.templateInputs.out1.type).to.equal("output");
expect(visitor.templateInputs.out1.dimension).to.deep.equal([13]);

expect(visitor.templateInputs.out2.type).to.equal("output");
expect(visitor.templateInputs.out2.dimension).to.deep.equal([16]);

expect(visitor.templateInputs.tmp1.type).to.equal("intermediate");
expect(visitor.templateInputs.tmp1.dimension).to.deep.equal([6, 8, 2, 20]);

expect(visitor.templateInputs.tmp2.type).to.equal("intermediate");
expect(visitor.templateInputs.tmp2.dimension).to.deep.equal([6, 2, 20]);

expect(visitor.templateInputs.tmp3.type).to.equal("intermediate");
expect(visitor.templateInputs.tmp3.dimension).to.deep.equal([6, 2, 2, 20]);

expect(visitor.templateInputs.tmp4.type).to.equal("intermediate");
expect(visitor.templateInputs.tmp4.dimension).to.deep.equal([5, 2, 2, 20]);

expect(visitor.templateInputs.powers.type).to.equal("intermediate");
expect(visitor.templateInputs.powers.dimension).to.deep.equal([
2, 256, 2, 6,
]);
});
});
24 changes: 24 additions & 0 deletions test/data/Math.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
pragma circom 2.1.6;

template Math(a, b, c) {
var input1 = (a + b) / 2;
var input2 = a + b / 2;

var PRECOMPUTE_NUMBER = 2 ** c;

signal tmp1 [a][PRECOMPUTE_NUMBER][2][b];

var STRIDE = 8;
var parts = a * c \ STRIDE;

signal tmp2[a] [2] [b];
signal tmp3[a] [2][2][b];
signal tmp4[a - 1][2][2][b];

signal powers[parts][2 ** STRIDE][2][a];

signal output out1[input1];
signal output out2[input2];
}

component main = Math(6, 20, 3);

0 comments on commit 2b0ab23

Please sign in to comment.