Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/pil2 expression refactoring #63

Draft
wants to merge 38 commits into
base: feature/pil2
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
21e832d
WIP expressions refactoring
zkronos73 Aug 1, 2023
74a9c2a
Merge branch 'feature/pil2'
zkronos73 Aug 3, 2023
b9e98ea
WIP - refactoring expressions
zkronos73 Aug 4, 2023
a6028e6
Merge branch 'feature/pil2'
zkronos73 Aug 4, 2023
6ca4442
WIP
zkronos73 Aug 5, 2023
b757b4b
WIP - refactoring expressions
zkronos73 Aug 7, 2023
ed20bc5
WIP - refactoring expressions
zkronos73 Aug 8, 2023
4e0ae6b
WIP
zkronos73 Aug 9, 2023
997949b
WIP - removing invalid code
zkronos73 Aug 10, 2023
a99748b
Merge branch 'feature/pil2' to feature/pil2-expression-refactoring
zkronos73 Aug 14, 2023
018da3e
WIP - refactoring expression items and definitions
zkronos73 Sep 2, 2023
6b2f5bc
Merge branch 'feature/pil2' of into feature/pil2-expression-refactoring
zkronos73 Sep 15, 2023
d063c73
WIP refactoring
zkronos73 Sep 19, 2023
33b5b32
WIP operators and casting
zkronos73 Sep 19, 2023
db2a833
adding more Exceptions and cast conversions
zkronos73 Sep 20, 2023
752ca07
WIP expressions
zkronos73 Sep 21, 2023
d4626f7
WIP
zkronos73 Sep 24, 2023
03356c0
WIP refactoring and testing
zkronos73 Oct 1, 2023
8f6c89a
WIP const expressions and integers
zkronos73 Oct 2, 2023
e720a83
some fixs to be compatible with previous version of pil2
zkronos73 Oct 3, 2023
c9e5ebf
fix some bugs on pilout
zkronos73 Oct 3, 2023
e01e53f
fix rowOffset on pilout
zkronos73 Oct 3, 2023
eaf2de7
WIP
zkronos73 Oct 18, 2023
0b4d025
WIP
zkronos73 Oct 25, 2023
92845d8
WIP pending finals and pilout errors
zkronos73 Nov 2, 2023
5864a08
WIP, continue testing std
zkronos73 Nov 7, 2023
8c25209
Merge feature/pil2 into feature/pil2-expression-refactoring
zkronos73 Nov 7, 2023
3499539
WIP debugging pilout generation
zkronos73 Nov 7, 2023
2ada145
fix bugs on pilout generation
zkronos73 Nov 10, 2023
be0d73f
WIP - translating etrog to pil2
zkronos73 Jan 4, 2024
11310d3
WIP zkevm-etrog
zkronos73 Jan 30, 2024
f09d001
WIP
zkronos73 Feb 1, 2024
41feddf
WIP pil2
zkronos73 Feb 6, 2024
4c15860
WIP
zkronos73 Feb 19, 2024
d2a5cb4
clean obsolete pils, add README with pil info and fix some compilers …
zkronos73 Feb 21, 2024
1d33f9b
WIP in speedup sequences
zkronos73 Feb 25, 2024
0b8e901
WIP - feature switch-case supported
zkronos73 Feb 26, 2024
98696ff
WIP
zkronos73 Feb 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
838 changes: 441 additions & 397 deletions build/pil_parser.js

Large diffs are not rendered by default.

21 changes: 19 additions & 2 deletions docs/expression.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ And next?
|fe||
|col witness||
|col fixed||
|col (im)||
|expression||
|challenge||
|public||
|air value||
Expand All @@ -25,4 +25,21 @@ And next?
- **instance()** make a copy of expression, where __runtime values and expressions__ (variables, eq, be) are replaced
- **evaluate()** calculate a single value (int, fe, bool) without replacing runtime values and expressions. For example, a condition on loop, etc..


