circuitscript 0.0.24 → 0.0.26

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 (73) hide show
  1. package/LICENSE +1 -1
  2. package/dist/cjs/BaseVisitor.js +485 -0
  3. package/dist/cjs/SemanticTokenVisitor.js +218 -0
  4. package/dist/cjs/SymbolValidatorVisitor.js +233 -0
  5. package/dist/cjs/antlr/CircuitScriptLexer.js +256 -219
  6. package/dist/cjs/antlr/CircuitScriptParser.js +2891 -2151
  7. package/dist/cjs/antlr/CircuitScriptVisitor.js +4 -3
  8. package/dist/cjs/draw_symbols.js +73 -22
  9. package/dist/cjs/execute.js +70 -78
  10. package/dist/cjs/export.js +91 -5
  11. package/dist/cjs/geometry.js +28 -8
  12. package/dist/cjs/globals.js +1 -2
  13. package/dist/cjs/helpers.js +180 -7
  14. package/dist/cjs/index.js +2 -0
  15. package/dist/cjs/layout.js +8 -0
  16. package/dist/cjs/lexer.js +19 -22
  17. package/dist/cjs/main.js +27 -20
  18. package/dist/cjs/objects/ClassComponent.js +4 -0
  19. package/dist/cjs/objects/ExecutionScope.js +1 -0
  20. package/dist/cjs/objects/types.js +7 -1
  21. package/dist/cjs/parser.js +29 -258
  22. package/dist/cjs/render.js +1 -1
  23. package/dist/cjs/validate.js +81 -0
  24. package/dist/cjs/visitor.js +601 -823
  25. package/dist/esm/BaseVisitor.mjs +486 -0
  26. package/dist/esm/SemanticTokenVisitor.mjs +215 -0
  27. package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
  28. package/dist/esm/antlr/CircuitScriptLexer.mjs +231 -218
  29. package/dist/esm/antlr/CircuitScriptParser.mjs +2852 -2144
  30. package/dist/esm/antlr/CircuitScriptVisitor.mjs +13 -4
  31. package/dist/esm/draw_symbols.mjs +74 -23
  32. package/dist/esm/execute.mjs +70 -75
  33. package/dist/esm/export.mjs +89 -6
  34. package/dist/esm/geometry.mjs +28 -8
  35. package/dist/esm/globals.mjs +1 -2
  36. package/dist/esm/helpers.mjs +171 -9
  37. package/dist/esm/index.mjs +2 -0
  38. package/dist/esm/layout.mjs +8 -0
  39. package/dist/esm/lexer.mjs +10 -10
  40. package/dist/esm/main.mjs +28 -21
  41. package/dist/esm/objects/ClassComponent.mjs +4 -0
  42. package/dist/esm/objects/ExecutionScope.mjs +1 -0
  43. package/dist/esm/objects/types.mjs +6 -0
  44. package/dist/esm/parser.mjs +25 -230
  45. package/dist/esm/render.mjs +2 -2
  46. package/dist/esm/validate.mjs +74 -0
  47. package/dist/esm/visitor.mjs +415 -643
  48. package/dist/types/BaseVisitor.d.ts +66 -0
  49. package/dist/types/SemanticTokenVisitor.d.ts +36 -0
  50. package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
  51. package/dist/types/antlr/CircuitScriptLexer.d.ts +37 -29
  52. package/dist/types/antlr/CircuitScriptParser.d.ts +606 -494
  53. package/dist/types/antlr/CircuitScriptVisitor.d.ts +78 -60
  54. package/dist/types/draw_symbols.d.ts +12 -3
  55. package/dist/types/execute.d.ts +5 -10
  56. package/dist/types/export.d.ts +27 -1
  57. package/dist/types/geometry.d.ts +4 -0
  58. package/dist/types/globals.d.ts +2 -3
  59. package/dist/types/helpers.d.ts +32 -1
  60. package/dist/types/index.d.ts +2 -0
  61. package/dist/types/lexer.d.ts +2 -2
  62. package/dist/types/objects/ClassComponent.d.ts +1 -0
  63. package/dist/types/objects/ExecutionScope.d.ts +4 -1
  64. package/dist/types/objects/types.d.ts +5 -0
  65. package/dist/types/parser.d.ts +15 -28
  66. package/dist/types/validate.d.ts +2 -0
  67. package/dist/types/visitor.d.ts +43 -95
  68. package/fonts/Inter-Bold.ttf +0 -0
  69. package/fonts/Inter-Regular.ttf +0 -0
  70. package/fonts/OpenSans-Regular.ttf +0 -0
  71. package/fonts/Roboto-Regular.ttf +0 -0
  72. package/libs/lib.cst +184 -0
  73. package/package.json +11 -6
