circuitscript 0.5.5 → 0.5.7

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.
package/README.md CHANGED
@@ -1,3 +1,106 @@
1
- # circuitscript
1
+ # Circuitscript
2
2
 
3
- CLI tool for the [circuitscript language](https://circuitscript.net)
3
+ A code-based language for creating electronic schematics. Instead of clicking through GUI tools, you write Circuitscript to describe circuits — and get SVG/PDF schematics and KiCAD-compatible netlists as output.
4
+
5
+ **Homepage:** https://circuitscript.net
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ - **Code-first design** — capture schematics using a simple scripting language
12
+ - **Version control friendly** — plain text files work naturally with git
13
+ - **SVG and PDF output** — high-quality schematic diagrams
14
+ - **KiCAD netlist export** — use generated netlists directly in KiCAD layout
15
+ - **Bill of Materials** — export BOM as CSV
16
+ - **Programmatic constructs** — loops, functions, conditionals, and modules for reusable circuit blocks
17
+ - **Standard library of components** — resistors, capacitors, inductors, LEDs, etc.
18
+ - **Custom components** — define components with arbitrary pin layouts and graphics
19
+ - **ERC** — basic electrical rules check (more to be added)
20
+
21
+ ---
22
+
23
+ ## Installation
24
+
25
+ Requires Node.js 16 or later.
26
+
27
+ ```bash
28
+ npm install -g circuitscript
29
+ ```
30
+
31
+ Or install locally as a library:
32
+
33
+ ```bash
34
+ npm install circuitscript
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Quick Start
40
+
41
+ Create a file `circuit.cst`:
42
+
43
+ ```
44
+ from "std" import *
45
+
46
+ v5 = supply("5V")
47
+ gnd = dgnd()
48
+
49
+ at v5
50
+ wire down 100
51
+ add res(100k)
52
+ wire down 100
53
+ to gnd
54
+
55
+ at v5
56
+ wire down 100
57
+ add cap(100n)
58
+ wire down 100
59
+ to gnd
60
+ ```
61
+
62
+ Generate a schematic:
63
+
64
+ ```bash
65
+ circuitscript circuit.cst output.svg
66
+ ```
67
+
68
+ ---
69
+
70
+ ## CLI Usage
71
+
72
+ ```
73
+ circuitscript [input path] [output path] [options]
74
+ ```
75
+
76
+ ### Options
77
+
78
+ | Option | Description |
79
+ |--------|-------------|
80
+ | `-w, --watch` | Watch for file changes and regenerate |
81
+ | `-u, --update-source` | Update source file with reference designator annotation |
82
+ | `-j, --annotated-path [file]` | Save annotated source file at given path |
83
+ | `-n, --dump-nets` | Print net information |
84
+ | `-d, --dump-data` | Dump data during parsing |
85
+ | `-s, --stats` | Show stats during generation |
86
+ | `-x, --skip-output` | Skip output generation |
87
+ | `-e, --erc` | Enable ERC output |
88
+ | `-b, --bom [output-path]` | Generate Bill of Materials as CSV |
89
+ | `-i, --input text <text>` | Provide input text directly instead of a file |
90
+ | `--version` | Show version |
91
+
92
+ ### Examples
93
+
94
+ ```bash
95
+ # Generate SVG
96
+ circuitscript schematic.cst schematic.svg
97
+
98
+ # Generate PDF
99
+ circuitscript schematic.cst schematic.pdf
100
+
101
+ # Generate BOM
102
+ circuitscript schematic.cst schematic.svg --bom bom.csv
103
+
104
+ # Print to stdout
105
+ circuitscript schematic.cst
106
+ ```
@@ -374,6 +374,7 @@ class ExecutionContext {
374
374
  this.applyComponentAngleFromWire(component, pinId);
375
375
  this.scope.setCurrent(component, pinId);
376
376
  this.scope.clearActive();
377
+ this.log('clear active wire/frame (to component)');
377
378
  if (addSequence) {
378
379
  if (this.scope.sequence.length > 0) {
379
380
  const [entryType, , segments] = this.scope.sequence[this.scope.sequence.length - 1];
@@ -410,6 +411,7 @@ class ExecutionContext {
410
411
  this.scope.setNet(component, usePinId, tmpNet);
411
412
  }
412
413
  this.scope.clearActive();
414
+ this.log('clear active wire/frame (at component)');
413
415
  if (addSequence) {
414
416
  this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.At,
415
417
  component, usePinId]);
@@ -448,8 +450,12 @@ class ExecutionContext {
448
450
  || blockType === BlockTypes_js_1.BlockTypes.Parallel
449
451
  || blockType === BlockTypes_js_1.BlockTypes.Branch) {
450
452
  const key = (0, utils_js_1.getBlockTypeString)(blockType);
453
+ const wireIdBefore = this.scope.currentWireId;
451
454
  this.addPoint(`${globals_js_1.Delimiter1}${key}.${this.name}.${this.tmpPointId}`, false);
452
455
  this.tmpPointId += 1;
456
+ if (wireIdBefore !== -1) {
457
+ this.scope.currentWireId = wireIdBefore;
458
+ }
453
459
  }
454
460
  this.scope.blockStack.set(this.scope.scopeLevel, {
455
461
  start_point: [
package/dist/cjs/index.js CHANGED
@@ -31,6 +31,7 @@ __exportStar(require("./parser.js"), exports);
31
31
  __exportStar(require("./utils.js"), exports);
32
32
  __exportStar(require("./visitor.js"), exports);
33
33
  __exportStar(require("./sizing.js"), exports);
34
+ __exportStar(require("./errors.js"), exports);
34
35
  __exportStar(require("./objects/types.js"), exports);
35
36
  __exportStar(require("./builtinMethods.js"), exports);
36
37
  __exportStar(require("./validate/SymbolTable.js"), exports);
@@ -9,13 +9,15 @@ const environment_js_1 = require("./environment/environment.js");
9
9
  const mainDir = './__tests__/testData/renderData/';
10
10
  const env = new environment_js_1.NodeScriptEnvironment();
11
11
  environment_js_1.NodeScriptEnvironment.setInstance(env);
12
- async function regenerateTests(extra = "") {
12
+ async function regenerateTests(extra = "", fileList = []) {
13
13
  await env.prepareSVGEnvironment();
14
14
  const cstFiles = [];
15
15
  const files = fs_1.default.readdirSync(mainDir);
16
16
  files.forEach(file => {
17
17
  if (file.endsWith('.cst') && file.startsWith('script')) {
18
- cstFiles.push(file);
18
+ if (fileList.length === 0 || fileList.includes(file)) {
19
+ cstFiles.push(file);
20
+ }
19
21
  }
20
22
  });
21
23
  for (let i = 0; i < cstFiles.length; i++) {
@@ -38,8 +40,15 @@ async function regenerateTests(extra = "") {
38
40
  (async () => {
39
41
  const generateDiff = (process.argv.indexOf('-diff') !== -1);
40
42
  console.log('diff flag: ', generateDiff);
43
+ const listIndex = process.argv.indexOf('--list');
44
+ const fileList = listIndex !== -1 && process.argv[listIndex + 1]
45
+ ? process.argv[listIndex + 1].split(',').map(f => f.trim())
46
+ : [];
47
+ if (fileList.length > 0) {
48
+ console.log('filtering to files: ', fileList);
49
+ }
41
50
  const nextExtra = generateDiff ? '.next' : '';
42
- const cstFiles = await regenerateTests(nextExtra);
51
+ const cstFiles = await regenerateTests(nextExtra, fileList);
43
52
  const allFiles = [];
44
53
  if (generateDiff) {
45
54
  cstFiles.forEach(file => {
@@ -379,6 +379,7 @@ export class ExecutionContext {
379
379
  this.applyComponentAngleFromWire(component, pinId);
380
380
  this.scope.setCurrent(component, pinId);
381
381
  this.scope.clearActive();
382
+ this.log('clear active wire/frame (to component)');
382
383
  if (addSequence) {
383
384
  if (this.scope.sequence.length > 0) {
384
385
  const [entryType, , segments] = this.scope.sequence[this.scope.sequence.length - 1];
@@ -415,6 +416,7 @@ export class ExecutionContext {
415
416
  this.scope.setNet(component, usePinId, tmpNet);
416
417
  }
417
418
  this.scope.clearActive();
419
+ this.log('clear active wire/frame (at component)');
418
420
  if (addSequence) {
419
421
  this.scope.sequence.push([SequenceAction.At,
420
422
  component, usePinId]);
@@ -453,8 +455,12 @@ export class ExecutionContext {
453
455
  || blockType === BlockTypes.Parallel
454
456
  || blockType === BlockTypes.Branch) {
455
457
  const key = getBlockTypeString(blockType);
458
+ const wireIdBefore = this.scope.currentWireId;
456
459
  this.addPoint(`${Delimiter1}${key}.${this.name}.${this.tmpPointId}`, false);
457
460
  this.tmpPointId += 1;
461
+ if (wireIdBefore !== -1) {
462
+ this.scope.currentWireId = wireIdBefore;
463
+ }
458
464
  }
459
465
  this.scope.blockStack.set(this.scope.scopeLevel, {
460
466
  start_point: [
package/dist/esm/index.js CHANGED
@@ -15,6 +15,7 @@ export * from './parser.js';
15
15
  export * from './utils.js';
16
16
  export * from './visitor.js';
17
17
  export * from './sizing.js';
18
+ export * from './errors.js';
18
19
  export * from './objects/types.js';
19
20
  export * from './builtinMethods.js';
20
21
  export * from './validate/SymbolTable.js';
@@ -4,13 +4,15 @@ import { NodeScriptEnvironment } from "./environment/environment.js";
4
4
  const mainDir = './__tests__/testData/renderData/';
5
5
  const env = new NodeScriptEnvironment();
6
6
  NodeScriptEnvironment.setInstance(env);
7
- async function regenerateTests(extra = "") {
7
+ async function regenerateTests(extra = "", fileList = []) {
8
8
  await env.prepareSVGEnvironment();
9
9
  const cstFiles = [];
10
10
  const files = fs.readdirSync(mainDir);
11
11
  files.forEach(file => {
12
12
  if (file.endsWith('.cst') && file.startsWith('script')) {
13
- cstFiles.push(file);
13
+ if (fileList.length === 0 || fileList.includes(file)) {
14
+ cstFiles.push(file);
15
+ }
14
16
  }
15
17
  });
16
18
  for (let i = 0; i < cstFiles.length; i++) {
@@ -33,8 +35,15 @@ async function regenerateTests(extra = "") {
33
35
  (async () => {
34
36
  const generateDiff = (process.argv.indexOf('-diff') !== -1);
35
37
  console.log('diff flag: ', generateDiff);
38
+ const listIndex = process.argv.indexOf('--list');
39
+ const fileList = listIndex !== -1 && process.argv[listIndex + 1]
40
+ ? process.argv[listIndex + 1].split(',').map(f => f.trim())
41
+ : [];
42
+ if (fileList.length > 0) {
43
+ console.log('filtering to files: ', fileList);
44
+ }
36
45
  const nextExtra = generateDiff ? '.next' : '';
37
- const cstFiles = await regenerateTests(nextExtra);
46
+ const cstFiles = await regenerateTests(nextExtra, fileList);
38
47
  const allFiles = [];
39
48
  if (generateDiff) {
40
49
  cstFiles.forEach(file => {
@@ -15,6 +15,7 @@ export * from './parser.js';
15
15
  export * from './utils.js';
16
16
  export * from './visitor.js';
17
17
  export * from './sizing.js';
18
+ export * from './errors.js';
18
19
  export * from './objects/types.js';
19
20
  export * from './builtinMethods.js';
20
21
  export * from './validate/SymbolTable.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circuitscript",
3
- "version": "0.5.5",
3
+ "version": "0.5.7",
4
4
  "description": "Interpreter for the circuitscript language",
5
5
  "homepage": "https://circuitscript.net",
6
6
  "engines": {
@@ -24,12 +24,14 @@
24
24
  "libs"
25
25
  ],
26
26
  "devDependencies": {
27
+ "@resvg/resvg-js": "^2.6.2",
27
28
  "@types/big.js": "^6.2.2",
28
29
  "@types/crypto-js": "^4.2.2",
29
30
  "@types/figlet": "^1.5.8",
30
31
  "@types/jest": "~29.5",
31
32
  "@types/node": "~18",
32
33
  "@types/pdfkit": "^0.13.6",
34
+ "@types/pngjs": "^6.0.5",
33
35
  "@types/svg-to-pdfkit": "^0.1.3",
34
36
  "@types/svgdom": "^0.1.2",
35
37
  "@typescript-eslint/eslint-plugin": "~5.59",
@@ -39,6 +41,9 @@
39
41
  "eslint-config-prettier": "~8.8",
40
42
  "eslint-plugin-jest": "~27.2",
41
43
  "jest": "~29.5",
44
+ "license-check-and-add": "^4.0.5",
45
+ "pixelmatch": "^7.1.0",
46
+ "pngjs": "^7.0.0",
42
47
  "prettier": "~2.8",
43
48
  "rimraf": "~5.0",
44
49
  "source-map-support": "^0.5.21",
@@ -76,7 +81,9 @@
76
81
  "changelog": "auto-changelog --handlebars-setup ../changelog/helper.js -p",
77
82
  "preversion": "npm run test",
78
83
  "version": "npm run changelog && git add CHANGELOG.md",
79
- "copy-assets": "mkdir -p dist/fonts && mkdir -p dist/libs && cp -r fonts dist/ && cp -r libs dist/"
84
+ "copy-assets": "mkdir -p dist/fonts && mkdir -p dist/libs && cp -r fonts dist/ && cp -r libs dist/",
85
+ "license:check": "license-check-and-add check -f licensecheck.json",
86
+ "license:add": "license-check-and-add add -f licensecheck.json"
80
87
  },
81
88
  "boilerplate_author": "Jakub Synowiec <jsynowiec@users.noreply.github.com>",
82
89
  "license": "MIT",