circuitscript 0.0.7 → 0.0.13
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/.gitlab-ci.yml +23 -17
- package/README.md +1 -1
- package/__tests__/helpers.ts +18 -16
- package/__tests__/renderData/script5.cst +23 -0
- package/__tests__/renderData/script5.cst.svg +1 -0
- package/__tests__/testCLI.ts +68 -0
- package/__tests__/testMathOps.ts +1 -1
- package/__tests__/testRender.ts +10 -9
- package/build/src/draw_symbols.js +3 -2
- package/build/src/main.js +25 -18
- package/build/src/parser.js +0 -6
- package/build/src/sizing.js +2 -2
- package/build/src/visitor.js +34 -15
- package/examples/example_arduino_uno.cst +159 -138
- package/jest.config.js +23 -0
- package/libs/lib.cst +190 -0
- package/package.json +2 -22
- package/src/antlr/CircuitScriptLexer.ts +2 -0
- package/src/antlr/CircuitScriptParser.ts +2 -0
- package/src/antlr/CircuitScriptVisitor.ts +2 -0
- package/src/draw_symbols.ts +5 -3
- package/src/main.ts +27 -21
- package/src/parser.ts +6 -6
- package/src/sizing.ts +2 -2
- package/src/visitor.ts +45 -16
- package/tsconfig.json +4 -1
- /package/{server.js → server.cjs} +0 -0
package/.gitlab-ci.yml
CHANGED
|
@@ -10,7 +10,8 @@ variables:
|
|
|
10
10
|
|
|
11
11
|
stages:
|
|
12
12
|
- prepare
|
|
13
|
-
|
|
13
|
+
- test_jest
|
|
14
|
+
- test_build
|
|
14
15
|
- publish
|
|
15
16
|
|
|
16
17
|
# Installs all dependencies.
|
|
@@ -26,27 +27,33 @@ install:
|
|
|
26
27
|
when: on_success
|
|
27
28
|
expire_in: 12h
|
|
28
29
|
script:
|
|
29
|
-
- npm config set -- '//registry.npmjs.org/:_authToken' "${NPM_AUTH_TOKEN}"
|
|
30
30
|
- npm install --no-progress --no-audit --no-fund --verbose
|
|
31
|
-
- npm run build:release || true
|
|
32
31
|
# only:
|
|
33
32
|
# - merge_requests
|
|
34
33
|
# - develop
|
|
35
34
|
# - main
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
test_jest:
|
|
37
|
+
stage: test_jest
|
|
38
|
+
interruptible: true
|
|
39
|
+
retry: 1
|
|
40
|
+
dependencies:
|
|
41
|
+
- install
|
|
42
|
+
script:
|
|
43
|
+
- npm run build:release || true
|
|
44
|
+
- npm run test
|
|
45
|
+
|
|
46
|
+
test_build:
|
|
47
|
+
stage: test_build
|
|
48
|
+
interruptible: true
|
|
49
|
+
retry: 1
|
|
50
|
+
dependencies:
|
|
51
|
+
- install
|
|
52
|
+
script:
|
|
53
|
+
- npm run build:release || true
|
|
54
|
+
- ls
|
|
55
|
+
- ls build
|
|
56
|
+
- node build/src/main.js
|
|
50
57
|
|
|
51
58
|
# Publishes the package to npm.
|
|
52
59
|
publish:
|
|
@@ -57,7 +64,6 @@ publish:
|
|
|
57
64
|
script:
|
|
58
65
|
- npm config set -- '//registry.npmjs.org/:_authToken' "${NPM_AUTH_TOKEN}"
|
|
59
66
|
- npm run build:release || true
|
|
60
|
-
- ls build/src
|
|
61
67
|
- npm publish --verbose
|
|
62
68
|
resource_group: 'deployment-$CI_COMMIT_REF_SLUG'
|
|
63
69
|
# rules:
|
package/README.md
CHANGED
package/__tests__/helpers.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import
|
|
2
|
-
import fs from 'fs';
|
|
1
|
+
import { dirname } from 'path';
|
|
3
2
|
|
|
4
|
-
import CircuitScriptParser from '../src/antlr/CircuitScriptParser';
|
|
3
|
+
import CircuitScriptParser from '../src/antlr/CircuitScriptParser.js';
|
|
5
4
|
|
|
6
5
|
import { CharStream, CommonTokenStream } from 'antlr4';
|
|
7
|
-
import { MainVisitor } from '../src/visitor';
|
|
8
|
-
import { ComponentPinNet } from '../src/objects/types';
|
|
9
|
-
import { CircuitscriptParserErrorListener
|
|
10
|
-
import { ClassComponent } from '../src/objects/ClassComponent';
|
|
11
|
-
import { MainLexer } from '../src/lexer';
|
|
6
|
+
import { MainVisitor } from '../src/visitor.js';
|
|
7
|
+
import { ComponentPinNet } from '../src/objects/types.js';
|
|
8
|
+
import { CircuitscriptParserErrorListener } from '../src/parser.js';
|
|
9
|
+
import { ClassComponent } from '../src/objects/ClassComponent.js';
|
|
10
|
+
import { MainLexer } from '../src/lexer.js';
|
|
12
11
|
|
|
13
12
|
|
|
14
|
-
export async function runScript(script: string): Promise<{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
export async function runScript(script: string): Promise<{
|
|
14
|
+
visitor: MainVisitor,
|
|
15
|
+
hasError: boolean,
|
|
16
|
+
componentPinNets: ComponentPinNet[]
|
|
17
|
+
}> {
|
|
18
|
+
|
|
18
19
|
const chars = new CharStream(script);
|
|
19
20
|
const lexer = new MainLexer(chars);
|
|
20
21
|
const tokens = new CommonTokenStream(lexer);
|
|
@@ -25,21 +26,22 @@ export async function runScript(script: string): Promise<{visitor: MainVisitor,
|
|
|
25
26
|
|
|
26
27
|
const errorListener = new CircuitscriptParserErrorListener();
|
|
27
28
|
parser.addErrorListener(errorListener);
|
|
28
|
-
|
|
29
|
+
|
|
29
30
|
const tree = parser.script();
|
|
30
31
|
|
|
31
32
|
const scriptPath = "./examples/helpers.ts";
|
|
33
|
+
const defaultLibsPath = "./libs";
|
|
32
34
|
|
|
33
35
|
const visitor = new MainVisitor(true);
|
|
34
36
|
visitor.printToConsole = false; // do not clutter the console log
|
|
35
37
|
|
|
36
|
-
const currentDirectory =
|
|
37
|
-
visitor.onImportFile = visitor.createImportFileHandler(currentDirectory);
|
|
38
|
+
const currentDirectory = dirname(scriptPath);
|
|
39
|
+
visitor.onImportFile = visitor.createImportFileHandler(currentDirectory, defaultLibsPath);
|
|
38
40
|
|
|
39
41
|
let hasError = false;
|
|
40
42
|
try {
|
|
41
43
|
visitor.visit(tree);
|
|
42
|
-
} catch (err){
|
|
44
|
+
} catch (err) {
|
|
43
45
|
// Error should be internally handled in visitor
|
|
44
46
|
err.print(script);
|
|
45
47
|
hasError = true;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import lib
|
|
2
|
+
|
|
3
|
+
v5v = supply("5v")
|
|
4
|
+
gnd = dgnd()
|
|
5
|
+
|
|
6
|
+
at gnd
|
|
7
|
+
wire up 20 right 20
|
|
8
|
+
to D1 = led("GREEN") pin 2 right
|
|
9
|
+
at D1 pin 1
|
|
10
|
+
wire right 20 up 20
|
|
11
|
+
to v5v
|
|
12
|
+
|
|
13
|
+
at v5v
|
|
14
|
+
wire down 20 right 20
|
|
15
|
+
add led("RED")
|
|
16
|
+
wire right 20 down 20
|
|
17
|
+
to gnd
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
#wire down 20
|
|
21
|
+
#add led("GREEN")
|
|
22
|
+
#wire down 20
|
|
23
|
+
#to gnd
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="190" height="310.5" viewBox="-25 -25.5 190 310.5"><g transform="matrix(1,0,0,1,0,0)"><path d="M -20 -20.5 L -20 280 M 0 -20.5 L 0 280 M 20 -20.5 L 20 280 M 40 -20.5 L 40 280 M 60 -20.5 L 60 280 M 80 -20.5 L 80 280 M 100 -20.5 L 100 280 M 120 -20.5 L 120 280 M 140 -20.5 L 140 280 M 160 -20.5 L 160 280" fill="none" stroke-dasharray="1,19" stroke-width="1" stroke="#aaaaaa"></path></g><g transform="matrix(1,0,0,1,20,90)"><g><path d="M -10 0 L 10 0 L 0 10 Z" stroke-width="1" stroke="#333333" fill="#ffffff"></path><path d="M 0 -10 L 0 0" stroke-width="2" stroke="#333333"></path><text fill="#333333" font-family="Inter" font-size="10" text-anchor="middle" dominant-baseline="text-top" transform="matrix(1,0,0,1,0,20)" svgjs:data="{"leading":"1.3"}"><tspan dy="0" x="0" svgjs:data="{"newLined":true}">GND</tspan></text></g></g><g transform="matrix(1,0,0,1,70,60)"><g><path d="M -10.000000000000002 9.999999999999998 L -9.999999999999998 -10.000000000000002" stroke-width="1" stroke="#333333" fill="none"></path><path d="M 9.999999999999998 10.000000000000002 L 10.000000000000002 -9.999999999999998 L -10 -1.2246467991473533e-15 Z" stroke-width="1" stroke="#333333" fill="#ffffff"></path><path d="M 9.797174393178826e-16 -8 L -4.999999999999998 -18" stroke-width="1" stroke="#333333" fill="none"></path><path d="M -2.999999999999999 -8 L -7.999999999999998 -18" stroke-width="1" stroke="#333333" fill="none"></path><path d="M 30 3.67394039744206e-15 L 10 1.2246467991473533e-15 M -30 -3.67394039744206e-15 L -10 -1.2246467991473533e-15" stroke-width="2" stroke="#333333"></path><text fill="#333333" font-family="Inter" font-size="10" text-anchor="end" dominant-baseline="hanging" transform="matrix(1,0,0,1,-15,5)" svgjs:data="{"leading":"1.3"}"><tspan dy="0" x="0" svgjs:data="{"newLined":true}">D1</tspan></text></g></g><g transform="matrix(1,0,0,1,120,30.000000000000007)"><g><path d="M -15 0 L 15 0" stroke-width="1" stroke="#333333" fill="none"></path><path d="M 0 10 L 0 0" stroke-width="2" stroke="#333333"></path><text fill="#333333" font-family="Inter" font-size="10" text-anchor="middle" dominant-baseline="text-top" transform="matrix(1,0,0,1,0,-5)" svgjs:data="{"leading":"1.3"}"><tspan dy="0" x="0" svgjs:data="{"newLined":true}">5v</tspan></text></g></g><g transform="matrix(1,0,0,1,20,170)"><g><path d="M -15 0 L 15 0" stroke-width="1" stroke="#333333" fill="none"></path><path d="M 0 10 L 0 0" stroke-width="2" stroke="#333333"></path><text fill="#333333" font-family="Inter" font-size="10" text-anchor="middle" dominant-baseline="text-top" transform="matrix(1,0,0,1,0,-5)" svgjs:data="{"leading":"1.3"}"><tspan dy="0" x="0" svgjs:data="{"newLined":true}">5v</tspan></text></g></g><g transform="matrix(1,0,0,1,70,200)"><g><path d="M 10 -10 L 10 10" stroke-width="1" stroke="#333333" fill="none"></path><path d="M -10 -10 L -10 10 L 10 0 Z" stroke-width="1" stroke="#333333" fill="#ffffff"></path><path d="M 0 8 L 5 18" stroke-width="1" stroke="#333333" fill="none"></path><path d="M 3 8 L 8 18" stroke-width="1" stroke="#333333" fill="none"></path><path d="M -30 0 L -10 0 M 30 0 L 10 0" stroke-width="2" stroke="#333333"></path><text fill="#333333" font-family="Inter" font-size="10" text-anchor="start" dominant-baseline="hanging" transform="matrix(1,0,0,1,15,5)" svgjs:data="{"leading":"1.3"}"><tspan dy="0" x="0" svgjs:data="{"newLined":true}">D2</tspan></text></g></g><g transform="matrix(1,0,0,1,120,230)"><g><path d="M -10 0 L 10 0 L 0 10 Z" stroke-width="1" stroke="#333333" fill="#ffffff"></path><path d="M 0 -10 L 0 0" stroke-width="2" stroke="#333333"></path><text fill="#333333" font-family="Inter" font-size="10" text-anchor="middle" dominant-baseline="text-top" transform="matrix(1,0,0,1,0,20)" svgjs:data="{"leading":"1.3"}"><tspan dy="0" x="0" svgjs:data="{"newLined":true}">GND</tspan></text></g></g><g><line x1="20" y1="80" x2="20" y2="60" stroke-linecap="square" stroke-width="1" stroke="#008400" fill="none"></line><line x1="20" y1="60" x2="40" y2="60" stroke-linecap="square" stroke-width="1" stroke="#008400" fill="none"></line><line x1="100" y1="200" x2="120" y2="200" stroke-linecap="square" stroke-width="1" stroke="#008400" fill="none"></line><line x1="120" y1="200" x2="120" y2="220" stroke-linecap="square" stroke-width="1" stroke="#008400" fill="none"></line><line x1="100" y1="60.00000000000001" x2="120" y2="60.00000000000001" stroke-linecap="square" stroke-width="1" stroke="#008400" fill="none"></line><line x1="120" y1="60.00000000000001" x2="120" y2="40.00000000000001" stroke-linecap="square" stroke-width="1" stroke="#008400" fill="none"></line><line x1="20" y1="180" x2="20" y2="200" stroke-linecap="square" stroke-width="1" stroke="#008400" fill="none"></line><line x1="20" y1="200" x2="40" y2="200" stroke-linecap="square" stroke-width="1" stroke="#008400" fill="none"></line></g><g></g></svg>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import figlet from 'figlet';
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync } from 'fs';
|
|
4
|
+
|
|
5
|
+
describe('test cli program', () => {
|
|
6
|
+
|
|
7
|
+
const tmpFolder = '__tests__/tmp';
|
|
8
|
+
|
|
9
|
+
const baseCommand = 'node build/src/main.js';
|
|
10
|
+
|
|
11
|
+
test('start program and display help', () => {
|
|
12
|
+
const result = execSync(baseCommand).toString();
|
|
13
|
+
const circuitscriptText = figlet.textSync('circuitscript', {
|
|
14
|
+
font: 'Small Slant'
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
expect(result.includes(circuitscriptText)).toBe(true);
|
|
18
|
+
|
|
19
|
+
const options =
|
|
20
|
+
`Options:
|
|
21
|
+
-V, --version output the version number
|
|
22
|
+
-i, --input text <input text> Input text directly
|
|
23
|
+
-f, --input-file <path> Input file
|
|
24
|
+
-o, --output <path> Output path
|
|
25
|
+
-c, --current-directory <path> Set current directory
|
|
26
|
+
-k, --kicad-netlist <filename> Create KiCad netlist
|
|
27
|
+
-w, --watch Watch for file changes
|
|
28
|
+
-n, --dump-nets Dump out net information
|
|
29
|
+
-d, --dump-data Dump data during parsing
|
|
30
|
+
-s, --stats Show stats during generation
|
|
31
|
+
-h, --help display help for command`
|
|
32
|
+
|
|
33
|
+
expect(result.includes(options)).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('pass in file and output directly', () => {
|
|
37
|
+
const result = execSync(baseCommand + ' -f __tests__/renderData/script1.cst').toString();
|
|
38
|
+
const expected = readFileSync('__tests__/renderData/script1.cst.svg').toString();
|
|
39
|
+
expect(result.trim()).toBe(expected);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test.each([false, true])('pass in file and output file (with stats: %s)', (withStatsFlag: boolean) => {
|
|
43
|
+
const outputPath = '__tests__/tmp/result1.svg';
|
|
44
|
+
if (existsSync(outputPath)) {
|
|
45
|
+
unlinkSync(outputPath);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!existsSync(tmpFolder)) {
|
|
49
|
+
mkdirSync(tmpFolder);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const statsFlag = withStatsFlag ? ' -s ' : '';
|
|
53
|
+
|
|
54
|
+
const result = execSync(`${baseCommand} -f __tests__/renderData/script1.cst -o ${outputPath} ${statsFlag}`).toString();
|
|
55
|
+
|
|
56
|
+
const outputFile = readFileSync(outputPath).toString();
|
|
57
|
+
const expected = readFileSync('__tests__/renderData/script1.cst.svg').toString();
|
|
58
|
+
|
|
59
|
+
expect(outputFile.trim()).toBe(expected.trim());
|
|
60
|
+
|
|
61
|
+
expect(
|
|
62
|
+
result.includes('Lexing took:') &&
|
|
63
|
+
result.includes('Parsing took:') &&
|
|
64
|
+
result.includes('Layout took:') &&
|
|
65
|
+
result.includes('Render took:')
|
|
66
|
+
).toBe(withStatsFlag);
|
|
67
|
+
});
|
|
68
|
+
});
|
package/__tests__/testMathOps.ts
CHANGED
package/__tests__/testRender.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
2
|
|
|
3
|
-
import { LayoutEngine } from "../src/layout";
|
|
4
|
-
import { generateSVG2 } from "../src/render";
|
|
5
|
-
import { runScript } from "./helpers";
|
|
3
|
+
import { LayoutEngine } from "../src/layout.js";
|
|
4
|
+
import { generateSVG2 } from "../src/render.js";
|
|
5
|
+
import { runScript } from "./helpers.js";
|
|
6
6
|
|
|
7
7
|
const mainPath = '__tests__/renderData/';
|
|
8
8
|
|
|
@@ -12,12 +12,13 @@ describe('Render tests', () => {
|
|
|
12
12
|
['variant and branch rendering', 'script1.cst'],
|
|
13
13
|
['simple function', 'script2.cst'],
|
|
14
14
|
['simple frame', 'script3.cst'],
|
|
15
|
-
['drawing functions for graphics', 'script4.cst']
|
|
16
|
-
|
|
15
|
+
['drawing functions for graphics', 'script4.cst'],
|
|
16
|
+
['drawing 180 deg flipped components', 'script5.cst']
|
|
17
|
+
|
|
17
18
|
])('render - %s (%s)', async (title, scriptPath) => {
|
|
18
19
|
|
|
19
|
-
const script =
|
|
20
|
-
const {hasError, visitor} = await runScript(script);
|
|
20
|
+
const script = readFileSync(mainPath + scriptPath, { encoding: 'utf8' });
|
|
21
|
+
const { hasError, visitor } = await runScript(script);
|
|
21
22
|
expect(hasError).toBe(false);
|
|
22
23
|
visitor.annotateComponents();
|
|
23
24
|
|
|
@@ -28,7 +29,7 @@ describe('Render tests', () => {
|
|
|
28
29
|
|
|
29
30
|
const svgOutput = generateSVG2(graph);
|
|
30
31
|
|
|
31
|
-
const expectedSvgOutput =
|
|
32
|
+
const expectedSvgOutput = readFileSync(mainPath + scriptPath + ".svg", { encoding: 'utf8' });
|
|
32
33
|
expect(svgOutput).toBe(expectedSvgOutput);
|
|
33
34
|
});
|
|
34
35
|
});
|
|
@@ -102,7 +102,8 @@ export class SymbolGraphic {
|
|
|
102
102
|
let anchorStyle = 'start';
|
|
103
103
|
let dominantBaseline = 'auto';
|
|
104
104
|
let useAnchor = anchor;
|
|
105
|
-
|
|
105
|
+
const isRotation180 = Math.abs(this.angle) === 180;
|
|
106
|
+
if (isRotation180) {
|
|
106
107
|
useAnchor = this.flipTextAnchor(anchor);
|
|
107
108
|
}
|
|
108
109
|
switch (useAnchor) {
|
|
@@ -140,7 +141,7 @@ export class SymbolGraphic {
|
|
|
140
141
|
anchor: anchorStyle,
|
|
141
142
|
'dominant-baseline': dominantBaseline,
|
|
142
143
|
});
|
|
143
|
-
if (
|
|
144
|
+
if (isRotation180) {
|
|
144
145
|
text.translate(-position[0], position[1]);
|
|
145
146
|
}
|
|
146
147
|
else {
|
package/build/src/main.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
import { program } from 'commander';
|
|
3
3
|
import figlet from 'figlet';
|
|
4
|
-
import fs from 'fs';
|
|
5
4
|
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { readFileSync, watch, writeFileSync } from 'fs';
|
|
6
7
|
import { MainVisitor } from './visitor.js';
|
|
7
8
|
import { prepareSizing } from './sizing.js';
|
|
8
9
|
import { LayoutEngine } from './layout.js';
|
|
@@ -12,9 +13,16 @@ import { parseFileWithVisitor } from './parser.js';
|
|
|
12
13
|
import { generateKiCADNetList } from './export.js';
|
|
13
14
|
import { SimpleStopwatch } from './utils.js';
|
|
14
15
|
export default async function main() {
|
|
16
|
+
const toolSrcPath = fileURLToPath(import.meta.url);
|
|
17
|
+
const toolDirectory = path.dirname(toolSrcPath) + '/../../';
|
|
18
|
+
const fontsPath = toolDirectory + '/fonts';
|
|
19
|
+
const defaultLibsPath = toolDirectory + '/libs';
|
|
20
|
+
const packageJson = JSON.parse(readFileSync(toolDirectory + 'package.json').toString());
|
|
21
|
+
;
|
|
22
|
+
const { version } = packageJson;
|
|
15
23
|
program
|
|
16
24
|
.description('generate graphical output from circuitscript files')
|
|
17
|
-
.version(
|
|
25
|
+
.version(version)
|
|
18
26
|
.option('-i, --input text <input text>', 'Input text directly')
|
|
19
27
|
.option('-f, --input-file <path>', 'Input file')
|
|
20
28
|
.option('-o, --output <path>', 'Output path')
|
|
@@ -41,7 +49,7 @@ export default async function main() {
|
|
|
41
49
|
if (watchFileChanges) {
|
|
42
50
|
console.log('watching for file changes...');
|
|
43
51
|
}
|
|
44
|
-
await prepareSizing();
|
|
52
|
+
await prepareSizing(fontsPath);
|
|
45
53
|
let inputFilePath = null;
|
|
46
54
|
let scriptData;
|
|
47
55
|
if (options.input) {
|
|
@@ -49,13 +57,14 @@ export default async function main() {
|
|
|
49
57
|
}
|
|
50
58
|
else {
|
|
51
59
|
inputFilePath = options.inputFile;
|
|
52
|
-
scriptData =
|
|
60
|
+
scriptData = readFileSync(inputFilePath, { encoding: 'utf-8' });
|
|
53
61
|
if (currentDirectory === null) {
|
|
54
62
|
currentDirectory = path.dirname(inputFilePath);
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
65
|
const renderOptions = {
|
|
58
66
|
currentDirectory,
|
|
67
|
+
defaultLibsPath,
|
|
59
68
|
dumpNets,
|
|
60
69
|
dumpData,
|
|
61
70
|
kicadNetlistPath: kicadNetlist,
|
|
@@ -66,9 +75,9 @@ export default async function main() {
|
|
|
66
75
|
console.log(output);
|
|
67
76
|
}
|
|
68
77
|
if (watchFileChanges) {
|
|
69
|
-
|
|
78
|
+
watch(inputFilePath, event => {
|
|
70
79
|
if (event === 'change') {
|
|
71
|
-
const scriptData =
|
|
80
|
+
const scriptData = readFileSync(inputFilePath, { encoding: 'utf-8' });
|
|
72
81
|
renderScript(scriptData, outputPath, renderOptions);
|
|
73
82
|
console.log('done');
|
|
74
83
|
}
|
|
@@ -76,27 +85,25 @@ export default async function main() {
|
|
|
76
85
|
}
|
|
77
86
|
}
|
|
78
87
|
export function renderScript(scriptData, outputPath, options) {
|
|
79
|
-
const { currentDirectory = null, dumpNets = false, dumpData = false, kicadNetlistPath = null, showStats = false } = options;
|
|
88
|
+
const { currentDirectory = null, defaultLibsPath, dumpNets = false, dumpData = false, kicadNetlistPath = null, showStats = false } = options;
|
|
80
89
|
const visitor = new MainVisitor(true);
|
|
81
|
-
visitor.onImportFile = visitor.createImportFileHandler(currentDirectory);
|
|
90
|
+
visitor.onImportFile = visitor.createImportFileHandler(currentDirectory, defaultLibsPath);
|
|
82
91
|
visitor.print('reading file');
|
|
83
92
|
visitor.print('done reading file');
|
|
84
93
|
const { tree, parser, hasParseError, hasError, parserTimeTaken, lexerTimeTaken } = parseFileWithVisitor(visitor, scriptData);
|
|
85
94
|
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
86
95
|
showStats && console.log('Parsing took:', parserTimeTaken);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
dumpData && fs.writeFileSync('dump/tree.lisp', tree.toStringTree(null, parser));
|
|
91
|
-
dumpData && fs.writeFileSync('dump/raw-parser.txt', visitor.logger.dump());
|
|
96
|
+
dumpNets && console.log(visitor.dumpNets());
|
|
97
|
+
dumpData && writeFileSync('dump/tree.lisp', tree.toStringTree(null, parser));
|
|
98
|
+
dumpData && writeFileSync('dump/raw-parser.txt', visitor.logger.dump());
|
|
92
99
|
if (hasError || hasParseError) {
|
|
93
100
|
console.log('Error while parsing');
|
|
94
|
-
return;
|
|
101
|
+
return null;
|
|
95
102
|
}
|
|
96
103
|
visitor.annotateComponents();
|
|
97
104
|
if (kicadNetlistPath) {
|
|
98
105
|
const kicadNetList = generateKiCADNetList(visitor.getNetList());
|
|
99
|
-
|
|
106
|
+
writeFileSync(kicadNetlistPath, kicadNetList);
|
|
100
107
|
console.log('Generated KiCad netlist file');
|
|
101
108
|
}
|
|
102
109
|
const { sequence, nets } = visitor.getGraph();
|
|
@@ -116,7 +123,7 @@ export function renderScript(scriptData, outputPath, options) {
|
|
|
116
123
|
}
|
|
117
124
|
return tmp.join(" | ");
|
|
118
125
|
});
|
|
119
|
-
dumpData &&
|
|
126
|
+
dumpData && writeFileSync('dump/raw-sequence.txt', tmpSequence.join('\n'));
|
|
120
127
|
let svgOutput = null;
|
|
121
128
|
try {
|
|
122
129
|
const layoutEngine = new LayoutEngine();
|
|
@@ -124,12 +131,12 @@ export function renderScript(scriptData, outputPath, options) {
|
|
|
124
131
|
const graph = layoutEngine.runLayout(sequence, nets);
|
|
125
132
|
layoutEngine.printWarnings();
|
|
126
133
|
showStats && console.log('Layout took:', layoutTimer.lap());
|
|
127
|
-
dumpData &&
|
|
134
|
+
dumpData && writeFileSync('dump/raw-layout.txt', layoutEngine.logger.dump());
|
|
128
135
|
const generateSvgTimer = new SimpleStopwatch();
|
|
129
136
|
svgOutput = generateSVG2(graph);
|
|
130
137
|
showStats && console.log('Render took:', generateSvgTimer.lap());
|
|
131
138
|
if (outputPath) {
|
|
132
|
-
|
|
139
|
+
writeFileSync(outputPath, svgOutput);
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
catch (err) {
|
package/build/src/parser.js
CHANGED
|
@@ -63,12 +63,6 @@ export class CircuitscriptParserErrorListener extends ErrorListener {
|
|
|
63
63
|
console.log("Syntax error at line", line, ':', column, ' - ', msg);
|
|
64
64
|
this.syntaxErrorCounter++;
|
|
65
65
|
}
|
|
66
|
-
reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs) {
|
|
67
|
-
}
|
|
68
|
-
reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs) {
|
|
69
|
-
}
|
|
70
|
-
reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs) {
|
|
71
|
-
}
|
|
72
66
|
hasParseErrors() {
|
|
73
67
|
return (this.syntaxErrorCounter > 0);
|
|
74
68
|
}
|
package/build/src/sizing.js
CHANGED
|
@@ -6,8 +6,8 @@ const supportedFonts = {
|
|
|
6
6
|
'Inter': 'Inter-Regular.ttf',
|
|
7
7
|
'Inter-Bold': 'Inter-Bold.ttf',
|
|
8
8
|
};
|
|
9
|
-
export async function prepareSizing() {
|
|
10
|
-
await config.setFontDir(
|
|
9
|
+
export async function prepareSizing(fontsPath) {
|
|
10
|
+
await config.setFontDir(fontsPath)
|
|
11
11
|
.setFontFamilyMappings(supportedFonts)
|
|
12
12
|
.preloadFonts();
|
|
13
13
|
}
|
package/build/src/visitor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ParseTreeVisitor } from 'antlr4';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
4
|
import { ExecutionContext } from './execute.js';
|
|
5
5
|
import { ClassComponent } from './objects/ClassComponent.js';
|
|
6
6
|
import { NumericValue, ParamDefinition, PercentageValue, PinBlankValue, } from './objects/ParamDefinition.js';
|
|
@@ -731,23 +731,42 @@ export class MainVisitor extends ParseTreeVisitor {
|
|
|
731
731
|
PinTypes.Output,
|
|
732
732
|
PinTypes.Power,
|
|
733
733
|
];
|
|
734
|
-
createImportFileHandler(directory) {
|
|
734
|
+
createImportFileHandler(directory, defaultLibsPath) {
|
|
735
735
|
return (visitor, importPath) => {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
736
|
+
let importResult;
|
|
737
|
+
importResult = this.importLib(visitor, directory, importPath);
|
|
738
|
+
if (!importResult.pathExists && importPath == 'lib') {
|
|
739
|
+
importResult = this.importLib(visitor, defaultLibsPath, importPath);
|
|
740
|
+
}
|
|
741
|
+
return importResult;
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
importLib(visitor, directory, filename) {
|
|
745
|
+
const tmpFilePath = join(directory, filename + ".cst");
|
|
746
|
+
visitor.print('importing path:', tmpFilePath);
|
|
747
|
+
let pathExists = false;
|
|
748
|
+
let fileData = null;
|
|
749
|
+
try {
|
|
750
|
+
fileData = readFileSync(tmpFilePath, { encoding: 'utf8' });
|
|
751
|
+
pathExists = true;
|
|
752
|
+
}
|
|
753
|
+
catch (err) {
|
|
754
|
+
pathExists = false;
|
|
755
|
+
}
|
|
756
|
+
try {
|
|
757
|
+
if (pathExists) {
|
|
740
758
|
visitor.print('done reading imported file data');
|
|
741
759
|
const { hasError, hasParseError } = parseFileWithVisitor(visitor, fileData);
|
|
742
|
-
return { hasError, hasParseError };
|
|
760
|
+
return { hasError, hasParseError, pathExists };
|
|
743
761
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
762
|
+
}
|
|
763
|
+
catch (err) {
|
|
764
|
+
visitor.print('Failed to import file: ', err.message);
|
|
765
|
+
}
|
|
766
|
+
return {
|
|
767
|
+
hasError: true,
|
|
768
|
+
hasParseError: true,
|
|
769
|
+
pathExists,
|
|
751
770
|
};
|
|
752
771
|
}
|
|
753
772
|
parseCreateComponentPins(pinData) {
|