@@ -3,6 +3,7 @@ import { NumericValue } from "./objects/ParamDefinition.mjs";
3
3
  export function generateKiCADNetList(netlist) {
4
4
  const componentsList = [];
5
5
  const nets = {};
6
+ const missingFootprints = [];
6
7
  netlist.forEach(entry => {
7
8
  const { instance, pins } = entry;
8
9
  if (instance.assignedRefDes !== null) {
@@ -22,7 +23,10 @@ export function generateKiCADNetList(netlist) {
22
23
  instance.parameters.get('footprint')]);
23
24
  }
24
25
  else {
25
- console.log(instance.assignedRefDes, instance.instanceName, 'does not have footprint');
26
+ missingFootprints.push({
27
+ refdes: instance.assignedRefDes,
28
+ instanceName: instance.instanceName
29
+ });
26
30
  }
27
31
  componentsList.push(instanceDetails);
28
32
  for (const key in pins) {
@@ -63,20 +67,24 @@ export function generateKiCADNetList(netlist) {
63
67
  ]);
64
68
  counter++;
65
69
  }
70
+ const dateString = new Date().toISOString().slice(0, 10);
66
71
  const tree = [
67
72
  Id("export"),
68
73
  [Id("version"), "E"],
69
74
  [Id("design"),
70
- [Id("source"), "/somefile"],
71
- [Id("date"), "2023-11-19"],
75
+ [Id("source"), "/unknown-file"],
76
+ [Id("date"), dateString],
72
77
  [Id("tool"), "circuitscript-to-kicad"]
73
78
  ],
74
79
  [Id('components'), ...componentsList],
75
80
  [Id('nets'), ...netItems]
76
81
  ];
77
- return printTree(tree);
82
+ return {
83
+ tree,
84
+ missingFootprints
85
+ };
78
86
  }
