circuitscript 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/cjs/BaseVisitor.js +487 -0
  2. package/dist/cjs/SemanticTokenVisitor.js +218 -0
  3. package/dist/cjs/SymbolValidatorVisitor.js +233 -0
  4. package/dist/cjs/antlr/CircuitScriptLexer.js +209 -195
  5. package/dist/cjs/antlr/CircuitScriptParser.js +2310 -2087
  6. package/dist/cjs/antlr/CircuitScriptVisitor.js +4 -3
  7. package/dist/cjs/draw_symbols.js +67 -22
  8. package/dist/cjs/execute.js +51 -53
  9. package/dist/cjs/geometry.js +28 -8
  10. package/dist/cjs/helpers.js +175 -5
  11. package/dist/cjs/index.js +2 -0
  12. package/dist/cjs/layout.js +8 -0
  13. package/dist/cjs/lexer.js +19 -22
  14. package/dist/cjs/main.js +6 -11
  15. package/dist/cjs/objects/ClassComponent.js +3 -0
  16. package/dist/cjs/objects/ExecutionScope.js +1 -0
  17. package/dist/cjs/objects/types.js +7 -1
  18. package/dist/cjs/parser.js +29 -258
  19. package/dist/cjs/validate.js +81 -0
  20. package/dist/cjs/visitor.js +529 -820
  21. package/dist/esm/BaseVisitor.mjs +488 -0
  22. package/dist/esm/SemanticTokenVisitor.mjs +215 -0
  23. package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
  24. package/dist/esm/antlr/CircuitScriptLexer.mjs +184 -194
  25. package/dist/esm/antlr/CircuitScriptParser.mjs +2279 -2084
  26. package/dist/esm/antlr/CircuitScriptVisitor.mjs +8 -3
  27. package/dist/esm/draw_symbols.mjs +67 -22
  28. package/dist/esm/execute.mjs +50 -52
  29. package/dist/esm/geometry.mjs +28 -8
  30. package/dist/esm/helpers.mjs +165 -6
  31. package/dist/esm/index.mjs +2 -0
  32. package/dist/esm/layout.mjs +8 -0
  33. package/dist/esm/lexer.mjs +10 -10
  34. package/dist/esm/main.mjs +7 -12
  35. package/dist/esm/objects/ClassComponent.mjs +3 -0
  36. package/dist/esm/objects/ExecutionScope.mjs +1 -0
  37. package/dist/esm/objects/types.mjs +6 -0
  38. package/dist/esm/parser.mjs +25 -230
  39. package/dist/esm/validate.mjs +74 -0
  40. package/dist/esm/visitor.mjs +343 -640
  41. package/dist/types/BaseVisitor.d.ts +69 -0
  42. package/dist/types/SemanticTokenVisitor.d.ts +36 -0
  43. package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
  44. package/dist/types/antlr/CircuitScriptLexer.d.ts +8 -7
  45. package/dist/types/antlr/CircuitScriptParser.d.ts +513 -469
  46. package/dist/types/antlr/CircuitScriptVisitor.d.ts +69 -59
  47. package/dist/types/draw_symbols.d.ts +9 -0
  48. package/dist/types/execute.d.ts +5 -8
  49. package/dist/types/geometry.d.ts +4 -0
  50. package/dist/types/helpers.d.ts +32 -1
  51. package/dist/types/index.d.ts +2 -0
  52. package/dist/types/lexer.d.ts +2 -2
  53. package/dist/types/objects/ExecutionScope.d.ts +4 -1
  54. package/dist/types/objects/types.d.ts +5 -0
  55. package/dist/types/parser.d.ts +15 -28
  56. package/dist/types/validate.d.ts +2 -0
  57. package/dist/types/visitor.d.ts +40 -95
  58. package/fonts/Inter-Bold.ttf +0 -0
  59. package/fonts/Inter-Regular.ttf +0 -0
  60. package/fonts/OpenSans-Regular.ttf +0 -0
  61. package/fonts/Roboto-Regular.ttf +0 -0
  62. package/libs/lib.cst +183 -0
  63. package/package.json +11 -6
@@ -1,815 +1,572 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VisitorExecutionException = exports.MainVisitor = void 0;
4
- const antlr4_1 = require("antlr4");
5
- const fs_1 = require("fs");
6
- const path_1 = require("path");
3
+ exports.VisitorExecutionException = exports.ParserVisitor = void 0;
7
4
  const execute_js_1 = require("./execute.js");
8
5
  const ClassComponent_js_1 = require("./objects/ClassComponent.js");
9
6
  const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
10
7
  const PinDefinition_js_1 = require("./objects/PinDefinition.js");
11
8
  const PinTypes_js_1 = require("./objects/PinTypes.js");
12
9
  const types_js_1 = require("./objects/types.js");
13
- const logger_js_1 = require("./logger.js");
14
10
  const globals_js_1 = require("./globals.js");
15
11
  const draw_symbols_js_1 = require("./draw_symbols.js");
