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