circuitscript 0.1.5 → 0.1.8
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/dist/cjs/BaseVisitor.js +127 -73
- package/dist/cjs/SemanticTokenVisitor.js +19 -13
- package/dist/cjs/antlr/CircuitScriptParser.js +711 -671
- package/dist/cjs/builtinMethods.js +29 -25
- package/dist/cjs/environment.js +118 -0
- package/dist/cjs/execute.js +53 -12
- package/dist/cjs/export.js +0 -5
- package/dist/cjs/geometry.js +1 -0
- package/dist/cjs/globals.js +11 -6
- package/dist/cjs/helpers.js +152 -127
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/layout.js +86 -44
- package/dist/cjs/main.js +31 -19
- package/dist/cjs/objects/ExecutionScope.js +33 -0
- package/dist/cjs/objects/ParamDefinition.js +15 -15
- package/dist/cjs/parser.js +27 -21
- package/dist/cjs/regenerate-tests.js +14 -10
- package/dist/cjs/render.js +3 -1
- package/dist/cjs/sizing.js +5 -58
- package/dist/cjs/utils.js +85 -30
- package/dist/cjs/validate/SymbolTable.js +96 -0
- package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +14 -0
- package/dist/cjs/validate/SymbolValidatorVisitor.js +170 -0
- package/dist/cjs/validate.js +71 -44
- package/dist/cjs/visitor.js +140 -24
- package/dist/esm/{BaseVisitor.mjs → BaseVisitor.js} +98 -45
- package/dist/esm/{SemanticTokenVisitor.mjs → SemanticTokenVisitor.js} +17 -11
- package/dist/esm/antlr/{CircuitScriptParser.mjs → CircuitScriptParser.js} +711 -671
- package/dist/esm/{builtinMethods.mjs → builtinMethods.js} +20 -16
- package/dist/esm/{draw_symbols.mjs → draw_symbols.js} +7 -7
- package/dist/esm/environment.js +110 -0
- package/dist/esm/{execute.mjs → execute.js} +66 -25
- package/dist/esm/{export.mjs → export.js} +2 -7
- package/dist/esm/{geometry.mjs → geometry.js} +6 -5
- package/dist/esm/{globals.mjs → globals.js} +6 -1
- package/dist/esm/helpers.js +394 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/{layout.mjs → layout.js} +72 -53
- package/dist/esm/{lexer.mjs → lexer.js} +2 -2
- package/dist/esm/{main.mjs → main.js} +33 -21
- package/dist/esm/objects/{ClassComponent.mjs → ClassComponent.js} +5 -4
- package/dist/esm/objects/{ExecutionScope.mjs → ExecutionScope.js} +33 -0
- package/dist/esm/objects/{Frame.mjs → Frame.js} +1 -1
- package/dist/esm/objects/{ParamDefinition.mjs → ParamDefinition.js} +1 -1
- package/dist/esm/objects/{PinDefinition.mjs → PinDefinition.js} +1 -1
- package/dist/esm/parser.js +71 -0
- package/dist/esm/{regenerate-tests.mjs → regenerate-tests.js} +15 -11
- package/dist/esm/{render.mjs → render.js} +11 -9
- package/dist/esm/{sizing.mjs → sizing.js} +6 -34
- package/dist/esm/{utils.mjs → utils.js} +61 -17
- package/dist/esm/validate/SymbolTable.js +90 -0
- package/dist/esm/validate/SymbolValidatorResolveVisitor.js +10 -0
- package/dist/esm/validate/SymbolValidatorVisitor.js +163 -0
- package/dist/esm/validate.js +105 -0
- package/dist/esm/{visitor.mjs → visitor.js} +151 -35
- package/dist/fonts/Arial.ttf +0 -0
- package/dist/fonts/Inter-Bold.ttf +0 -0
- package/dist/fonts/Inter-Regular.ttf +0 -0
- package/dist/fonts/OpenSans-Regular.ttf +0 -0
- package/dist/fonts/Roboto-Regular.ttf +0 -0
- package/dist/libs/lib.cst +423 -0
- package/dist/types/BaseVisitor.d.ts +34 -21
- package/dist/types/SemanticTokenVisitor.d.ts +6 -5
- package/dist/types/antlr/CircuitScriptParser.d.ts +4 -2
- package/dist/types/builtinMethods.d.ts +3 -2
- package/dist/types/environment.d.ts +31 -0
- package/dist/types/globals.d.ts +4 -1
- package/dist/types/helpers.d.ts +12 -14
- package/dist/types/index.d.ts +5 -0
- package/dist/types/layout.d.ts +2 -2
- package/dist/types/objects/ClassComponent.d.ts +1 -0
- package/dist/types/objects/ExecutionScope.d.ts +11 -0
- package/dist/types/objects/types.d.ts +6 -1
- package/dist/types/parser.d.ts +7 -11
- package/dist/types/sizing.d.ts +0 -3
- package/dist/types/utils.d.ts +30 -6
- package/dist/types/validate/SymbolTable.d.ts +40 -0
- package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +7 -0
- package/dist/types/validate/SymbolValidatorVisitor.d.ts +32 -0
- package/dist/types/validate.d.ts +1 -1
- package/package.json +15 -14
- package/dist/cjs/SymbolValidatorVisitor.js +0 -233
- package/dist/esm/SymbolValidatorVisitor.mjs +0 -222
- package/dist/esm/helpers.mjs +0 -364
- package/dist/esm/index.mjs +0 -15
- package/dist/esm/parser.mjs +0 -64
- package/dist/esm/validate.mjs +0 -74
- package/dist/types/SymbolValidatorVisitor.d.ts +0 -61
- /package/dist/esm/antlr/{CircuitScriptLexer.mjs → CircuitScriptLexer.js} +0 -0
- /package/dist/esm/antlr/{CircuitScriptVisitor.mjs → CircuitScriptVisitor.js} +0 -0
- /package/dist/esm/{fonts.mjs → fonts.js} +0 -0
- /package/dist/esm/{logger.mjs → logger.js} +0 -0
- /package/dist/esm/objects/{Net.mjs → Net.js} +0 -0
- /package/dist/esm/objects/{PinTypes.mjs → PinTypes.js} +0 -0
- /package/dist/esm/objects/{Wire.mjs → Wire.js} +0 -0
- /package/dist/esm/objects/{types.mjs → types.js} +0 -0
- /package/dist/esm/{server.mjs → server.js} +0 -0
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
import { program } from 'commander';
|
|
3
3
|
import figlet from 'figlet';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { getDefaultLibsPath, getFontsPath, getPackageVersion, renderScript } from './helpers.mjs';
|
|
4
|
+
import { watch } from 'fs';
|
|
5
|
+
import { renderScript } from './helpers.js';
|
|
6
|
+
import { NodeScriptEnvironment } from "./environment.js";
|
|
8
7
|
export default async function main() {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
const version = getPackageVersion();
|
|
8
|
+
const env = new NodeScriptEnvironment();
|
|
9
|
+
NodeScriptEnvironment.setInstance(env);
|
|
10
|
+
const version = env.getPackageVersion();
|
|
12
11
|
program
|
|
13
12
|
.description('generate graphical output from circuitscript files')
|
|
14
13
|
.version(version)
|
|
@@ -33,11 +32,13 @@ export default async function main() {
|
|
|
33
32
|
const watchFileChanges = options.watch;
|
|
34
33
|
const dumpNets = options.dumpNets;
|
|
35
34
|
const dumpData = options.dumpData;
|
|
36
|
-
|
|
35
|
+
if (options.currentDirectory) {
|
|
36
|
+
throw "Parameter not supported yet";
|
|
37
|
+
}
|
|
37
38
|
if (watchFileChanges) {
|
|
38
39
|
console.log('watching for file changes...');
|
|
39
40
|
}
|
|
40
|
-
await prepareSVGEnvironment(
|
|
41
|
+
await env.prepareSVGEnvironment();
|
|
41
42
|
let inputFilePath = "";
|
|
42
43
|
if (args.length > 2) {
|
|
43
44
|
console.log("Error: Extra arguments passed");
|
|
@@ -46,11 +47,8 @@ export default async function main() {
|
|
|
46
47
|
let scriptData;
|
|
47
48
|
if (args.length > 0 && args[0]) {
|
|
48
49
|
inputFilePath = args[0];
|
|
49
|
-
if (
|
|
50
|
-
scriptData =
|
|
51
|
-
if (currentDirectory === null) {
|
|
52
|
-
currentDirectory = path.dirname(inputFilePath);
|
|
53
|
-
}
|
|
50
|
+
if ((await env.exists(inputFilePath))) {
|
|
51
|
+
scriptData = await env.readFile(inputFilePath, { encoding: 'utf-8' });
|
|
54
52
|
}
|
|
55
53
|
else {
|
|
56
54
|
console.error("Error: File could not be found");
|
|
@@ -65,28 +63,42 @@ export default async function main() {
|
|
|
65
63
|
return;
|
|
66
64
|
}
|
|
67
65
|
const scriptOptions = {
|
|
68
|
-
currentDirectory,
|
|
69
|
-
defaultLibsPath,
|
|
70
66
|
dumpNets,
|
|
71
67
|
dumpData,
|
|
72
68
|
showStats: options.stats,
|
|
69
|
+
environment: env,
|
|
73
70
|
};
|
|
74
71
|
let outputPath = null;
|
|
75
72
|
if (args.length > 0 && args[1]) {
|
|
76
73
|
outputPath = args[1];
|
|
77
74
|
}
|
|
78
|
-
const output =
|
|
75
|
+
const output = await parseFile(scriptData, outputPath, scriptOptions);
|
|
79
76
|
if (outputPath === null && output && (options.skipOutput === undefined)) {
|
|
80
77
|
console.log(output);
|
|
81
78
|
}
|
|
82
79
|
if (watchFileChanges) {
|
|
83
|
-
watch(inputFilePath, event => {
|
|
80
|
+
watch(inputFilePath, async (event) => {
|
|
84
81
|
if (event === 'change') {
|
|
85
|
-
const scriptData =
|
|
86
|
-
|
|
87
|
-
console.log('done');
|
|
82
|
+
const scriptData = await env.readFile(inputFilePath, { encoding: 'utf-8' });
|
|
83
|
+
parseFile(scriptData, outputPath, scriptOptions);
|
|
88
84
|
}
|
|
89
85
|
});
|
|
90
86
|
}
|
|
91
87
|
}
|
|
88
|
+
async function parseFile(scriptData, outputPath, scriptOptions) {
|
|
89
|
+
try {
|
|
90
|
+
const { svgOutput: output, errors } = await renderScript(scriptData, outputPath, scriptOptions);
|
|
91
|
+
errors.forEach((err, index) => {
|
|
92
|
+
console.log(`[${index}] ${err}`);
|
|
93
|
+
});
|
|
94
|
+
if (errors.length > 0) {
|
|
95
|
+
console.log('Render failed due to syntax or parsing errors');
|
|
96
|
+
}
|
|
97
|
+
return output;
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error(`Unexpected Error: ${error}`);
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
92
104
|
main();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { SymbolDrawingCommands } from '../draw_symbols.
|
|
2
|
-
import { PinDefinition, PinIdType } from './PinDefinition.
|
|
3
|
-
import { PinTypes } from './PinTypes.
|
|
4
|
-
import { ParamKeys } from '../globals.
|
|
1
|
+
import { SymbolDrawingCommands } from '../draw_symbols.js';
|
|
2
|
+
import { PinDefinition, PinIdType } from './PinDefinition.js';
|
|
3
|
+
import { PinTypes } from './PinTypes.js';
|
|
4
|
+
import { ParamKeys } from '../globals.js';
|
|
5
5
|
export class ClassComponent {
|
|
6
6
|
instanceName;
|
|
7
7
|
numPins;
|
|
@@ -14,6 +14,7 @@ export class ClassComponent {
|
|
|
14
14
|
_cachedParams;
|
|
15
15
|
_copyID = null;
|
|
16
16
|
_copyFrom = null;
|
|
17
|
+
_pointLinkComponent;
|
|
17
18
|
arrangeProps = null;
|
|
18
19
|
displayProp = null;
|
|
19
20
|
widthProp = null;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Property_key_exprContext } from '../antlr/CircuitScriptParser.js';
|
|
1
2
|
export class ExecutionScope {
|
|
2
3
|
scopeId;
|
|
3
4
|
nets = [];
|
|
@@ -6,6 +7,8 @@ export class ExecutionScope {
|
|
|
6
7
|
variables = new Map();
|
|
7
8
|
symbols = new Map();
|
|
8
9
|
blockStack = new Map();
|
|
10
|
+
contextStack = [];
|
|
11
|
+
onPropertyHandler = [];
|
|
9
12
|
breakStack = [];
|
|
10
13
|
wires = [];
|
|
11
14
|
frames = [];
|
|
@@ -122,6 +125,36 @@ export class ExecutionScope {
|
|
|
122
125
|
this.currentPin = null;
|
|
123
126
|
}
|
|
124
127
|
}
|
|
128
|
+
enterContext(context) {
|
|
129
|
+
this.contextStack.push(context);
|
|
130
|
+
}
|
|
131
|
+
exitContext() {
|
|
132
|
+
return this.contextStack.pop();
|
|
133
|
+
}
|
|
134
|
+
findPropertyKeyTree() {
|
|
135
|
+
const keyNames = [];
|
|
136
|
+
for (let i = this.contextStack.length - 1; i >= 0; i--) {
|
|
137
|
+
const ctx = this.contextStack[i];
|
|
138
|
+
if (ctx instanceof Property_key_exprContext) {
|
|
139
|
+
keyNames.push([ctx, ctx.getText()]);
|
|
140
|
+
}
|
|
141
|
+
else if (typeof ctx === 'number') {
|
|
142
|
+
keyNames.push(['index', ctx]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return keyNames.reverse();
|
|
146
|
+
}
|
|
147
|
+
setOnPropertyHandler(handler) {
|
|
148
|
+
this.onPropertyHandler.push(handler);
|
|
149
|
+
}
|
|
150
|
+
popOnPropertyHandler() {
|
|
151
|
+
return this.onPropertyHandler.pop();
|
|
152
|
+
}
|
|
153
|
+
triggerPropertyHandler(value, valueCtx) {
|
|
154
|
+
const lastHandler = this.onPropertyHandler[this.onPropertyHandler.length - 1];
|
|
155
|
+
const propertyTree = this.findPropertyKeyTree();
|
|
156
|
+
lastHandler && lastHandler(propertyTree, value, valueCtx);
|
|
157
|
+
}
|
|
125
158
|
}
|
|
126
159
|
export var SequenceAction;
|
|
127
160
|
(function (SequenceAction) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getNumberExponential, getNumberExponentialText, resolveToNumericValue } from "../utils";
|
|
1
|
+
import { getNumberExponential, getNumberExponentialText, resolveToNumericValue } from "../utils.js";
|
|
2
2
|
import { Big } from 'big.js';
|
|
3
3
|
export class ParamDefinition {
|
|
4
4
|
paramName;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { CircuitScriptParser } from './antlr/CircuitScriptParser.js';
|
|
2
|
+
import { MainLexer } from './lexer.js';
|
|
3
|
+
import { ParseSyntaxError, RuntimeExecutionError, SimpleStopwatch } from './utils.js';
|
|
4
|
+
import { CharStream, CommonTokenStream } from 'antlr4ng';
|
|
5
|
+
export async function parseFileWithVisitor(visitor, data) {
|
|
6
|
+
const lexerErrorListener = new CircuitscriptParserErrorListener(visitor.onErrorHandler);
|
|
7
|
+
const parserErrorListener = new CircuitscriptParserErrorListener(visitor.onErrorHandler);
|
|
8
|
+
const chars = CharStream.fromString(data);
|
|
9
|
+
const lexer = new MainLexer(chars);
|
|
10
|
+
lexer.removeErrorListeners();
|
|
11
|
+
lexer.addErrorListener(lexerErrorListener);
|
|
12
|
+
const lexerTimer = new SimpleStopwatch();
|
|
13
|
+
const tokens = new CommonTokenStream(lexer);
|
|
14
|
+
tokens.fill();
|
|
15
|
+
const lexerTimeTaken = lexerTimer.lap();
|
|
16
|
+
const parserTimer = new SimpleStopwatch();
|
|
17
|
+
const parser = new CircuitScriptParser(tokens);
|
|
18
|
+
parser.removeErrorListeners();
|
|
19
|
+
parser.addErrorListener(parserErrorListener);
|
|
20
|
+
const tree = parser.script();
|
|
21
|
+
try {
|
|
22
|
+
await visitor.visitAsync(tree);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (visitor.onErrorHandler) {
|
|
26
|
+
if (error instanceof RuntimeExecutionError) {
|
|
27
|
+
visitor.onErrorHandler(error.message, null, error);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const parserTimeTaken = parserTimer.lap();
|
|
35
|
+
return {
|
|
36
|
+
tree, parser,
|
|
37
|
+
hasParseError: false,
|
|
38
|
+
hasError: false,
|
|
39
|
+
parserTimeTaken,
|
|
40
|
+
lexerTimeTaken,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export class CircuitscriptParserErrorListener {
|
|
44
|
+
syntaxErrorCounter = 0;
|
|
45
|
+
onErrorHandler = null;
|
|
46
|
+
constructor(onErrorHandler = null) {
|
|
47
|
+
this.onErrorHandler = onErrorHandler;
|
|
48
|
+
}
|
|
49
|
+
syntaxError(recognizer, offendingSymbol, line, column, msg, e) {
|
|
50
|
+
if (this.onErrorHandler && e) {
|
|
51
|
+
this.onErrorHandler(msg, e.ctx, e);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
if (offendingSymbol && msg.match("extraneous input 'import' expecting")) {
|
|
55
|
+
msg = "Invalid import statement";
|
|
56
|
+
throw new ParseSyntaxError("Invalid import statement", offendingSymbol);
|
|
57
|
+
}
|
|
58
|
+
console.log("Syntax error at line", line, ':', column, ' - ', msg);
|
|
59
|
+
}
|
|
60
|
+
this.syntaxErrorCounter++;
|
|
61
|
+
}
|
|
62
|
+
reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs) {
|
|
63
|
+
}
|
|
64
|
+
reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs) {
|
|
65
|
+
}
|
|
66
|
+
reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs) {
|
|
67
|
+
}
|
|
68
|
+
hasSyntaxErrors() {
|
|
69
|
+
return (this.syntaxErrorCounter > 0);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { renderScript } from './helpers.js';
|
|
3
|
+
import { NodeScriptEnvironment } from "./environment.js";
|
|
4
4
|
const mainDir = './__tests__/renderData/';
|
|
5
|
-
const
|
|
6
|
-
|
|
5
|
+
const env = new NodeScriptEnvironment();
|
|
6
|
+
NodeScriptEnvironment.setInstance(env);
|
|
7
7
|
async function regenerateTests(extra = "") {
|
|
8
|
-
await prepareSVGEnvironment(
|
|
8
|
+
await env.prepareSVGEnvironment();
|
|
9
9
|
const cstFiles = [];
|
|
10
10
|
const files = fs.readdirSync(mainDir);
|
|
11
11
|
files.forEach(file => {
|
|
@@ -13,16 +13,20 @@ async function regenerateTests(extra = "") {
|
|
|
13
13
|
cstFiles.push(file);
|
|
14
14
|
}
|
|
15
15
|
});
|
|
16
|
-
cstFiles.
|
|
16
|
+
for (let i = 0; i < cstFiles.length; i++) {
|
|
17
|
+
const file = cstFiles[i];
|
|
17
18
|
const inputPath = mainDir + file;
|
|
18
19
|
const scriptData = fs.readFileSync(inputPath, { encoding: 'utf-8' });
|
|
19
20
|
const outputPath = mainDir + 'svgs/' + file + extra + '.svg';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
env.setModuleDirectory(mainDir);
|
|
22
|
+
env.setDefaultLibsPath(mainDir + '../../libs/');
|
|
23
|
+
await renderScript(scriptData, outputPath, {
|
|
24
|
+
dumpNets: false,
|
|
25
|
+
dumpData: false,
|
|
26
|
+
showStats: false,
|
|
27
|
+
environment: env,
|
|
23
28
|
});
|
|
24
|
-
|
|
25
|
-
});
|
|
29
|
+
}
|
|
26
30
|
return cstFiles;
|
|
27
31
|
}
|
|
28
32
|
(async () => {
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { SVG, registerWindow } from '@svgdotjs/svg.js';
|
|
2
|
-
import { ExtractDrawingRects, RenderFrameType, getBounds } from "./layout.
|
|
3
|
-
import { applyFontsToSVG
|
|
4
|
-
import { ColorScheme, ComponentTypes, FrameType, MMToPt, MMToPx, ParamKeys, RenderFlags, defaultGridSizeUnits, defaultPageSpacingMM, defaultWireLineWidth, fontDisplayScale, junctionSize } from './globals.
|
|
5
|
-
import { numeric, NumericValue } from './objects/ParamDefinition.
|
|
6
|
-
import { combineMaps, getBoundsSize } from './utils.
|
|
7
|
-
import { getPaperSize, milsToMM } from './helpers.
|
|
2
|
+
import { ExtractDrawingRects, RenderFrameType, getBounds } from "./layout.js";
|
|
3
|
+
import { applyFontsToSVG } from './sizing.js';
|
|
4
|
+
import { ColorScheme, ComponentTypes, FrameType, MMToPt, MMToPx, ParamKeys, RenderFlags, defaultGridSizeUnits, defaultPageSpacingMM, defaultWireLineWidth, fontDisplayScale, junctionSize } from './globals.js';
|
|
5
|
+
import { numeric, NumericValue } from './objects/ParamDefinition.js';
|
|
6
|
+
import { combineMaps, getBoundsSize } from './utils.js';
|
|
7
|
+
import { getPaperSize, milsToMM } from './helpers.js';
|
|
8
|
+
import { NodeScriptEnvironment } from "./environment.js";
|
|
8
9
|
import SVGtoPDF from 'svg-to-pdfkit';
|
|
9
|
-
import { FrameParamKeys } from './objects/Frame.
|
|
10
|
-
import { SymbolPlaceholder } from './draw_symbols.
|
|
10
|
+
import { FrameParamKeys } from './objects/Frame.js';
|
|
11
|
+
import { SymbolPlaceholder } from './draw_symbols.js';
|
|
11
12
|
function createSvgCanvas() {
|
|
12
|
-
const
|
|
13
|
+
const env = NodeScriptEnvironment.getInstance();
|
|
14
|
+
const window = env.createSVGWindow();
|
|
13
15
|
const document = window.document;
|
|
14
16
|
registerWindow(window, document);
|
|
15
17
|
const canvas = SVG(document.documentElement);
|
|
@@ -1,42 +1,14 @@
|
|
|
1
|
-
import { SVG, registerWindow } from '@svgdotjs/svg.js';
|
|
2
1
|
import { Big } from 'big.js';
|
|
3
|
-
import { HorizontalAlign, HorizontalAlignProp, VerticalAlign, VerticalAlignProp } from './geometry.
|
|
4
|
-
import { defaultFont } from './globals.
|
|
5
|
-
import {
|
|
6
|
-
let MainCanvas = null;
|
|
7
|
-
const supportedFonts = {
|
|
8
|
-
'Arial': 'Arial.ttf',
|
|
9
|
-
};
|
|
10
|
-
let globalCreateSVGWindow;
|
|
11
|
-
export async function prepareSVGEnvironment(fontsPath) {
|
|
12
|
-
const moduleType = detectJSModuleType();
|
|
13
|
-
if (moduleType === JSModuleType.CommonJs) {
|
|
14
|
-
const { config, createSVGWindow } = await import('svgdom');
|
|
15
|
-
globalCreateSVGWindow = createSVGWindow;
|
|
16
|
-
if (fontsPath !== null) {
|
|
17
|
-
await config.setFontDir(fontsPath)
|
|
18
|
-
.setFontFamilyMappings(supportedFonts)
|
|
19
|
-
.preloadFonts();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export function getCreateSVGWindow() {
|
|
24
|
-
if (globalCreateSVGWindow === undefined) {
|
|
25
|
-
throw "SVG environment is not set up yet";
|
|
26
|
-
}
|
|
27
|
-
return globalCreateSVGWindow;
|
|
28
|
-
}
|
|
2
|
+
import { HorizontalAlign, HorizontalAlignProp, VerticalAlign, VerticalAlignProp } from './geometry.js';
|
|
3
|
+
import { defaultFont } from './globals.js';
|
|
4
|
+
import { NodeScriptEnvironment } from "./environment.js";
|
|
29
5
|
export function applyFontsToSVG(canvas) {
|
|
30
6
|
}
|
|
31
7
|
const measureTextSizeCache = {};
|
|
32
8
|
const measureTextSizeCacheHits = {};
|
|
33
9
|
export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regular', anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const { document } = window;
|
|
37
|
-
registerWindow(window, document);
|
|
38
|
-
MainCanvas = SVG(document.documentElement);
|
|
39
|
-
}
|
|
10
|
+
const environment = NodeScriptEnvironment.getInstance();
|
|
11
|
+
const mainCanvas = environment.getCanvasWindow();
|
|
40
12
|
const key = `${text}-${fontFamily}-${fontSize}-${fontWeight}-${anchor}-${vanchor}`;
|
|
41
13
|
if (measureTextSizeCache[key] === undefined) {
|
|
42
14
|
let dominantBaseline = VerticalAlignProp.Hanging;
|
|
@@ -64,7 +36,7 @@ export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regul
|
|
|
64
36
|
break;
|
|
65
37
|
}
|
|
66
38
|
fontFamily = defaultFont;
|
|
67
|
-
const tmpTextElement =
|
|
39
|
+
const tmpTextElement = mainCanvas.text(text).font({
|
|
68
40
|
family: fontFamily,
|
|
69
41
|
size: fontSize,
|
|
70
42
|
anchor: useAnchor,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Big } from 'big.js';
|
|
2
|
-
import { ClassComponent } from "./objects/ClassComponent";
|
|
3
|
-
import { NumericValue } from "./objects/ParamDefinition";
|
|
4
|
-
import { SequenceAction } from './objects/ExecutionScope';
|
|
5
|
-
import { BlockTypes } from './globals';
|
|
2
|
+
import { ClassComponent } from "./objects/ClassComponent.js";
|
|
3
|
+
import { NumericValue } from "./objects/ParamDefinition.js";
|
|
4
|
+
import { SequenceAction } from './objects/ExecutionScope.js';
|
|
5
|
+
import { BlockTypes } from './globals.js';
|
|
6
6
|
export class SimpleStopwatch {
|
|
7
7
|
startTime;
|
|
8
8
|
constructor() {
|
|
@@ -71,20 +71,17 @@ export function getPortType(component) {
|
|
|
71
71
|
export function roundValue(value) {
|
|
72
72
|
return resolveToNumericValue(new Big(value.toBigNumber().toFixed(7)));
|
|
73
73
|
}
|
|
74
|
-
export function throwWithContext(context,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const startString = startLine + ":" + startColumn;
|
|
78
|
-
const stopLine = context.stop?.line;
|
|
79
|
-
const stopColumn = context.stop?.column;
|
|
80
|
-
let stopString = "";
|
|
81
|
-
if (startLine === stopLine) {
|
|
82
|
-
stopString = stopColumn?.toString();
|
|
74
|
+
export function throwWithContext(context, messageOrError) {
|
|
75
|
+
if (messageOrError instanceof BaseError) {
|
|
76
|
+
throw messageOrError;
|
|
83
77
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
throw
|
|
78
|
+
throwWithTokenRange(messageOrError, context.start, context.stop);
|
|
79
|
+
}
|
|
80
|
+
export function throwWithToken(message, token) {
|
|
81
|
+
throw new ParseError(message, token);
|
|
82
|
+
}
|
|
83
|
+
export function throwWithTokenRange(message, startToken, endToken) {
|
|
84
|
+
throw new ParseError(message, startToken, endToken);
|
|
88
85
|
}
|
|
89
86
|
export function combineMaps(map1, map2) {
|
|
90
87
|
const newMap = new Map(map1);
|
|
@@ -240,3 +237,50 @@ export function getBlockTypeString(type) {
|
|
|
240
237
|
}
|
|
241
238
|
return returnValue;
|
|
242
239
|
}
|
|
240
|
+
export class BaseError extends Error {
|
|
241
|
+
name = 'BaseError';
|
|
242
|
+
message;
|
|
243
|
+
startToken;
|
|
244
|
+
endToken;
|
|
245
|
+
filePath;
|
|
246
|
+
constructor(message, startToken, endToken, filePath) {
|
|
247
|
+
super(message);
|
|
248
|
+
this.message = message;
|
|
249
|
+
this.startToken = startToken;
|
|
250
|
+
this.endToken = endToken;
|
|
251
|
+
this.filePath = filePath;
|
|
252
|
+
}
|
|
253
|
+
toString() {
|
|
254
|
+
const parts = [this.name];
|
|
255
|
+
if (this.startToken) {
|
|
256
|
+
const { line, column } = this.startToken;
|
|
257
|
+
if (this.endToken && (this.endToken.line !== this.startToken.line || this.endToken.column !== this.startToken.column)) {
|
|
258
|
+
const endLine = this.endToken.line;
|
|
259
|
+
const endColumn = this.endToken.column + (this.endToken.stop - this.endToken.start);
|
|
260
|
+
parts.push(` at ${line}:${column}-${endLine}:${endColumn}`);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
parts.push(` at ${line}:${column}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
parts.push(`: ${this.message}`);
|
|
267
|
+
return parts.join('');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
export class ParseSyntaxError extends BaseError {
|
|
271
|
+
name = 'ParseSyntaxError';
|
|
272
|
+
}
|
|
273
|
+
export class ParseError extends ParseSyntaxError {
|
|
274
|
+
name = 'ParseError';
|
|
275
|
+
}
|
|
276
|
+
export class RuntimeExecutionError extends BaseError {
|
|
277
|
+
name = 'RuntimeExecutionError';
|
|
278
|
+
}
|
|
279
|
+
export class RenderError extends Error {
|
|
280
|
+
stage;
|
|
281
|
+
constructor(message, stage) {
|
|
282
|
+
super(message);
|
|
283
|
+
this.name = 'RenderError';
|
|
284
|
+
this.stage = stage;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ParseSymbolType } from "../objects/types.js";
|
|
2
|
+
export class SymbolTable {
|
|
3
|
+
symbols = new Map();
|
|
4
|
+
executonContextsNamespaces = [];
|
|
5
|
+
getSymbols() {
|
|
6
|
+
return this.symbols;
|
|
7
|
+
}
|
|
8
|
+
addFunction(token, fileName, executionContext, id, funcDefinedParameters) {
|
|
9
|
+
return this.add(fileName, executionContext, id, ParseSymbolType.Function, {
|
|
10
|
+
funcDefinedParameters
|
|
11
|
+
}, token);
|
|
12
|
+
}
|
|
13
|
+
addVariable(token, fileName, executionContext, id, variableValue) {
|
|
14
|
+
return this.add(fileName, executionContext, id, ParseSymbolType.Variable, {
|
|
15
|
+
variableValue
|
|
16
|
+
}, token);
|
|
17
|
+
}
|
|
18
|
+
addUndefined(filePath, executionContext, id, token) {
|
|
19
|
+
return this.add(filePath, executionContext, id, ParseSymbolType.Undefined, {}, token);
|
|
20
|
+
}
|
|
21
|
+
add(fileName, executionContext, id, type, extra, token) {
|
|
22
|
+
if (this.executonContextsNamespaces.indexOf(executionContext.namespace) === -1) {
|
|
23
|
+
this.executonContextsNamespaces.push(executionContext.namespace);
|
|
24
|
+
}
|
|
25
|
+
const item = {
|
|
26
|
+
id,
|
|
27
|
+
type,
|
|
28
|
+
context: executionContext,
|
|
29
|
+
fileName,
|
|
30
|
+
extra,
|
|
31
|
+
token,
|
|
32
|
+
instances: [],
|
|
33
|
+
};
|
|
34
|
+
if (token !== null) {
|
|
35
|
+
item.instances.push(token);
|
|
36
|
+
}
|
|
37
|
+
this.symbols.set(this.idName(executionContext, id), item);
|
|
38
|
+
return item;
|
|
39
|
+
}
|
|
40
|
+
idName(executionContext, id) {
|
|
41
|
+
return executionContext.namespace + id;
|
|
42
|
+
}
|
|
43
|
+
dumpSymbols() {
|
|
44
|
+
for (const [key, value] of this.symbols) {
|
|
45
|
+
console.log(value.type.padEnd(10, " "), key);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exists(executionContext, id) {
|
|
49
|
+
const name = this.idName(executionContext, id);
|
|
50
|
+
return this.symbols.has(name);
|
|
51
|
+
}
|
|
52
|
+
existsAny(executionContext, id) {
|
|
53
|
+
if (this.exists(executionContext, id)) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
return this.searchParentContext(executionContext, id) !== null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
get(executionContext, id) {
|
|
61
|
+
const name = this.idName(executionContext, id);
|
|
62
|
+
return this.symbols.get(name);
|
|
63
|
+
}
|
|
64
|
+
getParentContexts(executionContext, contextsNamespace) {
|
|
65
|
+
if (executionContext.parentContext !== null) {
|
|
66
|
+
contextsNamespace.push(executionContext.parentContext.namespace);
|
|
67
|
+
this.getParentContexts(executionContext.parentContext, contextsNamespace);
|
|
68
|
+
}
|
|
69
|
+
return contextsNamespace;
|
|
70
|
+
}
|
|
71
|
+
searchParentContext(executionContext, id) {
|
|
72
|
+
const contextNames = this.getParentContexts(executionContext, []);
|
|
73
|
+
for (const [key,] of this.symbols) {
|
|
74
|
+
if (key.endsWith(`.${id}`)) {
|
|
75
|
+
const { context } = this.symbols.get(key);
|
|
76
|
+
if (contextNames.indexOf(context.namespace) !== -1) {
|
|
77
|
+
return context;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
clearUndefined() {
|
|
84
|
+
for (const [key, value] of this.symbols) {
|
|
85
|
+
if (value.type === ParseSymbolType.Undefined) {
|
|
86
|
+
this.symbols.delete(key);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SymbolValidatorVisitor } from "./SymbolValidatorVisitor.js";
|
|
2
|
+
export class SymbolValidatorResolveVisitor extends SymbolValidatorVisitor {
|
|
3
|
+
addSymbolVariable(token, name, value) {
|
|
4
|
+
}
|
|
5
|
+
addSymbolFunction(token, functionName, funcDefinedParameters) {
|
|
6
|
+
if (this.symbolTable.exists(this.getExecutor(), functionName)) {
|
|
7
|
+
this.symbolTable.addFunction(token, this.getCurrentFile(), this.getExecutor(), functionName, funcDefinedParameters);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|