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};