circuitscript 0.5.4 → 0.5.6
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 +105 -2
- package/dist/cjs/BaseVisitor.js +11 -10
- package/dist/cjs/builtinMethods.js +6 -5
- package/dist/cjs/environment/environment.js +2 -2
- package/dist/cjs/errors.js +140 -0
- package/dist/cjs/execute.js +12 -5
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/main.js +3 -2
- package/dist/cjs/objects/ClassComponent.js +4 -4
- package/dist/cjs/objects/ExecutionScope.js +2 -2
- package/dist/cjs/objects/NumericValue.js +15 -0
- package/dist/cjs/objects/PinDefinition.js +2 -2
- package/dist/cjs/objects/types.js +2 -2
- package/dist/cjs/parser.js +3 -2
- package/dist/cjs/pipeline.js +21 -14
- package/dist/cjs/regenerate-tests.js +6 -6
- package/dist/cjs/render/draw_symbols.js +17 -17
- package/dist/cjs/render/geometry.js +6 -6
- package/dist/cjs/render/layout.js +325 -253
- package/dist/cjs/render/render.js +21 -18
- package/dist/cjs/semantic-tokens/getSemanticTokens.js +2 -2
- package/dist/cjs/sizing.js +2 -2
- package/dist/cjs/utils.js +13 -110
- package/dist/cjs/validate/validateScript.js +2 -2
- package/dist/cjs/visitor.js +14 -12
- package/dist/esm/BaseVisitor.js +2 -1
- package/dist/esm/builtinMethods.js +6 -5
- package/dist/esm/environment/environment.js +1 -1
- package/dist/esm/errors.js +119 -0
- package/dist/esm/execute.js +10 -3
- package/dist/esm/index.js +1 -0
- package/dist/esm/main.js +3 -2
- package/dist/esm/objects/ClassComponent.js +1 -1
- package/dist/esm/objects/ExecutionScope.js +1 -1
- package/dist/esm/objects/NumericValue.js +15 -0
- package/dist/esm/objects/PinDefinition.js +1 -1
- package/dist/esm/objects/types.js +1 -1
- package/dist/esm/parser.js +2 -1
- package/dist/esm/pipeline.js +10 -3
- package/dist/esm/regenerate-tests.js +6 -6
- package/dist/esm/render/draw_symbols.js +15 -15
- package/dist/esm/render/geometry.js +6 -6
- package/dist/esm/render/layout.js +325 -253
- package/dist/esm/render/render.js +22 -19
- package/dist/esm/semantic-tokens/getSemanticTokens.js +1 -1
- package/dist/esm/sizing.js +2 -2
- package/dist/esm/utils.js +10 -95
- package/dist/esm/validate/validateScript.js +1 -1
- package/dist/esm/visitor.js +4 -2
- package/dist/libs/std.cst +31 -31
- package/dist/types/BaseVisitor.d.ts +3 -1
- package/dist/types/errors.d.ts +37 -0
- package/dist/types/execute.d.ts +1 -1
- package/dist/types/helpers.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/objects/NumericValue.d.ts +5 -1
- package/dist/types/render/geometry.d.ts +4 -4
- package/dist/types/render/layout.d.ts +7 -1
- package/dist/types/utils.d.ts +2 -27
- package/dist/types/visitor.d.ts +1 -1
- package/libs/std.cst +31 -31
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -1,3 +1,106 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Circuitscript
|
|
2
2
|
|
|
3
|
-
|
|
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
|
+
```
|
package/dist/cjs/BaseVisitor.js
CHANGED
|
@@ -14,7 +14,7 @@ const types_js_1 = require("./objects/types.js");
|
|
|
14
14
|
const globals_js_1 = require("./globals.js");
|
|
15
15
|
const utils_js_1 = require("./utils.js");
|
|
16
16
|
const builtinMethods_js_1 = require("./builtinMethods.js");
|
|
17
|
-
const
|
|
17
|
+
const errors_js_1 = require("./errors.js");
|
|
18
18
|
const ExecutionScope_js_1 = require("./objects/ExecutionScope.js");
|
|
19
19
|
const hash_js_1 = require("./cache/hash.js");
|
|
20
20
|
const storage_js_1 = require("./cache/storage.js");
|
|
@@ -34,6 +34,7 @@ class BaseVisitor extends CircuitScriptParserVisitor_js_1.CircuitScriptParserVis
|
|
|
34
34
|
types_js_1.Direction.Right, types_js_1.Direction.Left];
|
|
35
35
|
this.resultData = new Map;
|
|
36
36
|
this.componentCtxLinks = new Map;
|
|
37
|
+
this.wireCtxLinks = new Map;
|
|
37
38
|
this.onErrorHandler = null;
|
|
38
39
|
this.importedFiles = [];
|
|
39
40
|
this.warnings = [];
|
|
@@ -312,7 +313,7 @@ class BaseVisitor extends CircuitScriptParserVisitor_js_1.CircuitScriptParserVis
|
|
|
312
313
|
this.setResult(ctx, returnList);
|
|
313
314
|
};
|
|
314
315
|
this.visitImport_expr = (ctx) => {
|
|
315
|
-
throw new
|
|
316
|
+
throw new errors_js_1.RuntimeExecutionError("Cannot parse imports here", ctx);
|
|
316
317
|
};
|
|
317
318
|
this.visitFunction_return_expr = (ctx) => {
|
|
318
319
|
const executor = this.getExecutor();
|
|
@@ -360,14 +361,14 @@ class BaseVisitor extends CircuitScriptParserVisitor_js_1.CircuitScriptParserVis
|
|
|
360
361
|
const arrayItem = this.visitResult(ctxArray);
|
|
361
362
|
const indexValue = this.visitResult(ctxArrayIndex);
|
|
362
363
|
if (!Array.isArray(arrayItem)) {
|
|
363
|
-
throw new
|
|
364
|
+
throw new errors_js_1.RuntimeExecutionError("Invalid array", ctxArray);
|
|
364
365
|
}
|
|
365
366
|
if (!(indexValue instanceof NumericValue_js_1.NumericValue)) {
|
|
366
|
-
throw new
|
|
367
|
+
throw new errors_js_1.RuntimeExecutionError("Invalid index value", ctxArrayIndex);
|
|
367
368
|
}
|
|
368
369
|
const indexValueNumber = indexValue.toNumber();
|
|
369
370
|
if (isNaN(indexValueNumber)) {
|
|
370
|
-
throw new
|
|
371
|
+
throw new errors_js_1.RuntimeExecutionError("Invalid index value", ctxArrayIndex);
|
|
371
372
|
}
|
|
372
373
|
if (Array.isArray(arrayItem)) {
|
|
373
374
|
this.setResult(ctx, arrayItem[indexValueNumber]);
|
|
@@ -738,7 +739,7 @@ class BaseVisitor extends CircuitScriptParserVisitor_js_1.CircuitScriptParserVis
|
|
|
738
739
|
const invalidImportCondition2 = alreadyImportedFlag !== types_js_1.ImportFunctionHandling.AllWithNamespace &&
|
|
739
740
|
importHandling === types_js_1.ImportFunctionHandling.AllWithNamespace;
|
|
740
741
|
if (invalidImportCondition1 || invalidImportCondition2) {
|
|
741
|
-
throw new
|
|
742
|
+
throw new errors_js_1.RuntimeExecutionError(`Namespace import and wildcard/specific imports cannot be mixed: ${name}`, ctx);
|
|
742
743
|
}
|
|
743
744
|
if (isMergedNamespace) {
|
|
744
745
|
if (alreadyImportedFlag === types_js_1.ImportFunctionHandling.AllMergeIntoNamespace) {
|
|
@@ -866,7 +867,7 @@ class BaseVisitor extends CircuitScriptParserVisitor_js_1.CircuitScriptParserVis
|
|
|
866
867
|
}
|
|
867
868
|
}
|
|
868
869
|
if (errorMessage !== null && ctx) {
|
|
869
|
-
throw new
|
|
870
|
+
throw new errors_js_1.RuntimeExecutionError(errorMessage, ctx);
|
|
870
871
|
}
|
|
871
872
|
const newImportedFile = {
|
|
872
873
|
id: name.trim(),
|
|
@@ -892,7 +893,7 @@ class BaseVisitor extends CircuitScriptParserVisitor_js_1.CircuitScriptParserVis
|
|
|
892
893
|
}
|
|
893
894
|
catch (err) {
|
|
894
895
|
this.log(`failed to cache library: ${libName}`);
|
|
895
|
-
throw new
|
|
896
|
+
throw new errors_js_1.RuntimeExecutionError(`Failed to cache library: ${libName}`);
|
|
896
897
|
}
|
|
897
898
|
}
|
|
898
899
|
}
|
|
@@ -1037,7 +1038,7 @@ class BaseVisitor extends CircuitScriptParserVisitor_js_1.CircuitScriptParserVis
|
|
|
1037
1038
|
return value.slice(1, value.length - 1);
|
|
1038
1039
|
}
|
|
1039
1040
|
throwWithContext(context, messageOrError) {
|
|
1040
|
-
(0,
|
|
1041
|
+
(0, errors_js_1.throwWithContext)(context, messageOrError);
|
|
1041
1042
|
}
|
|
1042
1043
|
validateType(value, context, validateFunction, expectedType) {
|
|
1043
1044
|
if (value === undefined) {
|
|
@@ -1045,7 +1046,7 @@ class BaseVisitor extends CircuitScriptParserVisitor_js_1.CircuitScriptParserVis
|
|
|
1045
1046
|
}
|
|
1046
1047
|
const result = validateFunction(value);
|
|
1047
1048
|
if (!result) {
|
|
1048
|
-
throw new
|
|
1049
|
+
throw new errors_js_1.RuntimeExecutionError(`Invalid ${expectedType}`, context);
|
|
1049
1050
|
}
|
|
1050
1051
|
return result;
|
|
1051
1052
|
}
|
|
@@ -8,17 +8,18 @@ const big_js_1 = __importDefault(require("big.js"));
|
|
|
8
8
|
const NumericValue_js_1 = require("./objects/NumericValue.js");
|
|
9
9
|
const types_js_1 = require("./objects/types.js");
|
|
10
10
|
const utils_js_1 = require("./utils.js");
|
|
11
|
+
const errors_js_1 = require("./errors.js");
|
|
11
12
|
const globals_js_1 = require("./globals.js");
|
|
12
13
|
const ClassComponent_js_1 = require("./objects/ClassComponent.js");
|
|
13
14
|
const Net_js_1 = require("./objects/Net.js");
|
|
14
15
|
const builtInMethods = [
|
|
15
16
|
['enumerate', enumerate],
|
|
16
|
-
['
|
|
17
|
+
['to_mils', toMils],
|
|
17
18
|
['range', range],
|
|
18
19
|
['len', objectLength],
|
|
19
|
-
['
|
|
20
|
-
['
|
|
21
|
-
['
|
|
20
|
+
['array_push', arrayPush],
|
|
21
|
+
['array_get', arrayGet],
|
|
22
|
+
['array_set', arraySet],
|
|
22
23
|
['print', null],
|
|
23
24
|
];
|
|
24
25
|
exports.buildInMethodNamesList = builtInMethods.map(item => item[0]);
|
|
@@ -120,7 +121,7 @@ function arrayGet(arrayObject, index) {
|
|
|
120
121
|
useValue = index;
|
|
121
122
|
}
|
|
122
123
|
if (isNaN(useValue)) {
|
|
123
|
-
throw new
|
|
124
|
+
throw new errors_js_1.RuntimeExecutionError("Invalid index for arrayGet");
|
|
124
125
|
}
|
|
125
126
|
return arrayObject[useValue];
|
|
126
127
|
}
|
|
@@ -9,7 +9,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
11
11
|
const globals_js_1 = require("../globals.js");
|
|
12
|
-
const
|
|
12
|
+
const errors_js_1 = require("../errors.js");
|
|
13
13
|
class NodeScriptEnvironment {
|
|
14
14
|
constructor() {
|
|
15
15
|
this.useModuleDirectoryPath = null;
|
|
@@ -71,7 +71,7 @@ class NodeScriptEnvironment {
|
|
|
71
71
|
return finalPath;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
throw new
|
|
74
|
+
throw new errors_js_1.RuntimeExecutionError("Failed to get current module directory");
|
|
75
75
|
}
|
|
76
76
|
getRelativeToModule(filePath) {
|
|
77
77
|
return path_1.default.join(this.getModuleDirectory(), filePath);
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.printErrorChain = exports.collectErrorChain = exports.ParseError = exports.ParseSyntaxError = exports.RuntimeExecutionError = exports.AutoWireFailedError = exports.AutoWireFailedError_ = exports.RenderError = exports.throwWithTokenRange = exports.throwWithContext = exports.getLinePositionAsString = exports.BaseError = void 0;
|
|
4
|
+
const antlr4ng_1 = require("antlr4ng");
|
|
5
|
+
class BaseError extends Error {
|
|
6
|
+
constructor(message, startTokenOrCtx, endToken, filePath, options) {
|
|
7
|
+
super(message, options);
|
|
8
|
+
this.name = 'BaseError';
|
|
9
|
+
this.message = message;
|
|
10
|
+
if (startTokenOrCtx instanceof antlr4ng_1.ParserRuleContext) {
|
|
11
|
+
this.startToken = startTokenOrCtx.start;
|
|
12
|
+
this.endToken = startTokenOrCtx.stop;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.startToken = startTokenOrCtx;
|
|
16
|
+
this.endToken = endToken;
|
|
17
|
+
}
|
|
18
|
+
this.filePath = filePath;
|
|
19
|
+
}
|
|
20
|
+
toString() {
|
|
21
|
+
const parts = [this.name];
|
|
22
|
+
const linePosition = getLinePositionAsString({
|
|
23
|
+
start: this.startToken,
|
|
24
|
+
stop: this.endToken
|
|
25
|
+
});
|
|
26
|
+
if (linePosition !== null) {
|
|
27
|
+
parts.push(linePosition);
|
|
28
|
+
}
|
|
29
|
+
parts.push(`: ${this.message}`);
|
|
30
|
+
return parts.join('');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.BaseError = BaseError;
|
|
34
|
+
function getLinePositionAsString(ctx) {
|
|
35
|
+
if (ctx === null || ctx === undefined) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const { start: startToken, stop: stopToken } = ctx;
|
|
39
|
+
let result = null;
|
|
40
|
+
if (startToken) {
|
|
41
|
+
const { line, column } = startToken;
|
|
42
|
+
let stopLine = 0;
|
|
43
|
+
let stopCol = 0;
|
|
44
|
+
if (stopToken && (stopToken.line !== startToken.line || stopToken.column !== startToken.column)) {
|
|
45
|
+
stopLine = stopToken.line;
|
|
46
|
+
stopCol = stopToken.column + (stopToken.stop - stopToken.start);
|
|
47
|
+
}
|
|
48
|
+
else if (startToken === stopToken || startToken) {
|
|
49
|
+
stopLine = line;
|
|
50
|
+
stopCol = column + 1 + (startToken.stop - startToken.start);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
stopCol = -1;
|
|
54
|
+
}
|
|
55
|
+
result = ` at ${line}:${column + 1}`;
|
|
56
|
+
if (stopCol !== -1) {
|
|
57
|
+
result += `-${stopLine}:${stopCol + 1}`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
exports.getLinePositionAsString = getLinePositionAsString;
|
|
63
|
+
function throwWithContext(context, messageOrError) {
|
|
64
|
+
if (messageOrError instanceof BaseError) {
|
|
65
|
+
throw messageOrError;
|
|
66
|
+
}
|
|
67
|
+
throwWithTokenRange(messageOrError, context.start, context.stop);
|
|
68
|
+
}
|
|
69
|
+
exports.throwWithContext = throwWithContext;
|
|
70
|
+
function throwWithTokenRange(message, startToken, endToken) {
|
|
71
|
+
throw new ParseError(message, startToken, endToken);
|
|
72
|
+
}
|
|
73
|
+
exports.throwWithTokenRange = throwWithTokenRange;
|
|
74
|
+
class RenderError extends Error {
|
|
75
|
+
constructor(message, stage, options) {
|
|
76
|
+
super(message, options);
|
|
77
|
+
this.name = 'RenderError';
|
|
78
|
+
this.stage = stage;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.RenderError = RenderError;
|
|
82
|
+
class AutoWireFailedError_ extends Error {
|
|
83
|
+
constructor(message, wire) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.name = 'AutoWireFailedError_';
|
|
86
|
+
this.wire = wire;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.AutoWireFailedError_ = AutoWireFailedError_;
|
|
90
|
+
class AutoWireFailedError extends BaseError {
|
|
91
|
+
constructor() {
|
|
92
|
+
super(...arguments);
|
|
93
|
+
this.name = 'AutoWireFailedError';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.AutoWireFailedError = AutoWireFailedError;
|
|
97
|
+
class RuntimeExecutionError extends BaseError {
|
|
98
|
+
constructor() {
|
|
99
|
+
super(...arguments);
|
|
100
|
+
this.name = 'RuntimeExecutionError';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.RuntimeExecutionError = RuntimeExecutionError;
|
|
104
|
+
class ParseSyntaxError extends BaseError {
|
|
105
|
+
constructor() {
|
|
106
|
+
super(...arguments);
|
|
107
|
+
this.name = 'ParseSyntaxError';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.ParseSyntaxError = ParseSyntaxError;
|
|
111
|
+
class ParseError extends ParseSyntaxError {
|
|
112
|
+
constructor() {
|
|
113
|
+
super(...arguments);
|
|
114
|
+
this.name = 'ParseError';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.ParseError = ParseError;
|
|
118
|
+
function collectErrorChain(error) {
|
|
119
|
+
const items = [];
|
|
120
|
+
let currentError = error;
|
|
121
|
+
for (let i = 0; i < 100; i++) {
|
|
122
|
+
if (currentError.cause) {
|
|
123
|
+
items.push(currentError.cause);
|
|
124
|
+
currentError = currentError.cause;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return items;
|
|
131
|
+
}
|
|
132
|
+
exports.collectErrorChain = collectErrorChain;
|
|
133
|
+
function printErrorChain(error) {
|
|
134
|
+
const errors = collectErrorChain(error);
|
|
135
|
+
errors.reverse();
|
|
136
|
+
for (const err of errors) {
|
|
137
|
+
console.log(" " + err.toString());
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.printErrorChain = printErrorChain;
|
package/dist/cjs/execute.js
CHANGED
|
@@ -16,6 +16,7 @@ const layout_js_1 = require("./render/layout.js");
|
|
|
16
16
|
const helpers_js_1 = require("./helpers.js");
|
|
17
17
|
const draw_symbols_js_1 = require("./render/draw_symbols.js");
|
|
18
18
|
const utils_js_1 = require("./utils.js");
|
|
19
|
+
const errors_js_1 = require("./errors.js");
|
|
19
20
|
class ExecutionContext {
|
|
20
21
|
constructor(name, namespace, netNamespace, executionLevel = 0, scopeLevel = 0, silent = false, logger, warnings, parent) {
|
|
21
22
|
this.tmpPointId = 0;
|
|
@@ -347,7 +348,7 @@ class ExecutionContext {
|
|
|
347
348
|
this.log('to component');
|
|
348
349
|
const { addSequence = false } = options ?? {};
|
|
349
350
|
if (!(component instanceof ClassComponent_js_1.ClassComponent)) {
|
|
350
|
-
throw new
|
|
351
|
+
throw new errors_js_1.RuntimeExecutionError("Not a valid component!");
|
|
351
352
|
}
|
|
352
353
|
if (pinId === null) {
|
|
353
354
|
pinId = component.getDefaultPin();
|
|
@@ -358,7 +359,7 @@ class ExecutionContext {
|
|
|
358
359
|
}
|
|
359
360
|
else {
|
|
360
361
|
console.trace();
|
|
361
|
-
throw new
|
|
362
|
+
throw new errors_js_1.RuntimeExecutionError('Invalid pin number ' +
|
|
362
363
|
pinId +
|
|
363
364
|
' in ' +
|
|
364
365
|
component.instanceName);
|
|
@@ -400,7 +401,7 @@ class ExecutionContext {
|
|
|
400
401
|
usePinId = component.getPin(pinId);
|
|
401
402
|
}
|
|
402
403
|
else {
|
|
403
|
-
throw new
|
|
404
|
+
throw new errors_js_1.RuntimeExecutionError('Invalid pin number '
|
|
404
405
|
+ pinId + ' in ' + component);
|
|
405
406
|
}
|
|
406
407
|
this.scope.setCurrent(component, usePinId);
|
|
@@ -484,7 +485,13 @@ class ExecutionContext {
|
|
|
484
485
|
const { start_point: [component, pin,] } = stackRef;
|
|
485
486
|
this.atComponent(component, pin, { addSequence: true });
|
|
486
487
|
}
|
|
487
|
-
this.scope.blockStack.
|
|
488
|
+
const scopeLevels = Array.from(this.scope.blockStack.keys());
|
|
489
|
+
for (const level of scopeLevels) {
|
|
490
|
+
if (level >= scopeLevel) {
|
|
491
|
+
this.log(`blockstack delete level ${level}`);
|
|
492
|
+
this.scope.blockStack.delete(level);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
488
495
|
this.log('exit blocks');
|
|
489
496
|
}
|
|
490
497
|
closeOpenPathBlocks() {
|
|
@@ -901,7 +908,7 @@ class ExecutionContext {
|
|
|
901
908
|
this.log('-- done merging scope --');
|
|
902
909
|
return mergedInstances;
|
|
903
910
|
}
|
|
904
|
-
addWire(segments) {
|
|
911
|
+
addWire(segments, ctx) {
|
|
905
912
|
if (this.scope.currentComponent === null) {
|
|
906
913
|
throw "No current component";
|
|
907
914
|
}
|
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);
|
package/dist/cjs/main.js
CHANGED
|
@@ -9,6 +9,7 @@ const figlet_1 = __importDefault(require("figlet"));
|
|
|
9
9
|
const fs_1 = require("fs");
|
|
10
10
|
const pipeline_js_1 = require("./pipeline.js");
|
|
11
11
|
const environment_js_1 = require("./environment/environment.js");
|
|
12
|
+
const errors_js_1 = require("./errors.js");
|
|
12
13
|
async function main() {
|
|
13
14
|
const env = new environment_js_1.NodeScriptEnvironment();
|
|
14
15
|
environment_js_1.NodeScriptEnvironment.setInstance(env);
|
|
@@ -139,8 +140,8 @@ async function parseFile(scriptData, outputPath, scriptOptions) {
|
|
|
139
140
|
return output;
|
|
140
141
|
}
|
|
141
142
|
catch (error) {
|
|
142
|
-
console.error(`Unexpected Error
|
|
143
|
-
|
|
143
|
+
console.error(`Unexpected Error:`);
|
|
144
|
+
(0, errors_js_1.printErrorChain)(error);
|
|
144
145
|
}
|
|
145
146
|
return null;
|
|
146
147
|
}
|
|
@@ -5,7 +5,7 @@ const draw_symbols_js_1 = require("../render/draw_symbols.js");
|
|
|
5
5
|
const PinDefinition_js_1 = require("./PinDefinition.js");
|
|
6
6
|
const PinTypes_js_1 = require("./PinTypes.js");
|
|
7
7
|
const globals_js_1 = require("../globals.js");
|
|
8
|
-
const
|
|
8
|
+
const errors_js_1 = require("../errors.js");
|
|
9
9
|
class ComponentUnit {
|
|
10
10
|
get instanceName() {
|
|
11
11
|
return `${this.parent.instanceName},${this.unitId}`;
|
|
@@ -190,7 +190,7 @@ class ClassComponent {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
|
-
throw new
|
|
193
|
+
throw new errors_js_1.RuntimeExecutionError(`Could not find pin '${pinId}' on component '${this.instanceName}'`);
|
|
194
194
|
}
|
|
195
195
|
getNextPinAfter(pinIndex) {
|
|
196
196
|
const pins = Array.from(this.pins.keys());
|
|
@@ -321,14 +321,14 @@ class ClassComponent {
|
|
|
321
321
|
}
|
|
322
322
|
getUnitForPin(pinId) {
|
|
323
323
|
if (typeof pinId === "number") {
|
|
324
|
-
throw new
|
|
324
|
+
throw new errors_js_1.RuntimeExecutionError("Invalid pin id");
|
|
325
325
|
}
|
|
326
326
|
for (const [tmpPin, componentUnit] of this.pinUnitMap) {
|
|
327
327
|
if (tmpPin.equals(pinId)) {
|
|
328
328
|
return componentUnit;
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
|
-
throw new
|
|
331
|
+
throw new errors_js_1.RuntimeExecutionError("Could not find unit for pin: " + pinId);
|
|
332
332
|
}
|
|
333
333
|
}
|
|
334
334
|
exports.ClassComponent = ClassComponent;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ActiveObject = exports.FrameAction = exports.SequenceAction = exports.ExecutionScope = void 0;
|
|
4
4
|
const CircuitScriptParser_js_1 = require("../antlr/CircuitScriptParser.js");
|
|
5
5
|
const PinDefinition_js_1 = require("./PinDefinition.js");
|
|
6
|
-
const
|
|
6
|
+
const errors_js_1 = require("../errors.js");
|
|
7
7
|
class ExecutionScope {
|
|
8
8
|
constructor(scopeId) {
|
|
9
9
|
this.nets = [];
|
|
@@ -37,7 +37,7 @@ class ExecutionScope {
|
|
|
37
37
|
}
|
|
38
38
|
findNet(component, pin) {
|
|
39
39
|
if (!(pin instanceof PinDefinition_js_1.PinId)) {
|
|
40
|
-
throw new
|
|
40
|
+
throw new errors_js_1.RuntimeExecutionError('Invalid value for PinId: ' + pin);
|
|
41
41
|
}
|
|
42
42
|
return this.nets.find(([tmpComponent, tmpPin]) => {
|
|
43
43
|
return tmpComponent.isEqual(component) && tmpPin.equals(pin);
|
|
@@ -27,6 +27,9 @@ class NumericValue {
|
|
|
27
27
|
toString() {
|
|
28
28
|
return 'numeric:' + this.value;
|
|
29
29
|
}
|
|
30
|
+
copy() {
|
|
31
|
+
return this.add(0);
|
|
32
|
+
}
|
|
30
33
|
toDisplayString() {
|
|
31
34
|
if (typeof this.value === 'number') {
|
|
32
35
|
return this.value.toString();
|
|
@@ -81,6 +84,15 @@ class NumericValue {
|
|
|
81
84
|
eq(value) {
|
|
82
85
|
return this.toBigNumber().eq(value.toBigNumber());
|
|
83
86
|
}
|
|
87
|
+
floor() {
|
|
88
|
+
return numeric(Math.floor(this.toNumber()));
|
|
89
|
+
}
|
|
90
|
+
ceil() {
|
|
91
|
+
return numeric(Math.ceil(this.toNumber()));
|
|
92
|
+
}
|
|
93
|
+
roundDp() {
|
|
94
|
+
return roundValue(this.toNumber());
|
|
95
|
+
}
|
|
84
96
|
}
|
|
85
97
|
exports.NumericValue = NumericValue;
|
|
86
98
|
class NumberOperator {
|
|
@@ -191,6 +203,9 @@ function resolveToNumericValue(value) {
|
|
|
191
203
|
}
|
|
192
204
|
exports.resolveToNumericValue = resolveToNumericValue;
|
|
193
205
|
function roundValue(value) {
|
|
206
|
+
if (typeof value === "number") {
|
|
207
|
+
value = numeric(value);
|
|
208
|
+
}
|
|
194
209
|
return resolveToNumericValue(new big_js_1.Big(value.toBigNumber().toFixed(7)));
|
|
195
210
|
}
|
|
196
211
|
exports.roundValue = roundValue;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getPinDefinition = exports.isPinId = exports.PortSide = exports.PinIdType = exports.PinDefinition = exports.PinId = void 0;
|
|
4
|
-
const
|
|
4
|
+
const errors_js_1 = require("../errors.js");
|
|
5
5
|
const NumericValue_js_1 = require("./NumericValue.js");
|
|
6
6
|
const PinTypes_js_1 = require("./PinTypes.js");
|
|
7
7
|
class PinId {
|
|
8
8
|
constructor(value) {
|
|
9
9
|
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
10
|
-
throw new
|
|
10
|
+
throw new errors_js_1.RuntimeExecutionError("Invalid value for PinId: " + value);
|
|
11
11
|
}
|
|
12
12
|
this.value = value;
|
|
13
13
|
this.type = typeof value === 'number' ? PinIdType.Int : PinIdType.Str;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ImportFunctionHandling = exports.ImportedLibrary = exports.NetTypes = exports.Direction = exports.ParseSymbolType = exports.DeclaredReference = exports.UndeclaredReference = exports.AnyReference = exports.CFunctionEntry = void 0;
|
|
4
4
|
const globals_js_1 = require("../globals.js");
|
|
5
|
-
const
|
|
5
|
+
const errors_js_1 = require("../errors.js");
|
|
6
6
|
class CFunctionEntry {
|
|
7
7
|
constructor(namespace, name, execute, source, uniqueId) {
|
|
8
8
|
this.lazyLoaded = false;
|
|
@@ -31,7 +31,7 @@ class AnyReference {
|
|
|
31
31
|
this.referenceName = 'AnyReference';
|
|
32
32
|
if (refType.value instanceof AnyReference
|
|
33
33
|
&& refType.value.type !== globals_js_1.ReferenceTypes.function) {
|
|
34
|
-
throw new
|
|
34
|
+
throw new errors_js_1.RuntimeExecutionError("Nested reference types!");
|
|
35
35
|
}
|
|
36
36
|
this.found = refType.found;
|
|
37
37
|
this.name = refType.name;
|
package/dist/cjs/parser.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.CircuitscriptParserErrorListener = exports.parseFileWithVisitor = void 0
|
|
|
4
4
|
const CircuitScriptParser_js_1 = require("./antlr/CircuitScriptParser.js");
|
|
5
5
|
const lexer_js_1 = require("./lexer.js");
|
|
6
6
|
const utils_js_1 = require("./utils.js");
|
|
7
|
+
const errors_js_1 = require("./errors.js");
|
|
7
8
|
const antlr4ng_1 = require("antlr4ng");
|
|
8
9
|
function parseFileWithVisitor(visitor, data, options) {
|
|
9
10
|
const lexerErrorListener = new CircuitscriptParserErrorListener(visitor.onErrorHandler);
|
|
@@ -42,7 +43,7 @@ function parseFileWithVisitor(visitor, data, options) {
|
|
|
42
43
|
}
|
|
43
44
|
catch (error) {
|
|
44
45
|
if (visitor.onErrorHandler) {
|
|
45
|
-
if (error instanceof
|
|
46
|
+
if (error instanceof errors_js_1.RuntimeExecutionError) {
|
|
46
47
|
visitor.onErrorHandler(error.message, null, error);
|
|
47
48
|
}
|
|
48
49
|
else {
|
|
@@ -78,7 +79,7 @@ class CircuitscriptParserErrorListener {
|
|
|
78
79
|
else {
|
|
79
80
|
if (offendingSymbol && msg.match("extraneous input 'import' expecting")) {
|
|
80
81
|
msg = "Invalid import statement";
|
|
81
|
-
throw new
|
|
82
|
+
throw new errors_js_1.ParseSyntaxError("Invalid import statement", offendingSymbol);
|
|
82
83
|
}
|
|
83
84
|
console.log("Syntax error at line", line, ':', column, ' - ', msg);
|
|
84
85
|
}
|