16
- const parser_js_1 = require("./parser.js");
17
- class MainVisitor extends antlr4_1.ParseTreeVisitor {
18
- constructor(silent = false) {
19
- super();
20
- this.indentLevel = 0;
21
- this.silent = false;
22
- this.printStream = [];
23
- this.printToConsole = true;
24
- this.acceptedDirections = ['left', 'right', 'up', 'down'];
25
- this.pinTypesList = [
26
- PinTypes_js_1.PinTypes.Any,
27
- PinTypes_js_1.PinTypes.Input,
28
- PinTypes_js_1.PinTypes.Output,
29
- PinTypes_js_1.PinTypes.IO,
30
- PinTypes_js_1.PinTypes.Power,
31
- ];
32
- this.onImportFile = (visitor, filePath) => {
33
- throw "Import file not implemented";
12
+ const BaseVisitor_js_1 = require("./BaseVisitor.js");
13
+ class ParserVisitor extends BaseVisitor_js_1.BaseVisitor {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.visitKeyword_assignment_expr = (ctx) => {
17
+ const id = ctx.ID().getText();
18
+ const ctxDataExpr = ctx.data_expr();
19
+ this.visit(ctxDataExpr);
20
+ const value = this.getResult(ctxDataExpr);
21
+ this.setResult(ctx, [id, value]);
34
22
  };
35
- this.pinTypes = [
36
- PinTypes_js_1.PinTypes.Any,
37
- PinTypes_js_1.PinTypes.IO,
38
- PinTypes_js_1.PinTypes.Input,
39
- PinTypes_js_1.PinTypes.Output,
40
- PinTypes_js_1.PinTypes.Power,
41
- ];
42
- this.logger = new logger_js_1.Logger();
43
- this.startingContext = new execute_js_1.ExecutionContext('__', '__.', '/', 0, 0, silent, this.logger);
44
- this.setupPrintFunction(this.startingContext);
45
- this.executionStack = [this.startingContext];
46
- this.startingContext.resolveNet =
47
- this.createNetResolver(this.executionStack);
48
- this.silent = silent;
49
- }
50
- getExecutor() {
51
- return this.executionStack[this.executionStack.length - 1];
52
- }
53
- visit(ctx) {
54
- if (Array.isArray(ctx)) {
55
- return ctx.map(function (child) {
56
- try {
57
- return child.accept(this);
58
- }
59
- catch (err) {
60
- this.handleError(child, err);
61
- }
62
- }, this);
63
- }
64
- else {
65
- try {
66
- return ctx.accept(this);
67
- }
68
- catch (err) {
69
- this.handleError(ctx, err);
70
- }
71
- }
72
- }
73
- handleError(ctx, err) {
74
- if (!(err instanceof VisitorExecutionException)) {
75
- throw new VisitorExecutionException(ctx, err);
76
- }
77
- else {
78
- throw err;
79
- }
80
- }
81
- visitScript(ctx) {
82
- this.print('===', 'start', '===');
83
- const result = this.visitChildren(ctx);
84
- this.print('===', 'end', '===');
85
- return result;
86
- }
87
- visitParameters(ctx) {
88
- const dataExpressions = ctx.data_expr_list();
89
- const keywordAssignmentExpressions = ctx.keyword_assignment_expr_list();
90
- const returnList = [];
91
- dataExpressions.forEach((item, index) => {
92
- const value = this.visit(item);
93
- returnList.push(['position', index, value]);
94
- });
95
- keywordAssignmentExpressions.forEach((item) => {
96
- const [key, value] = this.visit(item);
97
- returnList.push(['keyword', key, value]);
98
- });
99
- return returnList;
100
- }
101
- visitKeyword_assignment_expr(ctx) {
102
- const id = ctx.ID().getText();
103
- const value = this.visit(ctx.data_expr());
104
- return [id, value];
105
- }
106
- visitAssignment_expr(ctx) {
107
- const atomStr = ctx.atom_expr().getText();
108
- if (atomStr.indexOf('(') !== -1 || atomStr.indexOf(')') !== -1) {
109
- throw "Invalid assignment expression!";
110
- }
111
- const reference = this.visit(ctx.atom_expr());
112
- const value = this.visit(ctx.data_expr());
113
- if (value instanceof ClassComponent_js_1.ClassComponent) {
114
- const instances = this.getExecutor().scope.instances;
115
- const tmpComponent = value;
116
- const oldName = tmpComponent.instanceName;
117
- tmpComponent.instanceName = reference.name;
118
- instances.delete(oldName);
119
- instances.set(reference.name, tmpComponent);
120
- this.getExecutor().print(`assigned '${reference.name}' to ClassComponent`);
121
- }
122
- else {
123
- const trailers = reference.trailers ?? [];
124
- if (trailers.length === 0) {
125
- this.getExecutor().scope.variables.set(reference.name, value);
126
- }
127
- else if (reference.value instanceof ClassComponent_js_1.ClassComponent) {
128
- this.setInstanceParam(reference.value, trailers, value);
23
+ this.visitPin_select_expr = (ctx) => {
24
+ let value = null;
25
+ const ctxIntegerValue = ctx.INTEGER_VALUE();
26
+ const ctxStringValue = ctx.STRING_VALUE();
27
+ if (ctxIntegerValue) {
28
+ value = Number(ctxIntegerValue.getText());
129
29
  }
130
- }
131
- return value;
132
- }
133
- setInstanceParam(object, trailers, value) {
134
- const paramName = trailers[0].slice(1);
135
- object.setParam(paramName, value);
136
- this.getExecutor().print(`set instance ${object.instanceName} param ${paramName} to ${value}`);
137
- }
138
- visitValue_expr(ctx) {
139
- const sign = ctx.Minus() ? -1 : 1;
140
- if (ctx.INTEGER_VALUE() || ctx.DECIMAL_VALUE() || ctx.NUMERIC_VALUE()) {
141
- if (ctx.INTEGER_VALUE()) {
142
- return sign * Number(ctx.INTEGER_VALUE().getText());
143
- }
144
- else if (ctx.DECIMAL_VALUE()) {
145
- return sign * Number(ctx.DECIMAL_VALUE().getText());
146
- }
147
- else if (ctx.NUMERIC_VALUE()) {
148
- const textExtra = ctx.Minus() ? '-' : '';
149
- return new ParamDefinition_js_1.NumericValue(textExtra + ctx.NUMERIC_VALUE().getText());
150
- }
151
- }
152
- else {
153
- if (sign === -1) {
154
- throw "Invalid value!";
155
- }
156
- }
157
- if (ctx.BOOLEAN_VALUE()) {
158
- const stringValue = ctx.BOOLEAN_VALUE().getText();
159
- if (stringValue === 'true') {
160
- return true;
30
+ else if (ctxStringValue) {
31
+ value = this.prepareStringValue(ctxStringValue.getText());
161
32
  }
162
- else if (stringValue === 'false') {
163
- return false;
164
- }
165
- }
166
- else if (ctx.STRING_VALUE()) {
167
- return this.prepareStringValue(ctx.STRING_VALUE().getText());
168
- }
169
- else if (ctx.PERCENTAGE_VALUE()) {
170
- return new ParamDefinition_js_1.PercentageValue(ctx.PERCENTAGE_VALUE().getText());
171
- }
172
- else if (ctx.blank_expr()) {
173
- return this.visit(ctx.blank_expr());
174
- }
175
- }
176
- visitBlank_expr(ctx) {
177
- return new ParamDefinition_js_1.PinBlankValue(Number(ctx.INTEGER_VALUE().getText()));
178
- }
179
- visitPin_select_expr(ctx) {
180
- if (ctx.INTEGER_VALUE()) {
181
- return Number(ctx.INTEGER_VALUE().getText());
182
- }
183
- else if (ctx.STRING_VALUE()) {
184
- return this.prepareStringValue(ctx.STRING_VALUE().getText());
185
- }
186
- return null;
187
- }
188
- visitAdd_component_expr(ctx) {
189
- const [component, pinValue] = this.visit(ctx.data_expr_with_assignment());
190
- if (ctx.ID()) {
191
- this.setComponentOrientation(component, pinValue, ctx.ID().getText());
192
- }
193
- return this.getExecutor().addComponentExisting(component, pinValue);
194
- }
195
- visitAt_component_expr(ctx) {
196
- if (ctx.Point()) {
197
- this.getExecutor().atPointBlock();
198
- }
199
- else {
200
- const [component, pin] = this.visit(ctx.component_select_expr());
201
- const currentPoint = this.getExecutor().atComponent(component, pin, {
202
- addSequence: true,
203
- cloneNetComponent: true
204
- });
205
- if (ctx.ID()) {
206
- this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
33
+ this.setResult(ctx, value);
34
+ };
35
+ this.visitAdd_component_expr = (ctx) => {
36
+ const ctxDataWithAssignmentExpr = ctx.data_expr_with_assignment();
37
+ this.setParam(ctxDataWithAssignmentExpr, { clone: false });
38
+ this.visit(ctxDataWithAssignmentExpr);
39
+ const [component, pinValue] = this.getResult(ctxDataWithAssignmentExpr);
40
+ return this.getExecutor().addComponentExisting(component, pinValue);
41
+ };
42
+ this.visitAt_component_expr = (ctx) => {
43
+ if (ctx.Point()) {
44
+ this.getExecutor().atPointBlock();
207
45
  }
208
- }
209
- return this.getExecutor().getCurrentPoint();
210
- }
211
- visitTo_component_expr(ctx) {
212
- let currentPoint;
213
- if (ctx.Point()) {
214
- this.getExecutor().toPointBlock();
215
- }
216
- else {
217
- ctx.component_select_expr_list().forEach((item) => {
218
- const [component, pin] = this.visit(item);
219
- currentPoint = this.getExecutor().toComponent(component, pin, {
220
- addSequence: true, cloneNetComponent: true
46
+ else {
47
+ const ctxComponentSelectExpr = ctx.component_select_expr();
48
+ this.visit(ctxComponentSelectExpr);
49
+ const [component, pin] = this.getResult(ctxComponentSelectExpr);
50
+ this.getExecutor().atComponent(component, pin, {
51
+ addSequence: true
221
52
  });
222
- });
223
- if (ctx.ID()) {
224
- this.setComponentOrientation(currentPoint[0], currentPoint[1], ctx.ID().getText());
225
- }
226
- }
227
- return this.getExecutor().getCurrentPoint();
228
- }
229
- visitComponent_select_expr(ctx) {
230
- if (ctx.data_expr_with_assignment()) {
231
- return this.visit(ctx.data_expr_with_assignment());
232
- }
233
- else {
234
- const component = this.getExecutor().scope.currentComponent;
235
- let pinId = null;
236
- if (ctx.pin_select_expr()) {
237
- pinId = this.visit(ctx.pin_select_expr());
238
53
  }
239
- return [component, pinId];
240
- }
241
- }
242
- visitPath_blocks(ctx) {
243
- const blocks = ctx.path_block_inner_list();
244
- let blockIndex = 0;
245
- let blockType = globals_js_1.BlockTypes.Branch;
246
- let prevBlockType = null;
247
- blocks.forEach((block, index) => {
248
- if (block.Branch()) {
249
- blockType = globals_js_1.BlockTypes.Branch;
250
- }
251
- else if (block.Join()) {
252
- blockType = globals_js_1.BlockTypes.Join;
54
+ return this.getExecutor().getCurrentPoint();
55
+ };
56
+ this.visitTo_component_expr = (ctx) => {
57
+ if (ctx.Point()) {
58
+ this.getExecutor().toPointBlock();
253
59
  }
254
- else if (block.Parallel()) {
255
- blockType = globals_js_1.BlockTypes.Parallel;
60
+ else {
61
+ ctx.component_select_expr().forEach(item => {
62
+ this.visit(item);
63
+ const [component, pin] = this.getResult(item);
64
+ this.getExecutor().toComponent(component, pin, {
65
+ addSequence: true
66
+ });
67
+ });
256
68
  }
257
- else if (block.Point()) {
258
- blockType = globals_js_1.BlockTypes.Point;
69
+ return this.getExecutor().getCurrentPoint();
70
+ };
71
+ this.visitComponent_select_expr = (ctx) => {
72
+ const ctxDataExprWithAssigment = ctx.data_expr_with_assignment();
73
+ if (ctxDataExprWithAssigment) {
74
+ this.visit(ctxDataExprWithAssigment);
75
+ this.setResult(ctx, this.getResult(ctxDataExprWithAssigment));
259
76
  }
260
- if (prevBlockType !== blockType) {
261
- if (index > 0) {
262
- this.getExecutor().exitBlocks();
77
+ else {
78
+ const component = this.getExecutor().scope.currentComponent;
79
+ let pinId = null;
80
+ const ctxPinSelectExpr = ctx.pin_select_expr();
81
+ if (ctxPinSelectExpr) {
82
+ this.visit(ctxPinSelectExpr);
83
+ pinId = this.getResult(ctxPinSelectExpr);
263
84
  }
264
- this.getExecutor().enterBlocks(blockType);
265
- blockIndex = 0;
85
+ this.setResult(ctx, [component, pinId]);
266
86
  }
267
- this.getExecutor().enterBlock(blockIndex);
268
- this.visit(block);
269
- this.getExecutor().exitBlock(blockIndex);
270
- blockIndex += 1;
271
- prevBlockType = blockType;
272
- });
273
- this.getExecutor().exitBlocks();
274
- return this.getExecutor().getCurrentPoint();
275
- }
276
- visitBreak_keyword() {
277
- this.getExecutor().breakBranch();
278
- return -1;
279
- }
280
- visitCreate_component_expr(ctx) {
281
- const properties = this.getPropertyExprList(ctx.property_expr_list());
282
- const pins = this.parseCreateComponentPins(properties.get('pins'));
283
- let instanceName = this.getExecutor().getUniqueInstanceName('');
284
- const propParams = properties.get('params');
285
- const params = this.parseCreateComponentParams(propParams);
286
- if (params.length > 0) {
287
- const firstParam = params[0];
288
- const paramValue = firstParam.paramValue;
289
- let appendValue = paramValue.toString();
290
- if (paramValue instanceof ParamDefinition_js_1.NumericValue) {
291
- appendValue = paramValue.value;
292
- }
293
- instanceName += '_' + appendValue;
294
- }
295
- const arrange = properties.has('arrange') ?
296
- properties.get('arrange') : null;
297
- const display = properties.has('display') ?
298
- properties.get('display') : null;
299
- const type = properties.has('type') ?
300
- properties.get('type') : null;
301
- const width = properties.has('width') ?
302
- properties.get('width') : null;
303
- const props = {
304
- arrange,
305
- display,
306
- type,
307
- width,
308
87
  };
309
- return this.getExecutor().createComponent(instanceName, pins, params, props);
310
- }
311
- visitCreate_graphic_expr(ctx) {
312
- const commands = ctx.sub_expr_list().reduce((accum, item) => {
313
- const [commandName, parameters] = this.visit(item);
314
- const keywordParams = new Map();
315
- const positionParams = parameters.reduce((accum, [argType, name, value]) => {
316
- if (argType === 'position') {
317
- accum.push(value);
88
+ this.visitPath_blocks = (ctx) => {
89
+ const blocks = ctx.path_block_inner();
90
+ let blockIndex = 0;
91
+ let blockType = globals_js_1.BlockTypes.Branch;
92
+ let prevBlockType = null;
93
+ blocks.forEach((block, index) => {
94
+ if (block.Branch()) {
95
+ blockType = globals_js_1.BlockTypes.Branch;
318
96
  }
319
- else {
320
- keywordParams.set(name, value);
97
+ else if (block.Join()) {
98
+ blockType = globals_js_1.BlockTypes.Join;
99
+ }
100
+ else if (block.Parallel()) {
101
+ blockType = globals_js_1.BlockTypes.Parallel;
102
+ }
103
+ else if (block.Point()) {
104
+ blockType = globals_js_1.BlockTypes.Point;
105
+ }
106
+ if (prevBlockType !== blockType) {
107
+ if (index > 0) {
108
+ this.getExecutor().exitBlocks();
109
+ }
110
+ this.getExecutor().enterBlocks(blockType);
111
+ blockIndex = 0;
321
112
  }
113
+ this.getExecutor().enterBlock(blockIndex);
114
+ this.visit(block);
115
+ this.getExecutor().exitBlock(blockIndex);
116
+ blockIndex += 1;
117
+ prevBlockType = blockType;
118
+ });
119
+ this.getExecutor().exitBlocks();
120
+ return this.getExecutor().getCurrentPoint();
121
+ };
122
+ this.visitCreate_component_expr = (ctx) => {
123
+ const properties = this.getPropertyExprList(ctx.property_expr());
124
+ const pins = this.parseCreateComponentPins(properties.get('pins'));
125
+ let instanceName = this.getExecutor().getUniqueInstanceName('');
126
+ const propParams = properties.get('params');
127
+ const params = this.parseCreateComponentParams(propParams);
128
+ if (params.length > 0) {
129
+ const firstParam = params[0];
130
+ const paramValue = firstParam.paramValue;
131
+ let appendValue = paramValue.toString();
132
+ if (paramValue instanceof ParamDefinition_js_1.NumericValue) {
133
+ appendValue = paramValue.value;
134
+ }
135
+ instanceName += '_' + appendValue;
136
+ }
137
+ const arrange = properties.has('arrange') ?
138
+ properties.get('arrange') : null;
139
+ const display = properties.has('display') ?
140
+ properties.get('display') : null;
141
+ const type = properties.has('type') ?
142
+ properties.get('type') : null;
143
+ const width = properties.has('width') ?
144
+ properties.get('width') : null;
145
+ const props = {
146
+ arrange,
147
+ display,
148
+ type,
149
+ width,
150
+ };
151
+ this.setResult(ctx, this.getExecutor().createComponent(instanceName, pins, params, props));
152
+ };
153
+ this.visitCreate_graphic_expr = (ctx) => {
154
+ const commands = ctx.sub_expr().reduce((accum, item) => {
155
+ this.visit(item);
156
+ const [commandName, parameters] = this.getResult(item);
157
+ const keywordParams = new Map();
158
+ const positionParams = parameters.reduce((accum, [argType, name, value]) => {
159
+ if (argType === 'position') {
160
+ accum.push(value);
161
+ }
162
+ else {
163
+ keywordParams.set(name, value);
164
+ }
165
+ return accum;
166
+ }, []);
167
+ accum.push([commandName, positionParams, keywordParams]);
322
168
  return accum;
323
169
  }, []);
324
- accum.push([commandName, positionParams, keywordParams]);
325
- return accum;
326
- }, []);
327
- return new draw_symbols_js_1.SymbolDrawingCommands(commands);
328
- }
329
- visitSub_expr(ctx) {
330
- let commandName = null;
331
- if (ctx.ID()) {
332
- commandName = ctx.ID().getText();
333
- }
334
- else if (ctx.Pin()) {
335
- commandName = ctx.Pin().getText();
336
- }
337
- else {
338
- throw "Invalid command!";
339
- }
340
- const parameters = this.visit(ctx.parameters());
341
- return [commandName, parameters];
342
- }
343
- visitProperty_expr(ctx) {
344
- const keyName = this.visit(ctx.property_key_expr());
345
- const value = this.visit(ctx.property_value_expr());
346
- const map = new Map();
347
- map.set(keyName, value);
348
- return map;
349
- }
350
- visitSingle_line_property(ctx) {
351
- let value;
352
- if (ctx.data_expr_list().length === 1) {
353
- value = this.visit(ctx.data_expr(0));
354
- }
355
- else {
356
- value = ctx.data_expr_list().map(item => {
357
- return this.visit(item);
358
- });
359
- }
360
- return value;
361
- }
362
- visitNested_properties(ctx) {
363
- const result = new Map();
364
- ctx.property_expr_list().forEach((item) => {
365
- const property = this.visit(item);
366
- for (const [key, value] of property) {
367
- result.set(key, value);
170
+ const drawing = new draw_symbols_js_1.SymbolDrawingCommands(commands);
171
+ drawing.source = ctx.getText();
172
+ this.setResult(ctx, drawing);
173
+ };
174
+ this.visitSub_expr = (ctx) => {
175
+ let commandName = null;
176
+ const command = ctx._command;
177
+ if (command) {
178
+ commandName = command.text;
368
179
  }
369
- });
370
- return result;
371
- }
372
- visitProperty_key_expr(ctx) {
373
- if (ctx.ID()) {
374
- return ctx.ID().getText();
375
- }
376
- else if (ctx.INTEGER_VALUE()) {
377
- return Number(ctx.INTEGER_VALUE().getText());
378
- }
379
- else if (ctx.STRING_VALUE()) {
380
- return this.prepareStringValue(ctx.STRING_VALUE().getText());
381
- }
382
- }
383
- visitData_expr_with_assignment(ctx) {
384
- let component;
385
- if (ctx.data_expr()) {
386
- component = this.visit(ctx.data_expr());
387
- if (component === null || component === undefined) {
388
- throw "Could not find component: " + ctx.data_expr().getText();
180
+ else {
181
+ throw "Invalid command!";
389
182
  }
390
- }
391
- else if (ctx.assignment_expr()) {
392
- component = this.visit(ctx.assignment_expr());
393
- }
394
- let pinValue = null;
395
- if (ctx.pin_select_expr()) {
396
- pinValue = this.visit(ctx.pin_select_expr());
397
- }
398
- else {
399
- pinValue = component.getDefaultPin();
400
- }
401
- return [component, pinValue];
402
- }
403
- visitValueAtomExpr(ctx) {
404
- let value;
405
- if (ctx.value_expr()) {
406
- value = this.visit(ctx.value_expr());
407
- }
408
- else if (ctx.atom_expr()) {
409
- const reference = this.visit(ctx.atom_expr());
410
- if (!reference.found) {
411
- value = new types_js_1.UndeclaredReference(reference);
183
+ const ctxParameters = ctx.parameters();
184
+ this.visit(ctxParameters);
185
+ const parameters = this.getResult(ctxParameters);
186
+ this.setResult(ctx, [commandName, parameters]);
187
+ };
188
+ this.visitProperty_expr = (ctx) => {
189
+ const ctxPropertyKeyExpr = ctx.property_key_expr();
190
+ const ctxPropertyValueExpr = ctx.property_value_expr();
191
+ this.visit(ctxPropertyKeyExpr);
192
+ this.visit(ctxPropertyValueExpr);
193
+ const keyName = this.getResult(ctxPropertyKeyExpr);
194
+ const value = this.getResult(ctxPropertyValueExpr);
195
+ const map = new Map();
196
+ map.set(keyName, value);
197
+ this.setResult(ctx, map);
198
+ };
199
+ this.visitSingle_line_property = (ctx) => {
200
+ let value;
201
+ if (ctx.data_expr().length === 1) {
202
+ const ctxFirst = ctx.data_expr(0);
203
+ this.visit(ctxFirst);
204
+ value = this.getResult(ctxFirst);
412
205
  }
413
206
  else {
414
- value = reference.value;
207
+ value = ctx.data_expr().map(item => {
208
+ this.visit(item);
209
+ return this.getResult(item);
210
+ });
415
211
  }
416
- }
417
- return value;
418
- }
419
- visitUnaryOperatorExpr(ctx) {
420
- const value = this.visit(ctx.data_expr());
421
- const unaryOp = ctx.unary_operator();
422
- if (unaryOp) {
423
- if (unaryOp.Not()) {
424
- if (typeof value === "boolean") {
425
- value = !value;
426
- }
427
- else {
428
- throw "Failed to do Not operator";
212
+ this.setResult(ctx, value);
213
+ };
214
+ this.visitNested_properties = (ctx) => {
215
+ const result = new Map();
216
+ ctx.property_expr().forEach((item) => {
217
+ this.visit(item);
218
+ const property = this.getResult(item);
219
+ for (const [key, value] of property) {
220
+ result.set(key, value);
429
221
  }
222
+ });
223
+ this.setResult(ctx, result);
224
+ };
225
+ this.visitProperty_key_expr = (ctx) => {
226
+ const ctxID = ctx.ID();
227
+ const ctxIntegerValue = ctx.INTEGER_VALUE();
228
+ const ctxStringValue = ctx.STRING_VALUE();
229
+ let result = null;
230
+ if (ctxID) {
231
+ result = ctxID.getText();
430
232
  }
431
- else if (unaryOp.Minus()) {
432
- if (typeof value === 'number') {
433
- return -value;
434
- }
435
- else {
436
- throw "Failed to do Negation operator";
233
+ else if (ctxIntegerValue) {
234
+ result = Number(ctxIntegerValue.getText());
235
+ }
236
+ else if (ctxStringValue) {
237
+ result = this.prepareStringValue(ctxStringValue.getText());
238
+ }
239
+ this.setResult(ctx, result);
240
+ };
241
+ this.visitData_expr_with_assignment = (ctx) => {
242
+ let component = null;
243
+ const ctxDataExpr = ctx.data_expr();
244
+ const ctxAssignmentExpr = ctx.assignment_expr();
245
+ if (ctxDataExpr) {
246
+ this.visit(ctxDataExpr);
247
+ component = this.getResult(ctxDataExpr);
248
+ if (component === null || component === undefined) {
249
+ throw "Could not find component: " + ctxDataExpr.getText();
437
250
  }
438
251
  }
439
- }
440
- return value;
441
- }
442
- visitDataExpr(ctx) {
443
- let value;
444
- if (ctx.create_component_expr()) {
445
- value = this.visit(ctx.create_component_expr());
446
- }
447
- else if (ctx.create_graphic_expr()) {
448
- value = this.visit(ctx.create_graphic_expr());
449
- }
450
- return value;
451
- }
452
- visitBinaryOperatorExpr(ctx) {
453
- const value1 = this.visit(ctx.data_expr(0));
454
- const value2 = this.visit(ctx.data_expr(1));
455
- const binaryOperatorType = ctx.binary_operator();
456
- if (binaryOperatorType.Equals()) {
457
- return value1 == value2;
458
- }
459
- else if (binaryOperatorType.NotEquals()) {
460
- return value1 != value2;
461
- }
462
- }
463
- visitMultiplyExpr(ctx) {
464
- const value1 = this.visit(ctx.data_expr(0));
465
- const value2 = this.visit(ctx.data_expr(1));
466
- if (ctx.Multiply()) {
467
- return value1 * value2;
468
- }
469
- else if (ctx.Divide()) {
470
- return value1 / value2;
471
- }
472
- }
473
- visitAdditionExpr(ctx) {
474
- const value1 = this.visit(ctx.data_expr(0));
475
- const value2 = this.visit(ctx.data_expr(1));
476
- if (ctx.Addition()) {
477
- return value1 + value2;
478
- }
479
- else if (ctx.Minus()) {
480
- return value1 - value2;
481
- }
482
- }
483
- visitFunction_args_expr(ctx) {
484
- const defaultValuesProvided = ctx.value_expr_list();
485
- const IDs = ctx.ID_list();
486
- const boundary = IDs.length - defaultValuesProvided.length;
487
- return IDs.map((id, index) => {
488
- if (index >= boundary) {
489
- const defaultValue = this.visit(defaultValuesProvided[index - boundary]);
490
- return [id.getText(), defaultValue];
252
+ else if (ctxAssignmentExpr) {
253
+ this.visit(ctxAssignmentExpr);
254
+ component = this.getResult(ctxAssignmentExpr);
255
+ }
256
+ let allowClone = true;
257
+ if (this.hasParam(ctx)) {
258
+ const { clone } = this.getParam(ctx);
259
+ allowClone = clone;
260
+ }
261
+ if (allowClone && component instanceof ClassComponent_js_1.ClassComponent
262
+ && (0, execute_js_1.isNetOnlyComponent)(component)) {
263
+ component = this.getExecutor().cloneComponent(component);
264
+ }
265
+ if (component && component instanceof ClassComponent_js_1.ClassComponent) {
266
+ const modifiers = ctx.component_modifier_expr();
267
+ modifiers.forEach(modifier => {
268
+ const modifierText = modifier.ID(0).getText();
269
+ const ctxValueExpr = modifier.value_expr();
270
+ const ctxID2 = modifier.ID(1);
271
+ let result = null;
272
+ if (ctxValueExpr) {
273
+ this.visit(ctxValueExpr);
274
+ result = this.getResult(ctxValueExpr);
275
+ }
276
+ else if (ctxID2) {
277
+ result = ctxID2.getText();
278
+ }
279
+ if (modifierText === 'flip') {
280
+ const flipValue = result;
281
+ if (flipValue.indexOf('x') !== -1) {
282
+ component.setParam('flipX', 1);
283
+ }
284
+ if (flipValue.indexOf('y') !== -1) {
285
+ component.setParam('flipY', 1);
286
+ }
287
+ }
288
+ else if (modifierText === 'angle') {
289
+ const angleValue = Number(result);
290
+ component.setParam('angle', angleValue);
291
+ }
292
+ });
491
293
  }
492
- else {
493
- return [id.getText()];
294
+ let pinValue = null;
295
+ const ctxPinSelectExpr = ctx.pin_select_expr();
296
+ if (ctxPinSelectExpr) {
297
+ this.visit(ctxPinSelectExpr);
298
+ pinValue = this.getResult(ctxPinSelectExpr);
494
299
  }
495
- });
496
- }
497
- createNetResolver(executionStack) {
498
- const resolveNet = (netName, netNamespace) => {
499
- this.print('find net', netNamespace, netName);
500
- const reversed = [...executionStack].reverse();
501
- for (let i = 0; i < reversed.length; i++) {
502
- const context = reversed[i];
503
- const net = context.scope.getNetWithName(netName);
504
- if (net !== null && net.namespace === netNamespace) {
505
- return {
506
- found: true,
507
- net,
508
- };
509
- }
300
+ else {
301
+ pinValue = component.getDefaultPin();
510
302
  }
511
- return {
512
- found: false
513
- };
514
- };
515
- return resolveNet;
516
- }
517
- visitFunction_def_expr(ctx) {
518
- const functionName = ctx.ID().getText();
519
- let funcDefinedParameters = [];
520
- if (ctx.function_args_expr()) {
521
- funcDefinedParameters = this.visit(ctx.function_args_expr());
522
- }
523
- const executionStack = this.executionStack;
524
- const functionCounter = { counter: 0 };
525
- const resolveNet = this.createNetResolver(this.executionStack);
526
- const __runFunc = (passedInParameters, options) => {
527
- const { netNamespace = "" } = options;
528
- const currentExecutionContext = executionStack[executionStack.length - 1];
529
- const executionLevel = currentExecutionContext.executionLevel;
530
- const executionContextName = functionName + '_' + functionCounter['counter'];
531
- const executionContextNamespace = currentExecutionContext.namespace
532
- + executionContextName + ".";
533
- functionCounter['counter'] += 1;
534
- const newExecutor = new execute_js_1.ExecutionContext(executionContextName, executionContextNamespace, netNamespace, executionLevel + 1, this.getExecutor().scope.indentLevel + 1, currentExecutionContext.silent, currentExecutionContext.logger);
535
- this.setupPrintFunction(newExecutor);
536
- newExecutor.resolveNet = resolveNet;
537
- executionStack.push(newExecutor);
538
- this.setupDefinedParameters(functionName, funcDefinedParameters, passedInParameters, newExecutor);
539
- const returnValue = this.runExpressions(newExecutor, ctx.function_expr_list());
540
- const lastExecution = executionStack.pop();
541
- const nextLastExecution = executionStack[executionStack.length - 1];
542
- nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
543
- return [lastExecution, returnValue];
303
+ this.setResult(ctx, [component, pinValue]);
544
304
  };
545
- this.getExecutor().createFunction(functionName, __runFunc);
546
- }
547
- setupDefinedParameters(functionName, funcDefinedParameters, passedInParameters, executor) {
548
- for (let i = 0; i < funcDefinedParameters.length; i++) {
549
- const tmpFuncArg = funcDefinedParameters[i];
550
- if (i < passedInParameters.length) {
551
- const tmpPassedInArgs = passedInParameters[i];
552
- if (tmpPassedInArgs[0] === 'position') {
553
- const variableName = tmpFuncArg[0];
554
- executor.print('set variable in scope, var name: ', variableName);
555
- executor.scope.variables.set(variableName, tmpPassedInArgs[2]);
556
- if (tmpPassedInArgs[2] instanceof ClassComponent_js_1.ClassComponent) {
557
- const component = tmpPassedInArgs[2];
558
- for (const [pinNumber, net] of component.pinNets) {
559
- executor.scope.setNet(component, pinNumber, net);
560
- }
305
+ this.visitUnaryOperatorExpr = (ctx) => {
306
+ this.visit(ctx.data_expr());
307
+ let value = this.getResult(ctx.data_expr());
308
+ const unaryOp = ctx.unary_operator();
309
+ if (unaryOp) {
310
+ if (unaryOp.Not()) {
311
+ if (typeof value === "boolean") {
312
+ value = !value;
313
+ }
314
+ else {
315
+ throw "Failed to do Not operator";
316
+ }
317
+ }
318
+ else if (unaryOp.Minus()) {
319
+ if (typeof value === 'number') {
320
+ value = -value;
321
+ }
322
+ else {
323
+ throw "Failed to do Negation operator";
561
324
  }
562
325
  }
563
326
  }
564
- else if (tmpFuncArg.length === 2) {
565
- const variableName = tmpFuncArg[0];
566
- const defaultValue = tmpFuncArg[1];
567
- executor.print('set variable in scope, var name: ', variableName);
568
- executor.scope.variables.set(variableName, defaultValue);
327
+ this.setResult(ctx, value);
328
+ };
329
+ this.visitDataExpr = (ctx) => {
330
+ let value;
331
+ const ctxCreateComponentExpr = ctx.create_component_expr();
332
+ const ctxCreateGraphicExpr = ctx.create_graphic_expr();
333
+ if (ctxCreateComponentExpr) {
334
+ this.visit(ctxCreateComponentExpr);
335
+ value = this.getResult(ctxCreateComponentExpr);
336
+ }
337
+ else if (ctxCreateGraphicExpr) {
338
+ this.visit(ctxCreateGraphicExpr);
339
+ value = this.getResult(ctxCreateGraphicExpr);
569
340
  }
570
341
  else {
571
- throw `Invalid arguments for function '${functionName}', got: `
572
- + passedInParameters;
342
+ throw "Invalid data expression";
573
343
  }
574
- }
575
- }
576
- visitFunction_return_expr(ctx) {
577
- const executor = this.getExecutor();
578
- executor.print('return from function');
579
- const returnValue = this.visit(ctx.data_expr());
580
- executor.stopFurtherExpressions = true;
581
- executor.returnValue = returnValue;
582
- return returnValue;
583
- }
584
- visitAtom_expr(ctx) {
585
- const executor = this.getExecutor();
586
- const atomId = ctx.ID().getText();
587
- let passedNetNamespace = null;
588
- if (ctx.net_namespace_expr()) {
589
- passedNetNamespace = this.visit(ctx.net_namespace_expr());
590
- }
591
- let currentReference;
592
- if (this.pinTypesList.indexOf(atomId) !== -1) {
593
- currentReference = {
594
- found: true,
595
- value: atomId
344
+ this.setResult(ctx, value);
345
+ };
346
+ this.visitBinaryOperatorExpr = (ctx) => {
347
+ const ctx0 = ctx.data_expr(0);
348
+ const ctx1 = ctx.data_expr(1);
349
+ this.visit(ctx0);
350
+ this.visit(ctx1);
351
+ const value1 = this.getResult(ctx0);
352
+ const value2 = this.getResult(ctx1);
353
+ const binaryOperatorType = ctx.binary_operator();
354
+ let result = null;
355
+ if (binaryOperatorType.Equals()) {
356
+ result = value1 == value2;
357
+ }
358
+ else if (binaryOperatorType.NotEquals()) {
359
+ result = value1 != value2;
360
+ }
361
+ this.setResult(ctx, result);
362
+ };
363
+ this.visitMultiplyExpr = (ctx) => {
364
+ this.visit(ctx.data_expr(0));
365
+ this.visit(ctx.data_expr(1));
366
+ const value1 = this.getResult(ctx.data_expr(0));
367
+ const value2 = this.getResult(ctx.data_expr(1));
368
+ let result = null;
369
+ if (ctx.Multiply()) {
370
+ result = value1 * value2;
371
+ }
372
+ else if (ctx.Divide()) {
373
+ result = value1 / value2;
374
+ }
375
+ this.setResult(ctx, result);
376
+ };
377
+ this.visitAdditionExpr = (ctx) => {
378
+ this.visit(ctx.data_expr(0));
379
+ this.visit(ctx.data_expr(1));
380
+ const value1 = this.getResult(ctx.data_expr(0));
381
+ const value2 = this.getResult(ctx.data_expr(1));
382
+ let result = null;
383
+ if (ctx.Addition()) {
384
+ result = value1 + value2;
385
+ }
386
+ else if (ctx.Minus()) {
387
+ result = value1 - value2;
388
+ }
389
+ this.setResult(ctx, result);
390
+ };
391
+ this.visitFunction_def_expr = (ctx) => {
392
+ const functionName = ctx.ID().getText();
393
+ let funcDefinedParameters = [];
394
+ const ctxFunctionArgsExpr = ctx.function_args_expr();
395
+ if (ctxFunctionArgsExpr) {
396
+ this.visit(ctxFunctionArgsExpr);
397
+ funcDefinedParameters = this.getResult(ctxFunctionArgsExpr);
398
+ }
399
+ const executionStack = this.executionStack;
400
+ const functionCounter = { counter: 0 };
401
+ const resolveNet = this.createNetResolver(this.executionStack);
402
+ const __runFunc = (passedInParameters, options) => {
403
+ const executionContextName = functionName + '_' + functionCounter['counter'];
404
+ const newExecutor = this.enterNewChildContext(executionStack, this.getExecutor(), executionContextName, options, funcDefinedParameters, passedInParameters);
405
+ functionCounter['counter'] += 1;
406
+ newExecutor.resolveNet = resolveNet;
407
+ const returnValue = this.runExpressions(newExecutor, ctx.function_expr());
408
+ const lastExecution = executionStack.pop();
409
+ const nextLastExecution = executionStack[executionStack.length - 1];
410
+ nextLastExecution.mergeScope(lastExecution.scope, executionContextName);
411
+ return [lastExecution, returnValue];
596
412
  };
597
- }
598
- else {
599
- currentReference = executor.resolveVariable(this.executionStack, atomId);
600
- }
601
- if (currentReference.found && currentReference.type === 'instance') {
602
- const tmpComponent = currentReference.value;
603
- for (const [pinId, net] of tmpComponent.pinNets) {
604
- executor.scope.setNet(tmpComponent, pinId, net);
413
+ this.getExecutor().createFunction(functionName, __runFunc);
414
+ };
415
+ this.visitPin_select_expr2 = (ctx) => {
416
+ const ctxStringValue = ctx.STRING_VALUE();
417
+ const ctxIntegerValue = ctx.INTEGER_VALUE();
418
+ let result = null;
419
+ if (ctxStringValue) {
420
+ result = this.prepareStringValue(ctxStringValue.getText());
605
421
  }
606
- }
607
- if (ctx.trailer_expr_list().length > 0) {
608
- if (!currentReference.found) {
609
- throw "Could not find reference! " + atomId;
422
+ else if (ctxIntegerValue) {
423
+ result = Number(ctxIntegerValue.getText());
610
424
  }
611
- currentReference.trailers = [];
612
- ctx.trailer_expr_list().forEach(item => {
613
- const itemValue = item.getText();
614
- if (item.OPEN_PAREN() && item.CLOSE_PAREN()) {
615
- let parameters = [];
616
- if (item.parameters()) {
617
- parameters = this.visit(item.parameters());
618
- }
619
- const useNetNamespace = this.getNetNamespace(executor.netNamespace, passedNetNamespace);
620
- const [, functionResult] = executor.callFunction(currentReference.name, parameters, this.executionStack, useNetNamespace);
621
- currentReference = {
622
- found: true,
623
- value: functionResult,
624
- type: (functionResult instanceof ClassComponent_js_1.ClassComponent) ?
625
- 'instance' : 'value',
626
- };
627
- }
628
- else {
629
- currentReference.trailers.push(itemValue);
630
- }
425
+ this.setResult(ctx, result);
426
+ };
427
+ this.visitAt_block_pin_expr = (ctx) => {
428
+ const ctxPinSelectExpr2 = ctx.pin_select_expr2();
429
+ this.visit(ctxPinSelectExpr2);
430
+ const atPin = this.getResult(ctxPinSelectExpr2);
431
+ const executor = this.getExecutor();
432
+ const currentComponent = executor.scope.currentComponent;
433
+ const currentPin = executor.scope.currentPin;
434
+ executor.atComponent(currentComponent, atPin, {
435
+ addSequence: true
631
436
  });
632
- }
633
- return currentReference;
634
- }
635
- visitPin_select_expr2(ctx) {
636
- if (ctx.STRING_VALUE()) {
637
- return this.prepareStringValue(ctx.STRING_VALUE().getText());
638
- }
639
- else if (ctx.INTEGER_VALUE()) {
640
- return Number(ctx.INTEGER_VALUE().getText());
641
- }
642
- }
643
- visitAt_block_pin_expr(ctx) {
644
- const atPin = this.visit(ctx.pin_select_expr2());
645
- const executor = this.getExecutor();
646
- const currentComponent = executor.scope.currentComponent;
647
- const currentPin = executor.scope.currentPin;
648
- executor.atComponent(currentComponent, atPin, {
649
- addSequence: true
650
- });
651
- executor.print('at block pin expressions');
652
- if (ctx.at_block_pin_expression_simple()) {
653
- this.visit(ctx.at_block_pin_expression_simple());
654
- }
655
- else if (ctx.at_block_pin_expression_complex()) {
656
- this.visit(ctx.at_block_pin_expression_complex());
657
- }
658
- executor.print('end at block pin expressions');
659
- return executor.atComponent(currentComponent, currentPin);
660
- }
661
- visitAt_block(ctx) {
662
- const executor = this.getExecutor();
663
- executor.print('entering at block');
664
- this.visit(ctx.at_component_expr());
665
- const currentComponent = executor.scope.currentComponent;
666
- const currentPin = executor.scope.currentPin;
667
- executor.scope.indentLevel += 1;
668
- ctx.at_block_expressions_list().forEach(expression => {
669
- this.visit(expression);
670
- });
671
- executor.scope.indentLevel -= 1;
672
- executor.scope.currentComponent = currentComponent;
673
- executor.scope.currentPin = currentPin;
674
- executor.print('leaving at block');
675
- return executor.getCurrentPoint();
676
- }
677
- visitAt_block_pin_expression_simple(ctx) {
678
- if (ctx.expression()) {
679
- this.visit(ctx.expression());
680
- }
681
- else if (ctx.NOT_CONNECTED()) {
682
- return;
683
- }
684
- }
685
- visitAt_block_pin_expression_complex(ctx) {
686
- ctx.expression_list().forEach(item => {
687
- this.visit(item);
688
- });
689
- return this.getExecutor().getCurrentPoint();
690
- }
691
- visitWire_expr(ctx) {
692
- const segments = [];
693
- const parts = ctx.children.slice(1);
694
- for (let i = 0; i < parts.length; i++) {
695
- const textValue = parts[i].getText();
696
- if (this.acceptedDirections.indexOf(textValue) !== -1) {
697
- const segment = [textValue];
698
- let skipNext = false;
699
- let invalidValue = true;
700
- if (i + 1 < parts.length) {
701
- const nextValue = parts[i + 1].getText();
702
- const nextValueNumber = Number(nextValue);
703
- if (!isNaN(nextValueNumber)) {
704
- invalidValue = false;
705
- segment.push(nextValueNumber);
706
- skipNext = true;
707
- }
708
- }
709
- if (invalidValue) {
710
- throw `Invalid value provided for direction ${textValue} in wire`;
711
- }
712
- segments.push(segment);
713
- if (skipNext) {
714
- i += 1;
715
- }
437
+ executor.log('at block pin expressions');
438
+ const ctxAtBlockSimple = ctx.at_block_pin_expression_simple();
439
+ const ctxAtBlockComplex = ctx.at_block_pin_expression_complex();
440
+ if (ctxAtBlockSimple) {
441
+ this.visit(ctxAtBlockSimple);
716
442
  }
717
- else if (textValue === "auto" || textValue === "auto_") {
718
- segments.push([textValue]);
443
+ else if (ctxAtBlockComplex) {
444
+ this.visit(ctxAtBlockComplex);
719
445
  }
720
- }
721
- this.getExecutor().addWire(segments);
722
- }
723
- visitPoint_expr(ctx) {
724
- const ID = ctx.ID();
725
- return this.getExecutor().addPoint(ID.getText());
726
- }
727
- visitImport_expr(ctx) {
728
- const ID = ctx.ID().toString();
729
- this.print('import', ID);
730
- const { hasError, hasParseError } = this.onImportFile(this, ID);
731
- if (hasError || hasParseError) {
732
- this.print('import', ID, 'failed');
733
- throw `import ${ID} failed`;
734
- }
735
- this.print('done import', ID);
736
- }
737
- visitProperty_set_expr(ctx) {
738
- const result = this.visit(ctx.data_expr());
739
- const resolvedProperty = this.visit(ctx.atom_expr());
740
- this.getExecutor().setProperty(resolvedProperty, result);
741
- }
742
- visitDouble_dot_property_set_expr(ctx) {
743
- const result = this.visit(ctx.data_expr());
744
- const propertyName = ctx.ID().getText();
745
- this.getExecutor().setProperty('..' + propertyName, result);
746
- }
747
- visitRoundedBracketsExpr(ctx) {
748
- return this.visit(ctx.data_expr());
749
- }
750
- visitFrame_expr(ctx) {
751
- const frameId = this.getExecutor().enterFrame();
752
- this.runExpressions(this.getExecutor(), ctx.expression_list());
753
- this.getExecutor().exitFrame(frameId);
754
- }
755
- visitNet_namespace_expr(ctx) {
756
- let dataValue = null;
757
- let netNamespace = null;
758
- const hasPlus = ctx.Addition();
759
- if (ctx.data_expr()) {
760
- dataValue = this.visit(ctx.data_expr());
761
- if (dataValue instanceof types_js_1.UndeclaredReference) {
762
- netNamespace = "/" + dataValue.reference.name;
446
+ executor.log('end at block pin expressions');
447
+ executor.atComponent(currentComponent, currentPin);
448
+ };
449
+ this.visitAt_block = (ctx) => {
450
+ const executor = this.getExecutor();
451
+ executor.log('entering at block');
452
+ this.visit(ctx.at_component_expr());
453
+ const currentComponent = executor.scope.currentComponent;
454
+ const currentPin = executor.scope.currentPin;
455
+ executor.scope.indentLevel += 1;
456
+ ctx.at_block_expressions().forEach(expression => {
457
+ this.visit(expression);
458
+ });
459
+ executor.scope.indentLevel -= 1;
460
+ executor.scope.currentComponent = currentComponent;
461
+ executor.scope.currentPin = currentPin;
462
+ executor.log('leaving at block');
463
+ };
464
+ this.visitAt_block_pin_expression_simple = (ctx) => {
465
+ const ctxExpression = ctx.expression();
466
+ if (ctxExpression) {
467
+ this.visit(ctxExpression);
763
468
  }
764
- else if (typeof dataValue === "string") {
765
- netNamespace = "/" + dataValue;
469
+ else if (ctx.NOT_CONNECTED()) {
470
+ return;
471
+ }
472
+ };
473
+ this.visitAt_block_pin_expression_complex = (ctx) => {
474
+ ctx.expression().forEach(item => {
475
+ this.visit(item);
476
+ });
477
+ };
478
+ this.visitWire_expr_direction_only = (ctx) => {
479
+ const value = ctx.ID().getText();
480
+ if (value === 'auto' || value === 'auto_') {
481
+ this.setResult(ctx, [value]);
766
482
  }
767
483
  else {
768
- throw "Failed to resolve net namespace value";
484
+ throw 'Invalid direction for wire';
769
485
  }
770
- }
771
- else {
772
- netNamespace = "/";
773
- }
774
- return (hasPlus ? "+" : "") + netNamespace;
775
- }
776
- createImportFileHandler(directory, defaultLibsPath) {
777
- return (visitor, importPath) => {
778
- let importResult;
779
- importResult = this.importLib(visitor, directory, importPath);
780
- if (!importResult.pathExists && importPath == 'lib') {
781
- importResult = this.importLib(visitor, defaultLibsPath, importPath);
486
+ };
487
+ this.visitWire_expr_direction_value = (ctx) => {
488
+ const direction = ctx.ID().getText();
489
+ if (this.acceptedDirections.indexOf(direction) !== -1) {
490
+ let useValue = null;
491
+ const ctxIntegerValue = ctx.INTEGER_VALUE();
492
+ const ctxDataExpr = ctx.data_expr();
493
+ if (ctxIntegerValue) {
494
+ useValue = Number(ctxIntegerValue);
495
+ }
496
+ else if (ctxDataExpr) {
497
+ this.visit(ctxDataExpr);
498
+ useValue = this.getResult(ctxDataExpr);
499
+ }
500
+ if (useValue !== null) {
501
+ this.setResult(ctx, [direction, useValue]);
502
+ return;
503
+ }
782
504
  }
783
- return importResult;
505
+ throw "Invalid direction or value for wire";
784
506
  };
785
- }
786
- importLib(visitor, directory, filename) {
787
- const tmpFilePath = (0, path_1.join)(directory, filename + ".cst");
788
- visitor.print('importing path:', tmpFilePath);
789
- let pathExists = false;
790
- let fileData = null;
791
- try {
792
- fileData = (0, fs_1.readFileSync)(tmpFilePath, { encoding: 'utf8' });
793
- pathExists = true;
794
- }
795
- catch (err) {
796
- pathExists = false;
797
- }
798
- try {
799
- if (pathExists) {
800
- visitor.print('done reading imported file data');
801
- const { hasError, hasParseError } = (0, parser_js_1.parseFileWithVisitor)(visitor, fileData);
802
- return { hasError, hasParseError, pathExists };
507
+ this.visitWire_expr = (ctx) => {
508
+ const wireAtomExpr = ctx.wire_atom_expr();
509
+ const segments = wireAtomExpr.map(wireSegment => {
510
+ this.visit(wireSegment);
511
+ return this.getResult(wireSegment);
512
+ });
513
+ this.getExecutor().addWire(segments);
514
+ };
515
+ this.visitPoint_expr = (ctx) => {
516
+ const ID = ctx.ID();
517
+ return this.getExecutor().addPoint(ID.getText());
518
+ };
519
+ this.visitProperty_set_expr = (ctx) => {
520
+ const ctxDataExpr = ctx.data_expr();
521
+ this.visit(ctxDataExpr);
522
+ const result = this.getResult(ctxDataExpr);
523
+ const ctxAtomExpr = ctx.atom_expr();
524
+ this.visit(ctxAtomExpr);
525
+ const resolvedProperty = this.getResult(ctxAtomExpr);
526
+ this.getExecutor().setProperty(resolvedProperty, result);
527
+ };
528
+ this.visitDouble_dot_property_set_expr = (ctx) => {
529
+ const ctxDataExpr = ctx.data_expr();
530
+ this.visit(ctxDataExpr);
531
+ const result = this.getResult(ctxDataExpr);
532
+ const propertyName = ctx.ID().getText();
533
+ this.getExecutor().setProperty('..' + propertyName, result);
534
+ };
535
+ this.visitFrame_expr = (ctx) => {
536
+ const frameId = this.getExecutor().enterFrame();
537
+ this.runExpressions(this.getExecutor(), ctx.expression());
538
+ this.getExecutor().exitFrame(frameId);
539
+ };
540
+ this.visitNet_namespace_expr = (ctx) => {
541
+ let dataValue = null;
542
+ let netNamespace = null;
543
+ const hasPlus = ctx.Addition();
544
+ const ctxDataExpr = ctx.data_expr();
545
+ if (ctxDataExpr) {
546
+ this.visit(ctxDataExpr);
547
+ dataValue = this.getResult(ctxDataExpr);
548
+ if (dataValue instanceof types_js_1.UndeclaredReference) {
549
+ netNamespace = "/" + dataValue.reference.name;
550
+ }
551
+ else if (typeof dataValue === "string") {
552
+ netNamespace = "/" + dataValue;
553
+ }
554
+ else {
555
+ throw "Failed to resolve net namespace value";
556
+ }
803
557
  }
804
- }
805
- catch (err) {
806
- visitor.print('Failed to import file: ', err.message);
807
- }
808
- return {
809
- hasError: true,
810
- hasParseError: true,
811
- pathExists,
558
+ else {
559
+ netNamespace = "/";
560
+ }
561
+ this.setResult(ctx, (hasPlus ? "+" : "") + netNamespace);
812
562
  };
563
+ this.pinTypes = [
564
+ PinTypes_js_1.PinTypes.Any,
565
+ PinTypes_js_1.PinTypes.IO,
566
+ PinTypes_js_1.PinTypes.Input,
567
+ PinTypes_js_1.PinTypes.Output,
568
+ PinTypes_js_1.PinTypes.Power,
569
+ ];
813
570
  }
814
571
  parseCreateComponentPins(pinData) {
815
572
  const pins = [];
@@ -862,18 +619,6 @@ class MainVisitor extends antlr4_1.ParseTreeVisitor {
862
619
  }
863
620
  return result;
864
621
  }
865
- prepareStringValue(value) {
866
- return value.slice(1, value.length - 1);
867
- }
868
- print(...params) {
869
- const indentOutput = ''.padStart(this.indentLevel * 4, ' ');
870
- const indentLevelText = this.indentLevel.toString().padStart(3, ' ');
871
- const args = ['[' + indentLevelText + ']', indentOutput, ...params];
872
- this.logger.add(args.join(' '));
873
- if (!this.silent) {
874
- console.log.apply(null, args);
875
- }
876
- }
877
622
  printNets() {
878
623
  this.getExecutor().scope.printNets();
879
624
  }
@@ -935,7 +680,10 @@ class MainVisitor extends antlr4_1.ParseTreeVisitor {
935
680
  }
936
681
  getGraph() {
937
682
  const executor = this.getExecutor();
938
- const sequence = executor.scope.sequence;
683
+ const fullSequence = executor.scope.sequence;
684
+ const tmpNet = executor.scope.getNet(executor.scope.componentRoot, 1);
685
+ const sequence = (tmpNet === null)
686
+ ? fullSequence.slice(1) : fullSequence;
939
687
  const nets = executor.scope.getNets();
940
688
  return {
941
689
  sequence,
@@ -944,7 +692,7 @@ class MainVisitor extends antlr4_1.ParseTreeVisitor {
944
692
  };
945
693
  }
946
694
  annotateComponents() {
947
- this.print('===== annotate components =====');
695
+ this.log('===== annotate components =====');
948
696
  const annotater = new ComponentAnnotater();
949
697
  const instances = this.getExecutor().scope.instances;
950
698
  const toAnnotate = [];
@@ -956,7 +704,7 @@ class MainVisitor extends antlr4_1.ParseTreeVisitor {
956
704
  continue;
957
705
  }
958
706
  if (instance.typeProp === null) {
959
- this.print('Instance has no type:', instance.instanceName, ' assuming connector');
707
+ this.log('Instance has no type:', instance.instanceName, ' assuming connector');
960
708
  instance.typeProp = 'conn';
961
709
  }
962
710
  if (instance.parameters.has('refdes')) {
@@ -964,7 +712,7 @@ class MainVisitor extends antlr4_1.ParseTreeVisitor {
964
712
  if (refdes) {
965
713
  instance.assignedRefDes = refdes;
966
714
  annotater.trackRefDes(refdes);
967
- this.print(refdes, '-', instance.instanceName);
715
+ this.log(refdes, '-', instance.instanceName);
968
716
  continue;
969
717
  }
970
718
  }
@@ -975,14 +723,14 @@ class MainVisitor extends antlr4_1.ParseTreeVisitor {
975
723
  const newRefDes = annotater.getAnnotation(instance.typeProp);
976
724
  if (newRefDes !== null) {
977
725
  instance.assignedRefDes = newRefDes;
978
- this.print(newRefDes, '-', instance.instanceName);
726
+ this.log(newRefDes, '-', instance.instanceName);
979
727
  }
980
728
  else {
981
- this.print('Failed to annotate:', instance.instanceName);
729
+ this.log('Failed to annotate:', instance.instanceName);
982
730
  }
983
731
  });
984
- this.print('===== annotate done =====');
985
- this.print('');
732
+ this.log('===== annotate done =====');
733
+ this.log('');
986
734
  }
987
735
  resolveNets(scope, instance) {
988
736
  const result = [];
@@ -1011,63 +759,24 @@ class MainVisitor extends antlr4_1.ParseTreeVisitor {
1011
759
  throw "Invalid modifier for orientation";
1012
760
  }
1013
761
  }
762
+ setComponentFlip(component, flipValue) {
763
+ if (this.acceptedFlip.indexOf(flipValue) !== -1) {
764
+ component.setParam(flipValue, 1);
765
+ }
766
+ }
1014
767
  getPropertyExprList(items) {
1015
768
  const properties = new Map();
1016
769
  items.forEach((item) => {
1017
- const result = this.visit(item);
770
+ this.visit(item);
771
+ const result = this.getResult(item);
1018
772
  for (const [key, value] of result) {
1019
773
  properties.set(key, value);
1020
774
  }
1021
775
  });
1022
776
  return properties;
1023
777
  }
1024
- runExpressions(executor, expressions) {
1025
- let returnValue = null;
1026
- for (let i = 0; i < expressions.length; i++) {
1027
- const expr = expressions[i];
1028
- this.visit(expr);
1029
- if (executor.stopFurtherExpressions) {
1030
- returnValue = executor.returnValue;
1031
- break;
1032
- }
1033
- }
1034
- return returnValue;
1035
- }
1036
- setupPrintFunction(context) {
1037
- context.createFunction('print', (params) => {
1038
- const items = params.map(([, , value]) => {
1039
- return value;
1040
- });
1041
- if (this.printToConsole) {
1042
- console.log('::', ...items);
1043
- }
1044
- this.printStream.push(...items);
1045
- return [this, null];
1046
- });
1047
- }
1048
- getNetNamespace(executorNetNamespace, passedNetNamespace) {
1049
- let result = executorNetNamespace;
1050
- if (passedNetNamespace !== null && passedNetNamespace.length > 0) {
1051
- if (passedNetNamespace === '/' || passedNetNamespace === '_') {
1052
- result = '';
1053
- }
1054
- else if (passedNetNamespace[0] === '+') {
1055
- if (executorNetNamespace === '/') {
1056
- result = passedNetNamespace.slice(1);
1057
- }
1058
- else {
1059
- result = executorNetNamespace + passedNetNamespace.slice(2);
1060
- }
1061
- }
1062
- else {
1063
- result = passedNetNamespace;
1064
- }
1065
- result = result + '/';
1066
- }
1067
- return result;
1068
- }
1069
778
  }
1070
- exports.MainVisitor = MainVisitor;
779
+ exports.ParserVisitor = ParserVisitor;
1071
780
  const ComponentRefDesPrefixes = {
1072
781
  'res': 'R',
1073
782
  'cap': 'C',