79
- function printTree(tree, level = 0) {
87
+ export function printTree(tree, level = 0) {
80
88
  const output = [];
81
89
  if (!Array.isArray(tree)) {
82
90
  return "\"" + tree + "\"";
@@ -98,9 +106,84 @@ function printTree(tree, level = 0) {
98
106
  function Id(name) {
99
107
  return new IdObject(name);
100
108
  }
101
- class IdObject {
109
+ export class IdObject {
102
110
  keyName;
103
111
  constructor(keyName) {
104
112
  this.keyName = keyName;
105
113
  }
106
114
  }
115
+ export function _id(key) {
116
+ return new IdObject(key);
117
+ }
118
+ export class SExpObject {
119
+ object;
120
+ constructor(object) {
121
+ this.object = object;
122
+ }
123
+ getKey(object = null) {
124
+ object = object ?? this.object;
125
+ return object[0];
126
+ }
127
+ getValue(object = null) {
128
+ object = object ?? this.object;
129
+ return object.slice(1);
130
+ }
131
+ getJSON(object = null) {
132
+ object = object ?? this.object;
133
+ if (!Array.isArray(object)) {
134
+ return object;
135
+ }
136
+ const properties = {};
137
+ const keyName = object[0].keyName;
138
+ if (object.length === 2) {
139
+ properties[keyName] = this.getJSON(object[1]);
140
+ }
141
+ else {
142
+ const innerProps = {};
143
+ this.getValue(object).forEach(item => {
144
+ const tmpValue = this.getJSON(item);
145
+ if (typeof tmpValue === "object") {
146
+ for (const key in tmpValue) {
147
+ if (innerProps[key]) {
148
+ if (!Array.isArray(innerProps[key])) {
149
+ innerProps[key] = [innerProps[key]];
150
+ }
151
+ innerProps[key].push(tmpValue[key]);
152
+ }
153
+ else {
154
+ innerProps[key] = tmpValue[key];
155
+ }
156
+ }
157
+ }
158
+ else {
159
+ innerProps[item[0].keyName] = tmpValue;
160
+ }
161
+ });
162
+ properties[keyName] = innerProps;
163
+ }
164
+ return properties;
165
+ }
166
+ getWithId(id, object = null) {
167
+ object = object ?? this.object;
168
+ let result = null;
169
+ const key = object[0];
170
+ if (key.keyName === id) {
171
+ return object;
172
+ }
173
+ else {
174
+ this.getValue(object).some(item => {
175
+ if (Array.isArray(item)) {
176
+ result = this.getWithId(id, item);
177
+ if (result !== null) {
178
+ return true;
179
+ }
180
+ }
181
+ return false;
182
+ });
183
+ }
184
+ return result;
185
+ }
186
+ print() {
187
+ console.log(printTree(this.object));
188
+ }
189
+ }
@@ -52,8 +52,12 @@ export class Label extends Flatten.Polygon {
52
52
  return new Label(id, useText, [x, y], polygon, style, box);
53
53
  }
54
54
  rotate(angle, origin) {
55
- const polygonRotate = super.rotate(angle, origin);
56
- return new Label(this.id, this.text, this.anchorPoint, polygonRotate, this.style, this.textMeasurementBounds);
55
+ const feature = super.rotate(angle, origin);
56
+ return new Label(this.id, this.text, this.anchorPoint, feature, this.style, this.textMeasurementBounds);
57
+ }
58
+ transform(matrix) {
59
+ const feature = super.transform(matrix);
60
+ return new Label(this.id, this.text, this.anchorPoint, feature, this.style, this.textMeasurementBounds);
57
61
  }
58
62
  getLabelPosition() {
59
63
  return this.anchorPoint;
@@ -103,6 +107,10 @@ export class Geometry {
103
107
  const angleRads = angleDegrees * Math.PI / 180;
104
108
  return feature.rotate(angleRads, Geometry.point(center[0], center[1]));
105
109
  }
110
+ static flip(feature, flipX, flipY) {
111
+ const flipMatrix = (new Flatten.Matrix()).scale(flipX === 0 ? 1 : -1, flipY == 0 ? 1 : -1);
112
+ return feature.transform(flipMatrix);
113
+ }
106
114
  static groupRotate(features, angle, center) {
107
115
  const angleRads = angle * Math.PI / 180;
108
116
  const rotateAboutPoint = Geometry.point(center[0], center[1]);
@@ -110,6 +118,12 @@ export class Geometry {
110
118
  return feature.rotate(angleRads, rotateAboutPoint);
111
119
  });
112
120
  }
121
+ static groupFlip(features, flipX, flipY) {
122
+ const flipMatrix = (new Flatten.Matrix()).scale(flipX === 0 ? 1 : -1, flipY == 0 ? 1 : -1);
123
+ return features.map(feature => {
124
+ return feature.transform(flipMatrix);
125
+ });
126
+ }
113
127
  static groupBounds(features) {
114
128
  let minX = Number.POSITIVE_INFINITY;
115
129
  let minY = Number.POSITIVE_INFINITY;
@@ -171,9 +185,7 @@ export class Geometry {
171
185
  }
172
186
  const startPoint = getArcPointRadians(x, y, radius, item.startAngle);
173
187
  const endPoint = getArcPointRadians(x, y, radius, useEndAngle);
174
- paths.push('M ' + startPoint[0] + ' ' + startPoint[1]
175
- + 'A ' + radius + ' ' + radius + ' 0 1 1 '
176
- + endPoint[0] + ' ' + endPoint[1] + extraEnd);
188
+ paths.push('M', startPoint[0], startPoint[1], 'A', radius, radius, 0, 1, 1, endPoint[0], endPoint[1], extraEnd);
177
189
  }
178
190
  else {
179
191
  const coords = Geometry.getCoords(item);
@@ -183,19 +195,27 @@ export class Geometry {
183
195
  for (let i = 0; i < coords.length; i++) {
184
196
  const [x, y] = coords[i];
185
197
  const command = (i === 0) ? 'M' : 'L';
186
- path.push(`${command} ${x} ${y}`);
198
+ path.push(`${command}`, x, y);
187
199
  }
188
200
  if (isClosedPolygon) {
189
201
  path.push('Z');
190
202
  }
191
- paths.push(path.join(' '));
203
+ paths.push(...path);
192
204
  }
193
205
  });
194
206
  return {
195
- path: paths.join(" "),
207
+ path: this.roundPathValues(paths),
196
208
  isClosedPolygon,
197
209
  };
198
210
  }
211
+ static roundPathValues(pathItems) {
212
+ return pathItems.map(item => {
213
+ if (typeof item === 'number') {
214
+ return (+item.toFixed(7)).toString();
215
+ }
216
+ return item;
217
+ }).join(" ");
218
+ }
199
219
  static angle(dx, dy) {
200
220
  const line = new Flatten.Segment(new Flatten.Point(0, 0), new Flatten.Point(dx, dy));
201
221
  return line.slope * 180 / Math.PI;
@@ -10,8 +10,6 @@ export var GlobalNames;
10
10
  export const NoNetText = 'NO_NET';
11
11
  export var ParamKeys;
12
12
  (function (ParamKeys) {
13
- ParamKeys["__is_net"] = "__is_net";
14
- ParamKeys["__is_label"] = "__is_label";
15
13
  ParamKeys["priority"] = "priority";
16
14
  ParamKeys["net_name"] = "net_name";
17
15
  })(ParamKeys || (ParamKeys = {}));
@@ -47,6 +45,7 @@ export var ReferenceTypes;
47
45
  ReferenceTypes["value"] = "value";
48
46
  ReferenceTypes["variable"] = "variable";
49
47
  ReferenceTypes["instance"] = "instance";
48
+ ReferenceTypes["pinType"] = "pinType";
50
49
  })(ReferenceTypes || (ReferenceTypes = {}));
51
50
  export var BlockTypes;
52
51
  (function (BlockTypes) {
@@ -1,23 +1,165 @@
1
- import { writeFileSync } from "fs";
2
- import { generateKiCADNetList } from "./export.mjs";
1
+ import { readFileSync, writeFileSync } from "fs";
2
+ import { generateKiCADNetList, printTree } from "./export.mjs";
3
3
  import { LayoutEngine } from "./layout.mjs";
4
4
  import { SequenceAction } from "./objects/ExecutionScope.mjs";
5
5
  import { parseFileWithVisitor } from "./parser.mjs";
6
6
  import { generateSVG2 } from "./render.mjs";
7
7
  import { SimpleStopwatch } from "./utils.mjs";
8
- import { MainVisitor } from "./visitor.mjs";
8
+ import { ParserVisitor, VisitorExecutionException } from "./visitor.mjs";
9
9
  import { createContext } from "this-file";
10
+ import { SymbolValidatorResolveVisitor, SymbolValidatorVisitor } from "./SymbolValidatorVisitor.mjs";
11
+ import { BaseErrorListener, CharStream, CommonTokenStream, DefaultErrorStrategy } from "antlr4ng";
12
+ import { MainLexer } from "./lexer.mjs";
13
+ import { CircuitScriptParser } from "./antlr/CircuitScriptParser.mjs";
14
+ import { prepareTokens, SemanticTokensVisitor } from "./SemanticTokenVisitor.mjs";
15
+ import path from "path";
10
16
  export var JSModuleType;
11
17
  (function (JSModuleType) {
12
18
  JSModuleType["CommonJs"] = "cjs";
13
19
  JSModuleType["ESM"] = "mjs";
14
20
  })(JSModuleType || (JSModuleType = {}));
21
+ export function prepareFile(textData) {
22
+ const chars = CharStream.fromString(textData);
23
+ const lexer = new MainLexer(chars);
24
+ const lexerTimer = new SimpleStopwatch();
25
+ const tokens = new CommonTokenStream(lexer);
26
+ tokens.fill();
27
+ const lexerTimeTaken = lexerTimer.lap();
28
+ const parser = new CircuitScriptParser(tokens);
29
+ return {
30
+ parser,
31
+ lexer,
32
+ lexerTimeTaken,
33
+ tokens
34
+ };
35
+ }
36
+ export function getScriptText(filePath) {
37
+ try {
38
+ return readFileSync(filePath, { encoding: 'utf-8' });
39
+ }
40
+ catch (err) {
41
+ return null;
42
+ }
43
+ }
44
+ export function getSemanticTokens(scriptData, options) {
45
+ const { parser, lexer, tokens } = prepareFile(scriptData);
46
+ const tree = parser.script();
47
+ const { currentDirectory = null, defaultLibsPath, } = options;
48
+ const visitor = new SemanticTokensVisitor(true, null, currentDirectory, defaultLibsPath, lexer, scriptData);
49
+ parser.removeErrorListeners();
50
+ visitor.onImportFile = (visitor, textData) => {
51
+ let hasError = false;
52
+ let hasParseError = false;
53
+ if (textData !== null) {
54
+ const { parser } = prepareFile(textData);
55
+ const tree = parser.script();
56
+ try {
57
+ visitor.visit(tree);
58
+ }
59
+ catch (err) {
60
+ console.log('Error while parsing: ', err);
61
+ hasParseError = true;
62
+ hasError = true;
63
+ }
64
+ }
65
+ else {
66
+ console.log('File does not exist');
67
+ hasError = true;
68
+ }
69
+ return {
70
+ hasError, hasParseError
71
+ };
72
+ };
73
+ visitor.visit(tree);
74
+ const semanticTokens = visitor.getTokens();
75
+ const parsedTokens = prepareTokens(tokens.getTokens(), lexer, scriptData);
76
+ const finalParsedTokens = [];
77
+ parsedTokens.forEach(token => {
78
+ const location = `${token.line}_${token.column}`;
79
+ if (semanticTokens.has(location)) {
80
+ finalParsedTokens.push(semanticTokens.get(location));
81
+ }
82
+ else {
83
+ finalParsedTokens.push(token);
84
+ }
85
+ });
86
+ return {
87
+ visitor,
88
+ parsedTokens: finalParsedTokens
89
+ };
90
+ }
91
+ class TokenErrorListener extends BaseErrorListener {
92
+ syntaxError(recognizer, offendingSymbol, line, column, msg, e) {
93
+ console.log(msg);
94
+ }
95
+ }
96
+ export class ParseErrorStrategy extends DefaultErrorStrategy {
97
+ reportUnwantedToken(recognizer) {
98
+ if (this.inErrorRecoveryMode(recognizer)) {
99
+ return;
100
+ }
101
+ this.beginErrorCondition(recognizer);
102
+ const t = recognizer.getCurrentToken();
103
+ const tokenName = this.getTokenErrorDisplay(t);
104
+ const msg = "extraneous input " + tokenName;
105
+ recognizer.notifyErrorListeners(msg, t, null);
106
+ this.endErrorCondition(recognizer);
107
+ }
108
+ }
109
+ export function validateScript(scriptData, options) {
110
+ const { parser } = prepareFile(scriptData);
111
+ parser.removeErrorListeners();
112
+ parser.errorHandler = new ParseErrorStrategy();
113
+ parser.addErrorListener(new TokenErrorListener());
114
+ const tree = parser.script();
115
+ const { currentDirectory = null, defaultLibsPath, } = options;
116
+ const visitor = new SymbolValidatorVisitor(true, null, currentDirectory, defaultLibsPath);
117
+ visitor.onImportFile = (visitor, textData) => {
118
+ let hasError = false;
119
+ let hasParseError = false;
120
+ if (textData !== null) {
121
+ const { parser } = prepareFile(textData);
122
+ const tree = parser.script();
123
+ try {
124
+ visitor.visit(tree);
125
+ }
126
+ catch (err) {
127
+ console.log('got an error while parsing tree: ', err);
128
+ hasParseError = true;
129
+ hasError = true;
130
+ }
131
+ }
132
+ else {
133
+ console.log('file does not exist!');
134
+ hasError = true;
135
+ }
136
+ return {
137
+ hasError, hasParseError
138
+ };
139
+ };
140
+ visitor.visit(tree);
141
+ const symbolTable = visitor.getSymbols();
142
+ symbolTable.clearUndefined();
143
+ const visitorResolver = new SymbolValidatorResolveVisitor(true, null, currentDirectory, defaultLibsPath);
144
+ visitorResolver.setSymbols(visitor.getSymbols());
145
+ visitorResolver.onImportFile = visitor.onImportFile;
146
+ visitorResolver.visit(tree);
147
+ return visitorResolver;
148
+ }
15
149
  export function renderScript(scriptData, outputPath, options) {
16
150
  const { currentDirectory = null, defaultLibsPath, dumpNets = false, dumpData = false, kicadNetlistPath = null, showStats = false } = options;
17
- const visitor = new MainVisitor(true);
18
- visitor.onImportFile = visitor.createImportFileHandler(currentDirectory, defaultLibsPath);
19
- visitor.print('reading file');
20
- visitor.print('done reading file');
151
+ const onErrorHandler = (line, column, message, error) => {
152
+ if (error instanceof VisitorExecutionException) {
153
+ console.log('Error', line, column, message, error.errorMessage);
154
+ }
155
+ };
156
+ const visitor = new ParserVisitor(true, onErrorHandler, currentDirectory, defaultLibsPath);
157
+ visitor.onImportFile = (visitor, fileData) => {
158
+ const { hasError, hasParseError } = parseFileWithVisitor(visitor, fileData);
159
+ return { hasError, hasParseError };
160
+ };
161
+ visitor.log('reading file');
162
+ visitor.log('done reading file');
21
163
  const { tree, parser, hasParseError, hasError, parserTimeTaken, lexerTimeTaken } = parseFileWithVisitor(visitor, scriptData);
22
164
  showStats && console.log('Lexing took:', lexerTimeTaken);
23
165
  showStats && console.log('Parsing took:', parserTimeTaken);
@@ -35,8 +177,11 @@ export function renderScript(scriptData, outputPath, options) {
35
177
  console.log('Error during annotation: ', err);
36
178
  }
37
179
  if (kicadNetlistPath) {
38
- const kicadNetList = generateKiCADNetList(visitor.getNetList());
39
- writeFileSync(kicadNetlistPath, kicadNetList);
180
+ const { tree: kicadNetList, missingFootprints } = generateKiCADNetList(visitor.getNetList());
181
+ missingFootprints.forEach(entry => {
182
+ console.log(`${entry.refdes} (${entry.instanceName}) does not have footprint`);
183
+ });
184
+ writeFileSync(kicadNetlistPath, printTree(kicadNetList));
40
185
  console.log('Generated KiCad netlist file');
41
186
  }
42
187
  const { sequence, nets } = visitor.getGraph();
@@ -91,3 +236,20 @@ export function getCurrentPath() {
91
236
  const filename = context.filename;
92
237
  return { filePath: filename };
93
238
  }
239
+ function getToolsPath() {
240
+ const { filePath } = getCurrentPath();
241
+ return path.normalize(path.dirname(filePath) + '/../../');
242
+ }
243
+ export function getFontsPath() {
244
+ const toolsPath = getToolsPath();
245
+ return path.normalize(toolsPath + "fonts");
246
+ }
247
+ export function getDefaultLibsPath() {
248
+ const toolsPath = getToolsPath();
249
+ return path.normalize(toolsPath + "libs");
250
+ }
251
+ export function getPackageVersion() {
252
+ const packageJson = JSON.parse(readFileSync(getToolsPath() + 'package.json').toString());
253
+ const { version } = packageJson;
254
+ return version;
255
+ }
@@ -11,3 +11,5 @@ export * from './parser.mjs';
11
11
  export * from './render.mjs';
12
12
  export * from './utils.mjs';
13
13
  export * from './visitor.mjs';
14
+ export * from './sizing.mjs';
15
+ export * from './objects/types.mjs';
@@ -393,6 +393,14 @@ export class LayoutEngine {
393
393
  didSetAngle = true;
394
394
  tmpSymbol.angle = component.parameters.get('angle');
395
395
  }
396
+ if (component.parameters.has('flipX')) {
397
+ tmpSymbol.flipX =
398
+ component.parameters.get('flipX');
399
+ }
400
+ if (component.parameters.has('flipY')) {
401
+ tmpSymbol.flipY =
402
+ component.parameters.get('flipY');
403
+ }
396
404
  if (tmpSymbol instanceof SymbolCustom && widthProp) {
397
405
  tmpSymbol.bodyWidth = widthProp;
398
406
  }
@@ -1,6 +1,6 @@
1
- import { CommonToken } from "antlr4";
2
- import CircuitScriptParser from "./antlr/CircuitScriptParser.mjs";
3
- import CircuitScriptLexer from "./antlr/CircuitScriptLexer.mjs";
1
+ import { CommonToken } from "antlr4ng";
2
+ import { CircuitScriptParser } from "./antlr/CircuitScriptParser.mjs";
3
+ import { CircuitScriptLexer } from "./antlr/CircuitScriptLexer.mjs";
4
4
  export class MainLexer extends CircuitScriptLexer {
5
5
  tokens;
6
6
  indents;
@@ -22,7 +22,7 @@ export class MainLexer extends CircuitScriptLexer {
22
22
  this.tokens.push(token);
23
23
  }
24
24
  nextToken() {
25
- if (this._input.LA(1) === CircuitScriptParser.EOF && this.indents.length) {
25
+ if (this.inputStream.LA(1) === CircuitScriptParser.EOF && this.indents.length) {
26
26
  this.tokens = this.tokens.filter(function (val) {
27
27
  return val.type !== CircuitScriptParser.EOF;
28
28
  });
@@ -40,20 +40,20 @@ export class MainLexer extends CircuitScriptLexer {
40
40
  return this.commonToken(CircuitScriptParser.DEDENT, "");
41
41
  }
42
42
  getCharIndex() {
43
- return this._input.index;
43
+ return this.inputStream.index;
44
44
  }
45
45
  commonToken(type, text) {
46
46
  const stop = this.getCharIndex() - 1;
47
47
  const start = text.length ? stop - text.length + 1 : stop;
48
- const token = new CommonToken([this, this._input], type, 0, start, stop);
49
- let tokenTypeString;
48
+ const token = CommonToken.fromSource([this, this.inputStream], type, 0, start, stop);
49
+ let tokenTypeString = null;
50
50
  if (type === CircuitScriptParser.INDENT) {
51
51
  tokenTypeString = "indent";
52
52
  }
53
53
  else if (type === CircuitScriptParser.DEDENT) {
54
54
  tokenTypeString = "dedent";
55
55
  }
56
- if (tokenTypeString) {
56
+ if (tokenTypeString !== null) {
57
57
  token.text = tokenTypeString;
58
58
  }
59
59
  return token;
@@ -82,8 +82,8 @@ export class MainLexer extends CircuitScriptLexer {
82
82
  onNewLine() {
83
83
  const newLine = this.text.replace(/[^\r\n]+/g, '');
84
84
  const spaces = this.text.replace(/[\r\n]+/g, '');
85
- const next = this._input.LA(1);
86
- const nextnext = this._input.LA(2);
85
+ const next = this.inputStream.LA(1);
86
+ const nextnext = this.inputStream.LA(2);
87
87
  if (this.opened > 0 || (nextnext != -1 &&
88
88
  (next === 13 || next === 10 || next === 35))) {
89
89
  this.skip();
package/dist/esm/main.mjs CHANGED
@@ -4,22 +4,17 @@ import figlet from 'figlet';
4
4
  import path from 'path';
5
5
  import { readFileSync, watch } from 'fs';
6
6
  import { prepareSVGEnvironment } from './sizing.mjs';
7
- import { getCurrentPath, renderScript } from './helpers.mjs';
7
+ import { getDefaultLibsPath, getFontsPath, getPackageVersion, renderScript } from './helpers.mjs';
8
8
  export default async function main() {
9
- const { filePath } = getCurrentPath();
10
- const toolSrcPath = filePath;
11
- const toolDirectory = path.dirname(toolSrcPath) + '/../../';
12
- const fontsPath = toolDirectory + '/fonts';
13
- const defaultLibsPath = toolDirectory + '/libs';
14
- const packageJson = JSON.parse(readFileSync(toolDirectory + 'package.json').toString());
15
- ;
16
- const { version } = packageJson;
9
+ const fontsPath = getFontsPath();
10
+ const defaultLibsPath = getDefaultLibsPath();
11
+ const version = getPackageVersion();
17
12
  program
18
13
  .description('generate graphical output from circuitscript files')
19
14
  .version(version)
15
+ .argument('[input path]', 'Input path')
16
+ .argument('[output path]', 'Output path')
20
17
  .option('-i, --input text <input text>', 'Input text directly')
21
- .option('-f, --input-file <path>', 'Input file')
22
- .option('-o, --output <path>', 'Output path')
23
18
  .option('-c, --current-directory <path>', 'Set current directory')
24
19
  .option('-k, --kicad-netlist <filename>', 'Create KiCad netlist')
25
20
  .option('-w, --watch', 'Watch for file changes')
@@ -34,8 +29,8 @@ export default async function main() {
34
29
  }
35
30
  program.parse();
36
31
  const options = program.opts();
32
+ const args = program.args;
37
33
  const watchFileChanges = options.watch;
38
- const outputPath = options.output ?? null;
39
34
  const dumpNets = options.dumpNets;
40
35
  const dumpData = options.dumpData;
41
36
  const kicadNetlist = options.kicadNetlist;
@@ -44,19 +39,27 @@ export default async function main() {
44
39
  console.log('watching for file changes...');
45
40
  }
46
41
  await prepareSVGEnvironment(fontsPath);
47
- let inputFilePath = null;
48
- let scriptData;
49
- if (options.input) {
50
- scriptData = options.input;
42
+ let inputFilePath = "";
43
+ if (args.length > 2) {
44
+ console.log("Error: Extra arguments passed");
45
+ return;
51
46
  }
52
- else {
53
- inputFilePath = options.inputFile;
47
+ let scriptData;
48
+ if (args.length > 0 && args[0]) {
49
+ inputFilePath = args[0];
54
50
  scriptData = readFileSync(inputFilePath, { encoding: 'utf-8' });
55
51
  if (currentDirectory === null) {
56
52
  currentDirectory = path.dirname(inputFilePath);
57
53
  }
58
54
  }
59
- const renderOptions = {
55
+ else if (options.input) {
56
+ scriptData = options.input;
57
+ }
58
+ else {
59
+ console.log("Error: No input provided");
60
+ return;
61
+ }
62
+ const scriptOptions = {
60
63
  currentDirectory,
61
64
  defaultLibsPath,
62
65
  dumpNets,
@@ -64,7 +67,11 @@ export default async function main() {
64
67
  kicadNetlistPath: kicadNetlist,
65
68
  showStats: options.stats,
66
69
  };
67
- const output = renderScript(scriptData, outputPath, renderOptions);
70
+ let outputPath = null;
71
+ if (args.length > 0 && args[1]) {
72
+ outputPath = args[1];
73
+ }
74
+ const output = renderScript(scriptData, outputPath, scriptOptions);
68
75
  if (outputPath === null && output) {
69
76
  console.log(output);
70
77
  }
@@ -72,7 +79,7 @@ export default async function main() {
72
79
  watch(inputFilePath, event => {
73
80
  if (event === 'change') {
74
81
  const scriptData = readFileSync(inputFilePath, { encoding: 'utf-8' });
75
- renderScript(scriptData, outputPath, renderOptions);
82
+ renderScript(scriptData, outputPath, scriptOptions);
76
83
  console.log('done');
77
84
  }
78
85
  });
@@ -17,6 +17,7 @@ export class ClassComponent {
17
17
  displayProp = null;
18
18
  widthProp = null;
19
19
  typeProp = null;
20
+ copyProp = false;
20
21
  styles = {};
21
22
  assignedRefDes = null;
22
23
  constructor(instanceName, numPins, className) {
@@ -129,6 +130,9 @@ export class ClassComponent {
129
130
  }
130
131
  }
131
132
  for (const [key, value] of this.parameters) {
133
+ if (key === 'flipX' || key === 'flipY' || key === 'angle') {
134
+ continue;
135
+ }
132
136
  component.parameters.set(key, value);
133
137
  }
134
138
  for (const [key, value] of this.pins) {
@@ -4,6 +4,7 @@ export class ExecutionScope {
4
4
  instances = new Map();
5
5
  functions = new Map();
6
6
  variables = new Map();
7
+ symbols = new Map();
7
8
  blockStack = new Map();
8
9
  wires = [];
9
10
  frames = [];
@@ -4,3 +4,9 @@ export class UndeclaredReference {
4
4
  this.reference = reference;
5
5
  }
6
6
  }
7
+ export var ParseSymbolType;
8
+ (function (ParseSymbolType) {
9
+ ParseSymbolType["Variable"] = "variable";
10
+ ParseSymbolType["Function"] = "function";
11
+ ParseSymbolType["Undefined"] = "undefined";
12
+ })(ParseSymbolType || (ParseSymbolType = {}));