```mermaid
classDiagram
ExpressionItem <-- RuntimeItem
ExpressionItem <-- ProofItem
RuntimeItem <-- ReferenceItem
RuntimeItem <-- ExpressionReference
RuntimeItem <-- ValueItem
RuntimeItem <-- StringValue
RuntimeItem <-- FunctionCall
ProofItem <-- Challenge
ProofItem <-- ProofVal
ProofItem <-- FixedCol
ProofItem <-- WitnessCol
ProofItem <-- Public
ProofItem <-- SubproofVal
ValueItem <-- IntValue
ValueItem <-- FeValue
``````
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@
"homepage": "https://github.com/0xpolygonhermez/pilcom#readme",
"devDependencies": {
"chai": "^4.3.6",
"fastfile": "^0.0.20",
"ffjavascript": "^0.2.55",
"jison": "^0.4.18",
"mocha": "^10.0.0",
"nyc": "^15.1.0",
"tmp-promise": "^3.0.3",
"yargs": "^17.2.1",
"fastfile": "^0.0.20"
"yargs": "^17.2.1"
},
"dependencies": {
"deep-equal-in-any-order": "^2.0.6",
"lodash": "^4.17.21",
"long": "^5.2.3",
"protobufjs": "^7.2.3"
Expand Down
5 changes: 5 additions & 0 deletions src/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# TODO
- specifics Exception Class to manage compiler (user) errors and internal errors.
- static context value, to avoid pass on all constructors. Add Fr manager inside context, same for scope and references.
- typecast and type verification.
- second level of optimizations, for example: v1 + (v2 + col) => (v1+v2) + col, similar for prod, sub, etc..
18 changes: 18 additions & 0 deletions src/assert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const _assert = require("chai").assert;

function assertLog(condition, info) {
if (!condition) {
console.log(info);
}
_assert(condition);
}

function assertReturnInstanceOf(value, cls, info) {
assertLog(value instanceof cls, [value, info]);
return value;
}
module.exports = {
assert: _assert,
assertLog,
assertReturnInstanceOf
}
74 changes: 42 additions & 32 deletions src/assign.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@
const References = require("./references.js");
const Expressions = require("./expressions.js");
const Expression = require("./expression.js");
const Context = require('./context.js');
const {assert, assertLog} = require('./assert.js');
const NonRuntimeEvaluableItem = require('./expression_items/non_runtime_evaluable_item.js');
const Debug = require('./debug.js');

module.exports = class Assign {
constructor (Fr, parent, context, references, expressions) {
this.Fr = Fr;
this.context = context;
this.references = references;
this.expressions = expressions;
this.parent = parent;
constructor () {
}

assign (name, indexes, value) {
// console.log(value.stack[0].operands[0]);
if (Debug.active) console.log(value);
value = this.getValue(value);
if (Debug.active) console.log(value);
assert(value !== null);
return this.#assign(name, indexes, value);
}
getValue(value) {
const _value = value.eval();
if (typeof _value !== 'undefined') {
value = _value;
if (typeof _value !== 'undefined' && _value !== null && (_value instanceof NonRuntimeEvaluableItem) === false) {
return _value;
}
return this.__assign(name, indexes, value);
return value;
}
__assign(name, indexes, value) {
const [type, reference, array] = this.references.getTypeR(name, indexes);
const dim = (array && array.dim) ? array.dim : 0;
if (this.parent.context.sourceRef === 'assigns.pil:115') {
debugger;
}
#assign (name, indexes, value) {
// console.log(`ASSIGN(${name})[#${indexes.length ?? 0}] = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`);
// const array = Context.references.getArray(name, indexes);
const reference = Context.references.getReference(name);
return reference.set(value, indexes);
/*
const dim = array.dim ?? 0;
if (dim > 0) {
// array asignation as array or subarray copy
return this.assignArray(name, indexes, value, array);
}
// console.log([name, type, reference, array]);
return this.assignType(type, name, indexes, value);
console.log(value);
return Context.references.set(name, indexes, value);*/
}
assignType(type, name, indexes, value) {
if (Debug.active) console.log(type);
switch (type) {
case 'int': return this.assignTypeInt(name, indexes, value, type);
case 'expr': return this.assignTypeExpr(name, indexes, value, type);
}
}
assignArray(name, indexes, value, array) {
console.log(`ASSIGN_ARRAY(${name})[#${indexes.length ?? 0}] = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`);
const ref = value.getAloneOperand();
let valueIndexes = value.__indexes ?? [];
const def = this.references.getDefinition(ref.name);
const def = Context.references.getDefinition(ref.name);

if (array.dim != def.array.dim) {
throw new Error(`different array dimension on asignation ${array.dim} vs ${def.array.dim}`);
Expand All @@ -49,39 +55,43 @@ module.exports = class Assign {
// array.lengths[0] != def.array.lengths[0]) {
}
assignArrayLevel(level, name, indexes, value, leftArray, rightArray) {
console.log(`ASSIGN_ARRAY_LEVEL(${level},${name})[#${indexes.length ?? 0}] = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`);
// console.log(['assignArrayLevel', level, name, indexes]);
const len = leftArray.lengths[level];
for (let index = 0; index < len; ++index) {
let _indexes = [...indexes];
_indexes.push(index);
value.pushAloneIndex(index);
if (level + 1 === leftArray.dim) {
this.__assign(name, _indexes, value.evaluateAloneReference());
this.#assign(name, _indexes, value.evaluateAloneReference());
} else {
this.assignArrayLevel(level+1, name, _indexes, value, leftArray, rightArray);
}
value.popAloneIndex();
}
}
assignReference (name, value) {
this.references.setReference(name, value);
console.log(`ASSIGN_REFERENCE(${level},${name}) = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`);
Context.references.setReference(name, value);
}
assignTypeInt(name, indexes, value, type) {
// TODO: WARNING: e2value an extra evaluation
const v = this.expressions.getValue(value);
const v = Expression.getValue(value);
if (typeof v === 'number' || typeof v === 'bigint') {
return this.references.set(name, indexes, v);
return Context.references.set(name, indexes, v);
}
}
assignTypeExpr(name, indexes, value, type) {
console.log(`ASSIGN_TYPE_EXPR(${name},${type})[#${indexes.length ?? 0}] = ${value.constructor ? (value.constructor.name ?? typeof value):typeof value}`);
if (!(value instanceof Expression)) {
this.references.set(name, indexes, value);
Context.references.set(name, indexes, value);
return;
}
value = value.instance({simplify: true});

console.log(`ASSIGN ${this.context.sourceRef} ${value}`);
this.references.set(name, indexes, value);
return
value = value.instance(true);
if (Context.sourceRef === 'std_sum.pil:195') {
if (Debug.active) console.log('XXX');
}
if (Debug.active) console.log(`ASSIGN ${Context.sourceRef} ${value}`);
Context.references.set(name, indexes, value);
}
}
14 changes: 10 additions & 4 deletions src/builtin/assert.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
const Function = require("../function.js");
const Context = require('../context.js');
const ExpressionItems = require('../expression_items.js')
module.exports = class Assert extends Function {
constructor (parent) {
super(parent, {funcname: 'assert'});
}
mapArguments(s) {
if (s.arguments.length !== 1) {
console.log('############### ASSERT (prepare) ########################');
console.log(s.args);
if (s.args.length !== 1) {
throw new Error('Invalid number of parameters');
}
const arg0 = this.expressions.e2bool(s.arguments[0]);
const arg0 = s.args[0].asBool();
console.log(arg0);
if (!arg0) {
throw new Error(`Assert fails ${arg0} on ${this.parent.sourceRef}`);
throw new Error(`Assert fails ${arg0} on ${Context.sourceRef}`);
}
return 0n;
return new ExpressionItems.IntValue(0n);
}
exec(s, mapInfo) {
console.log('############### ASSERT (exec) ########################');
return mapInfo;
}
}
24 changes: 16 additions & 8 deletions src/builtin/assert_eq.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
const Function = require("../function.js");
const Expression = require('../expression.js');
const Context = require('../context.js');
const IntValue = require('../expression_items/int_value.js');
const {assert, assertLog} = require('../assert.js');
module.exports = class AssertEq extends Function {
constructor (parent) {
super(parent, {funcname: 'assert_eq'});
constructor () {
super(999999, {funcname: 'assert_eq'});
}
mapArguments(s) {
if (s.arguments.length !== 2) {
if (s.args.length !== 2) {
throw new Error('Invalid number of parameters');
}
const arg0 = this.expressions.e2value(s.arguments[0]);
const arg1 = this.expressions.e2value(s.arguments[1]);
if (arg0 !== arg1) {
throw new Error(`Assert fails (${arg0} === ${arg1}) on ${this.parent.sourceRef}`);
assert(s.args[0] instanceof Expression);
assert(s.args[1] instanceof Expression);
const arg0 = s.args[0].eval();
const arg1 = s.args[1].eval();
console.log(arg0);
console.log(arg1);
if (!arg0.equals(arg1)) {
throw new Error(`Assert fails (${arg0} === ${arg1}) on ${Context.sourceRef}`);
}
return 0n;
}
exec(s, mapInfo) {
return mapInfo;
return new IntValue(mapInfo);
}
}
10 changes: 6 additions & 4 deletions src/builtin/assert_not_eq.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
const Function = require("../function.js");
const IntValue = require('../expression_items/int_value.js');

module.exports = class AssertNotEq extends Function {
constructor (parent) {
super(parent, {funcname: 'assert_not_eq'});
}
mapArguments(s) {
if (s.arguments.length !== 2) {
if (s.args.length !== 2) {
throw new Error('Invalid number of parameters');
}
const arg0 = this.expressions.e2value(s.arguments[0]);
const arg1 = this.expressions.e2value(s.arguments[1]);
const arg0 = this.expressions.e2value(s.args[0]);
const arg1 = this.expressions.e2value(s.args[1]);
if (arg0 === arg1) {
throw new Error(`Assert fails (${arg0} !== ${arg1}) on ${this.parent.sourceRef}`);
}
return 0n;
}
exec(s, mapInfo) {
return mapInfo;
return new IntValue(mapInfo);
}

}
37 changes: 37 additions & 0 deletions src/builtin/cast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const Function = require("../function.js");
const Context = require('../context.js');
const Expression = require('../expression.js');

module.exports = class Cast extends Function {
constructor (parent) {
super(parent, {funcname: 'cast'});
}
mapArguments(s) {
console.log('############### CAST (prepare) ########################');
console.log(s.args);
if (s.args.length !== 2) {
throw new Error('Invalid number of parameters');
}
if (typeof s.args[0] !== 'string') {
throw new Error('Invalid type of cast');
}
const cast = s.args[0];
let arg1 = s.args[1] instanceof Expression ? s.args[1].eval() : s.args[1];
console.log(arg1, arg1.isBaseType, typeof arg1.asStringItem);
if (arg1 instanceof Expression) {
arg1.dump();
arg1 = arg1.eval();
}
switch (cast) {
case 'string':
if (arg1.isBaseType && typeof arg1.asStringItem === 'function') {
return arg1.asStringItem();
}
}
EXIT_HERE;
}
exec(s, mapInfo) {
console.log('############### CAST (exec) ########################', mapInfo);
return mapInfo;
}
}
30 changes: 22 additions & 8 deletions src/builtin/defined.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
const Function = require("../function.js");
const {MultiArray, ErrorIndexOutOfRange} = require("../multi_array.js");
const MultiArray = require("../multi_array.js");
const {IntValue} = require('../expression_items.js');
const Exceptions = require('../exceptions.js');

module.exports = class Defined extends Function {
constructor (parent) {
super(parent, {funcname: 'defined'});
}
mapArguments(s) {
if (s.arguments.length !== 1) {
if (s.args.length !== 1) {
throw new Error('Invalid number of parameters');
}
const arg0 = s.arguments[0];
if (arg0 && arg0.isReference()) {
const ref = arg0.getReference();
// console.log(ref);
return this.references.isDefined(ref.name, ref.__indexes) ? 1n : 0n;
const arg0 = s.args[0];
let value = false;
try {
if (arg0) {
value = arg0.eval();
}
// if (arg0 && arg0.isReference()) {
// const ref = arg0.getReference();
// return this.references.isDefined(ref.name, ref.__indexes) ? 1n : 0n;
// }
} catch (e) {
if (e instanceof Exceptions.ReferenceNotFound || e instanceof Exceptions.ReferenceNotVisible) {
console.log(`defined(${arg0.toString()}) EXCEPTION `, e.message);
} else {
throw e;
}
}
return 0n;
const res = new IntValue(value !== false ? 1n : 0n);
return res;
}
exec(s, mapInfo) {
return mapInfo;
Expand Down
Loading