arnaucube
arnaucube/circomPublic Self-hosted repository
circom/src/ctx.js
src/ctx.jsRaw
  1const bigInt = require("big-integer");
  2const BigArray = require("./bigarray.js");
  3
  4
  5class TableName {
  6    constructor (ctx) {
  7        this.ctx = ctx;
  8        this.o = {};
  9    }
 10
 11    _allocElement(name, _sizes, type) {
 12        const sizes = _sizes || [];
 13        let l = 1;
 14        for (let i=0; i<sizes.length; i++) {
 15            l = l*sizes[i];
 16        }
 17        this.o[name] = {
 18            sizes: sizes,
 19            type: type
 20        };
 21        return l;
 22    }
 23
 24    addSignal(name, sizes) {
 25        const l = this._allocElement(name, sizes, "S");
 26        const o = this.ctx.nSignals;
 27        this.o[name].offset = o;
 28        this.ctx.nSignals += l;
 29        if (l>1) {
 30            return [o, o+l];
 31        } else {
 32            return o;
 33        }
 34    }
 35
 36    addComponent(name, sizes) {
 37        const l = this._allocElement(name, sizes, "C");
 38        const o = this.ctx.nComponents;
 39        this.o[name].offset = o;
 40        this.ctx.nComponents += l;
 41        if (l>1) {
 42            return [o, o+l];
 43        } else {
 44            return o;
 45        }
 46    }
 47
 48    _getElement(name, _sels, type) {
 49        const sels = _sels || [];
 50        const s = this.o[name];
 51        if (!s) return -1;
 52        if (s.type != type) return -1;
 53        if (sels.length > s.sizes.length) return -1;
 54        let l=1;
 55        for (let i = s.sizes.length-1; i>sels.length; i--) {
 56            l = l*s.sizes[i];
 57        }
 58        let o =0;
 59        let p=1;
 60        for (let i=sels.length-1; i>=0; i--) {
 61            if (sels[i] > s.sizes[i]) return -1; // Out of range
 62            if (sels[i] < 0) return -1; // Out of range
 63            o += p*sels[i];
 64            p *= s.sizes[i];
 65        }
 66        if (l>1) {
 67            return [s.offset + o, s.offset + o + l];
 68        } else {
 69            return s.offset + o;
 70        }
 71    }
 72
 73    getSignalIdx(name, sels) {
 74        return this._getElement(name, sels, "S");
 75    }
 76
 77    getComponentIdx(name, sels) {
 78        return this._getElement(name, sels, "C");
 79    }
 80
 81    getSizes(name) {
 82        return this.o[name].sels;
 83    }
 84
 85}
 86
 87module.exports = class Ctx {
 88
 89    constructor() {
 90
 91        this.stONE = 1;
 92        this.stOUTPUT = 2;
 93        this.stPUBINPUT = 3;
 94        this.stPRVINPUT = 4;
 95        this.stINTERNAL = 5;
 96        this.stDISCARDED = 6;
 97        this.stCONSTANT = 7;
 98
 99        this.IN = 0x01;
100        this.OUT = 0x02;
101        this.PRV = 0x04;
102        this.ONE = 0x08;
103        this.MAIN = 0x10;
104        this.COUNTED = 0x20;
105
106        this.scopes = [{}];
107        this.signals = new BigArray();
108
109        this.currentComponent= -1;
110        this.constraints= new BigArray();
111        this.components= new BigArray();
112        this.templates= {};
113        this.functions= {};
114        this.functionParams= {};
115        this.nSignals = 0;
116        this.nComponents =0;
117        this.names = new TableName(this);
118        this.main=false;
119        this.error = null;
120        this.warnings = [];
121
122        const oneIdx = this.addSignal("one");
123        this.signals[oneIdx] = {
124            v: bigInt(1),
125            o: this.ONE,
126            e: -1,
127        };
128
129        this.uniqueNames = {};
130    }
131
132    addSignal(name, sizes) {
133        if (this.currentComponent>=0) {
134            return this.components[this.currentComponent].names.addSignal(name, sizes);
135        } else {
136            return this.names.addSignal(name, sizes);
137        }
138    }
139
140    addComponent(name, sizes) {
141        if (this.currentComponent>=0) {
142            return this.components[this.currentComponent].names.addComponent(name, sizes);
143        } else {
144            return this.names.addComponent(name, sizes);
145        }
146    }
147
148    getSignalIdx(name, sels) {
149        if (this.currentComponent>=0) {
150            return this.components[this.currentComponent].names.getSignalIdx(name, sels);
151        } else {
152            return this.names.getSignalIdx(name, sels);
153        }
154    }
155
156    getComponentIdx(name, sels) {
157        if (this.currentComponent>=0) {
158            return this.components[this.currentComponent].names.getComponentIdx(name, sels);
159        } else {
160            return this.names.getComponentIdx(name, sels);
161        }
162    }
163
164    getSizes(name) {
165        if (this.currentComponent>=0) {
166            return this.components[this.currentComponent].names.getSizes(name);
167        } else {
168            return this.names.getSizes(name);
169        }
170    }
171
172    newTableName() {
173        return new TableName(this);
174    }
175
176    _buildErr(ast, errStr) {
177        if (typeof ast == "string") {
178            ast = null;
179            errStr = ast;
180        }
181        if (ast) {
182            return {
183                pos:   {
184                    first_line: ast.first_line,
185                    first_column: ast.first_column,
186                    last_line: ast.last_line,
187                    last_column: ast.last_column
188                },
189                errStr: errStr,
190                ast: ast,
191                message: errStr,
192                errFile: this.fileName
193            };
194        } else {
195            return {
196                errStr: errStr,
197                message: errStr
198            };
199        }
200    }
201
202    throwError(ast, errStr) {
203        const err = this._buildErr(ast, errStr);
204        this.error = err;
205    }
206
207    logWarning(ast, errStr) {
208        const w = this._buildErr(ast, errStr);
209        this.warnings.push(w);
210    }
211
212    getUniqueName(suggestedName) {
213        if (!suggestedName) {
214            suggestedName = "_tmp";
215        }
216
217        if (typeof(this.uniqueNames[suggestedName]) == "undefined") {
218            this.uniqueNames[suggestedName] = 1;
219            return suggestedName;
220        } else {
221            const name = suggestedName + "_" + this.uniqueNames[suggestedName];
222            this.uniqueNames[suggestedName]++;
223            return name;
224        }
225    }
226
227};