circuitscript 0.1.27 → 0.1.29

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.
@@ -427,9 +427,15 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
427
427
  const innerResult = this.getResult(ctxDataExpr);
428
428
  this.setResult(ctx, innerResult);
429
429
  };
430
+ this.silent = silent;
430
431
  this.logger = new logger_js_1.Logger();
431
432
  this.onErrorHandler = onErrorHandler;
432
433
  this.environment = environment;
434
+ this.log('-- Environment --');
435
+ this.log('Module directory: ' + environment.getModuleDirectory());
436
+ this.log('Default libs path: ' + environment.getDefaultLibsPath());
437
+ this.log('Current file: ' + environment.getCurrentFile());
438
+ this.log('-----------------');
433
439
  this.startingContext = new execute_js_1.ExecutionContext(globals_js_1.DoubleDelimiter1, `${globals_js_1.DoubleDelimiter1}.`, '/', 0, 0, silent, this.logger, this.warnings, null);
434
440
  const scope = this.startingContext.scope;
435
441
  scope.sequence.push([
@@ -618,7 +624,7 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
618
624
  let hasError = false;
619
625
  let hasParseError = false;
620
626
  let pathExists = false;
621
- const tmpFilePath = this.environment.getRelativeToModule(name + ".cst");
627
+ const tmpFilePath = this.environment.getRelativeToCurrentFolder(name + ".cst");
622
628
  this.log('importing path:', tmpFilePath);
623
629
  let fileData = null;
624
630
  let filePathUsed = null;
@@ -628,16 +634,19 @@ class BaseVisitor extends CircuitScriptVisitor_js_1.CircuitScriptVisitor {
628
634
  pathExists = true;
629
635
  }
630
636
  catch (err) {
637
+ this.log('failed to read file');
631
638
  pathExists = false;
632
639
  }
633
640
  if (!pathExists) {
634
641
  try {
635
642
  const tmpFilePath2 = this.environment.getRelativeToDefaultLibs(name + ".cst");
643
+ this.log('checking default libs: ' + tmpFilePath2);
636
644
  filePathUsed = tmpFilePath2;
637
645
  fileData = await this.environment.readFile(tmpFilePath2, { encoding: 'utf8' });
638
646
  pathExists = true;
639
647
  }
640
648
  catch (err) {
649
+ this.log('failed to read file');
641
650
  pathExists = false;
642
651
  }
643
652
  }
@@ -10,6 +10,16 @@ class SemanticTokensVisitor extends BaseVisitor_js_1.BaseVisitor {
10
10
  super(silent, onErrorHandler, environment);
11
11
  this.parsedTokens = [];
12
12
  this.semanticTokens = new Map();
13
+ this.visitScript = async (ctx) => {
14
+ this.log('===', 'start', '===');
15
+ ctx.import_expr().forEach(ctxImport => {
16
+ this.visit(ctxImport);
17
+ });
18
+ const result = this.runExpressions(this.getExecutor(), ctx.expression());
19
+ this.setResult(ctx, result);
20
+ this.getExecutor().closeOpenPathBlocks();
21
+ this.log('===', 'end', '===');
22
+ };
13
23
  this.visitFunction_args_expr = (ctx) => {
14
24
  const IDs = ctx.ID();
15
25
  IDs.map(id => {
@@ -97,6 +107,10 @@ class SemanticTokensVisitor extends BaseVisitor_js_1.BaseVisitor {
97
107
  this.addSemanticToken(ctx.ID(0), [], 'variable');
98
108
  }
99
109
  };
110
+ this.visitOperator_assignment_expr = (ctx) => {
111
+ this.visit(ctx.atom_expr());
112
+ this.visit(ctx.data_expr());
113
+ };
100
114
  this.visitImport_expr = (ctx) => {
101
115
  this.addSemanticToken(ctx.ID(), [], 'namespace');
102
116
  };
@@ -104,13 +118,19 @@ class SemanticTokensVisitor extends BaseVisitor_js_1.BaseVisitor {
104
118
  ctx.ID().forEach(item => {
105
119
  this.addSemanticToken(item, [], 'variable');
106
120
  });
121
+ this.visit(ctx.data_expr());
122
+ this.visit(ctx.expressions_block());
123
+ };
124
+ this.visitAnnotation_comment_expr = (ctx) => {
125
+ this.addSemanticToken(ctx.ANNOTATION_START(), [], 'comment');
126
+ this.addSemanticToken(ctx.ID(), [], 'comment');
107
127
  };
108
128
  this.lexer = lexer;
109
129
  this.script = script;
110
130
  }
111
131
  addSemanticToken(node, modifiers, tokenType = null) {
112
132
  const parsedToken = this.parseToken(node, modifiers, tokenType);
113
- this.semanticTokens.set(parsedToken.line + "_" + parsedToken.column, parsedToken);
133
+ this.semanticTokens.set(`${parsedToken.line}_${parsedToken.column}_${parsedToken.length}`, parsedToken);
114
134
  }
115
135
  parseToken(node, modifiers, tokenType = null) {
116
136
  const token = node.symbol;
@@ -13,6 +13,7 @@ class NodeScriptEnvironment {
13
13
  constructor() {
14
14
  this.useModuleDirectoryPath = null;
15
15
  this.useDefaultLibsPath = null;
16
+ this.currentFile = '';
16
17
  this.globalCreateSVGWindow = null;
17
18
  this.cachedVersion = null;
18
19
  this.supportedFonts = {
@@ -118,6 +119,22 @@ class NodeScriptEnvironment {
118
119
  async readFile(path, options) {
119
120
  return fs_1.default.promises.readFile(path, options);
120
121
  }
122
+ getAbsolutePath(filePath) {
123
+ return path_1.default.resolve(filePath);
124
+ }
125
+ getDirPath(filePath) {
126
+ return path_1.default.dirname(path_1.default.resolve(filePath));
127
+ }
128
+ setCurrentFile(filePath) {
129
+ this.currentFile = this.getAbsolutePath(filePath);
130
+ return this.currentFile;
131
+ }
132
+ getCurrentFile() {
133
+ return this.currentFile;
134
+ }
135
+ getRelativeToCurrentFolder(filePath) {
136
+ return path_1.default.join(this.getDirPath(this.currentFile), filePath);
137
+ }
121
138
  async exists(path) {
122
139
  try {
123
140
  fs_1.default.promises.access(path, fs_1.default.constants.F_OK);
@@ -175,8 +175,8 @@ class ExecutionContext {
175
175
  paramsMap.set(param.paramName, param.paramValue);
176
176
  });
177
177
  if (component.typeProp === globals_js_1.ComponentTypes.net) {
178
- const netName = paramsMap.get(globals_js_1.ParamKeys.net_name);
179
- const netType = paramsMap.get(globals_js_1.ParamKeys.net_type);
178
+ const netName = paramsMap.get(globals_js_1.ParamKeys.net_name) ?? this.getUniqueNetName();
179
+ const netType = paramsMap.get(globals_js_1.ParamKeys.net_type) ?? types_js_1.NetTypes.Any;
180
180
  let priority = 0;
181
181
  if (paramsMap.has(globals_js_1.ParamKeys.priority)) {
182
182
  priority = paramsMap.get(globals_js_1.ParamKeys.priority).toNumber();
@@ -82,7 +82,7 @@ async function getSemanticTokens(scriptData, options) {
82
82
  const parsedTokens = (0, SemanticTokenVisitor_js_1.prepareTokens)(tokens.getTokens(), lexer, scriptData);
83
83
  const finalParsedTokens = [];
84
84
  parsedTokens.forEach(token => {
85
- const location = `${token.line}_${token.column}`;
85
+ const location = `${token.line}_${token.column}_${token.length}`;
86
86
  if (semanticTokens.has(location)) {
87
87
  finalParsedTokens.push(semanticTokens.get(location));
88
88
  }
@@ -187,7 +187,7 @@ async function renderScript(scriptData, outputPath, options) {
187
187
  }
188
188
  exports.renderScript = renderScript;
189
189
  async function renderScriptCustom(scriptData, outputPath, options, parseHandlers, postAnnotationCallbacks) {
190
- const { dumpNets = false, dumpData = false, showStats = false, enableErc = false, enableBom = false, bomOutputPath = undefined, environment } = options;
190
+ const { dumpNets = false, dumpData = false, showStats = false, enableErc = false, enableBom = false, inputPath = '', bomOutputPath = undefined, environment } = options;
191
191
  const errors = [];
192
192
  const onErrorHandler = (message, context, error) => {
193
193
  if (error && error instanceof utils_js_1.RuntimeExecutionError) {
@@ -214,7 +214,8 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
214
214
  errors.push(new utils_js_1.ParseError(message, context.start, context.stop));
215
215
  }
216
216
  };
217
- const visitor = new visitor_js_1.ParserVisitor(true, onErrorHandler, options.environment);
217
+ environment.setCurrentFile(inputPath);
218
+ const visitor = new visitor_js_1.ParserVisitor(true, onErrorHandler, environment);
218
219
  visitor.onImportFile = async (visitor, filePath, fileData) => {
219
220
  const { hasError, hasParseError } = await (0, parser_js_1.parseFileWithVisitor)(visitor, fileData);
220
221
  if (hasError || hasParseError) {
@@ -70,6 +70,7 @@ async function validate() {
70
70
  const visitor = await (0, helpers_js_1.validateScript)(inputFilePath, scriptData, scriptOptions);
71
71
  const symbols = visitor.getSymbols().getSymbols();
72
72
  const undefinedSymbols = [];
73
+ console.log('----- symbols -----');
73
74
  symbols.forEach((value, key) => {
74
75
  if (value.type !== types_js_1.ParseSymbolType.Undefined) {
75
76
  value = value;
@@ -83,7 +84,9 @@ async function validate() {
83
84
  undefinedSymbols.push(value);
84
85
  }
85
86
  });
87
+ console.log('----- tokens -----');
86
88
  const { parsedTokens } = await (0, helpers_js_1.getSemanticTokens)(scriptData, scriptOptions);
89
+ console.log('----- dump tokens -----');
87
90
  parsedTokens.forEach(item => {
88
91
  const { line, column, tokenType, tokenModifiers, textValue } = item;
89
92
  console.log(`${line}:${column} - ${textValue} - ${tokenType} | ${tokenModifiers.join(',')}`);
@@ -40,9 +40,15 @@ export class BaseVisitor extends CircuitScriptVisitor {
40
40
  };
41
41
  constructor(silent = false, onErrorHandler = null, environment) {
42
42
  super();
43
+ this.silent = silent;
43
44
  this.logger = new Logger();
44
45
  this.onErrorHandler = onErrorHandler;
45
46
  this.environment = environment;
47
+ this.log('-- Environment --');
48
+ this.log('Module directory: ' + environment.getModuleDirectory());
49
+ this.log('Default libs path: ' + environment.getDefaultLibsPath());
50
+ this.log('Current file: ' + environment.getCurrentFile());
51
+ this.log('-----------------');
46
52
  this.startingContext = new ExecutionContext(DoubleDelimiter1, `${DoubleDelimiter1}.`, '/', 0, 0, silent, this.logger, this.warnings, null);
47
53
  const scope = this.startingContext.scope;
48
54
  scope.sequence.push([
@@ -613,7 +619,7 @@ export class BaseVisitor extends CircuitScriptVisitor {
613
619
  let hasError = false;
614
620
  let hasParseError = false;
615
621
  let pathExists = false;
616
- const tmpFilePath = this.environment.getRelativeToModule(name + ".cst");
622
+ const tmpFilePath = this.environment.getRelativeToCurrentFolder(name + ".cst");
617
623
  this.log('importing path:', tmpFilePath);
618
624
  let fileData = null;
619
625
  let filePathUsed = null;
@@ -623,16 +629,19 @@ export class BaseVisitor extends CircuitScriptVisitor {
623
629
  pathExists = true;
624
630
  }
625
631
  catch (err) {
632
+ this.log('failed to read file');
626
633
  pathExists = false;
627
634
  }
628
635
  if (!pathExists) {
629
636
  try {
630
637
  const tmpFilePath2 = this.environment.getRelativeToDefaultLibs(name + ".cst");
638
+ this.log('checking default libs: ' + tmpFilePath2);
631
639
  filePathUsed = tmpFilePath2;
632
640
  fileData = await this.environment.readFile(tmpFilePath2, { encoding: 'utf8' });
633
641
  pathExists = true;
634
642
  }
635
643
  catch (err) {
644
+ this.log('failed to read file');
636
645
  pathExists = false;
637
646
  }
638
647
  }
@@ -12,6 +12,16 @@ export class SemanticTokensVisitor extends BaseVisitor {
12
12
  this.lexer = lexer;
13
13
  this.script = script;
14
14
  }
15
+ visitScript = async (ctx) => {
16
+ this.log('===', 'start', '===');
17
+ ctx.import_expr().forEach(ctxImport => {
18
+ this.visit(ctxImport);
19
+ });
20
+ const result = this.runExpressions(this.getExecutor(), ctx.expression());
21
+ this.setResult(ctx, result);
22
+ this.getExecutor().closeOpenPathBlocks();
23
+ this.log('===', 'end', '===');
24
+ };
15
25
  visitFunction_args_expr = (ctx) => {
16
26
  const IDs = ctx.ID();
17
27
  IDs.map(id => {
@@ -99,6 +109,10 @@ export class SemanticTokensVisitor extends BaseVisitor {
99
109
  this.addSemanticToken(ctx.ID(0), [], 'variable');
100
110
  }
101
111
  };
112
+ visitOperator_assignment_expr = (ctx) => {
113
+ this.visit(ctx.atom_expr());
114
+ this.visit(ctx.data_expr());
115
+ };
102
116
  visitImport_expr = (ctx) => {
103
117
  this.addSemanticToken(ctx.ID(), [], 'namespace');
104
118
  };
@@ -106,10 +120,16 @@ export class SemanticTokensVisitor extends BaseVisitor {
106
120
  ctx.ID().forEach(item => {
107
121
  this.addSemanticToken(item, [], 'variable');
108
122
  });
123
+ this.visit(ctx.data_expr());
124
+ this.visit(ctx.expressions_block());
125
+ };
126
+ visitAnnotation_comment_expr = (ctx) => {
127
+ this.addSemanticToken(ctx.ANNOTATION_START(), [], 'comment');
128
+ this.addSemanticToken(ctx.ID(), [], 'comment');
109
129
  };
110
130
  addSemanticToken(node, modifiers, tokenType = null) {
111
131
  const parsedToken = this.parseToken(node, modifiers, tokenType);
112
- this.semanticTokens.set(parsedToken.line + "_" + parsedToken.column, parsedToken);
132
+ this.semanticTokens.set(`${parsedToken.line}_${parsedToken.column}_${parsedToken.length}`, parsedToken);
113
133
  }
114
134
  parseToken(node, modifiers, tokenType = null) {
115
135
  const token = node.symbol;
@@ -13,6 +13,7 @@ export class NodeScriptEnvironment {
13
13
  }
14
14
  useModuleDirectoryPath = null;
15
15
  useDefaultLibsPath = null;
16
+ currentFile = '';
16
17
  globalCreateSVGWindow = null;
17
18
  cachedVersion = null;
18
19
  supportedFonts = {
@@ -112,6 +113,22 @@ export class NodeScriptEnvironment {
112
113
  async readFile(path, options) {
113
114
  return fs.promises.readFile(path, options);
114
115
  }
116
+ getAbsolutePath(filePath) {
117
+ return path.resolve(filePath);
118
+ }
119
+ getDirPath(filePath) {
120
+ return path.dirname(path.resolve(filePath));
121
+ }
122
+ setCurrentFile(filePath) {
123
+ this.currentFile = this.getAbsolutePath(filePath);
124
+ return this.currentFile;
125
+ }
126
+ getCurrentFile() {
127
+ return this.currentFile;
128
+ }
129
+ getRelativeToCurrentFolder(filePath) {
130
+ return path.join(this.getDirPath(this.currentFile), filePath);
131
+ }
115
132
  async exists(path) {
116
133
  try {
117
134
  fs.promises.access(path, fs.constants.F_OK);
@@ -4,7 +4,7 @@ import { ActiveObject, ExecutionScope, FrameAction, SequenceAction } from './obj
4
4
  import { Net } from './objects/Net.js';
5
5
  import { numeric, NumericValue } from './objects/ParamDefinition.js';
6
6
  import { PinId, PortSide } from './objects/PinDefinition.js';
7
- import { AnyReference, CFunctionEntry, DeclaredReference, Direction } from './objects/types.js';
7
+ import { AnyReference, CFunctionEntry, DeclaredReference, Direction, NetTypes } from './objects/types.js';
8
8
  import { Wire } from './objects/Wire.js';
9
9
  import { Frame } from './objects/Frame.js';
10
10
  import { CalculatePinPositions } from './layout.js';
@@ -180,8 +180,8 @@ export class ExecutionContext {
180
180
  paramsMap.set(param.paramName, param.paramValue);
181
181
  });
182
182
  if (component.typeProp === ComponentTypes.net) {
183
- const netName = paramsMap.get(ParamKeys.net_name);
184
- const netType = paramsMap.get(ParamKeys.net_type);
183
+ const netName = paramsMap.get(ParamKeys.net_name) ?? this.getUniqueNetName();
184
+ const netType = paramsMap.get(ParamKeys.net_type) ?? NetTypes.Any;
185
185
  let priority = 0;
186
186
  if (paramsMap.has(ParamKeys.priority)) {
187
187
  priority = paramsMap.get(ParamKeys.priority).toNumber();
@@ -75,7 +75,7 @@ export async function getSemanticTokens(scriptData, options) {
75
75
  const parsedTokens = prepareTokens(tokens.getTokens(), lexer, scriptData);
76
76
  const finalParsedTokens = [];
77
77
  parsedTokens.forEach(token => {
78
- const location = `${token.line}_${token.column}`;
78
+ const location = `${token.line}_${token.column}_${token.length}`;
79
79
  if (semanticTokens.has(location)) {
80
80
  finalParsedTokens.push(semanticTokens.get(location));
81
81
  }
@@ -176,7 +176,7 @@ export async function renderScript(scriptData, outputPath, options) {
176
176
  return renderScriptCustom(scriptData, outputPath, options, parseHandlers, [DefaultPostAnnotationCallback]);
177
177
  }
178
178
  export async function renderScriptCustom(scriptData, outputPath, options, parseHandlers, postAnnotationCallbacks) {
179
- const { dumpNets = false, dumpData = false, showStats = false, enableErc = false, enableBom = false, bomOutputPath = undefined, environment } = options;
179
+ const { dumpNets = false, dumpData = false, showStats = false, enableErc = false, enableBom = false, inputPath = '', bomOutputPath = undefined, environment } = options;
180
180
  const errors = [];
181
181
  const onErrorHandler = (message, context, error) => {
182
182
  if (error && error instanceof RuntimeExecutionError) {
@@ -203,7 +203,8 @@ export async function renderScriptCustom(scriptData, outputPath, options, parseH
203
203
  errors.push(new ParseError(message, context.start, context.stop));
204
204
  }
205
205
  };
206
- const visitor = new ParserVisitor(true, onErrorHandler, options.environment);
206
+ environment.setCurrentFile(inputPath);
207
+ const visitor = new ParserVisitor(true, onErrorHandler, environment);
207
208
  visitor.onImportFile = async (visitor, filePath, fileData) => {
208
209
  const { hasError, hasParseError } = await parseFileWithVisitor(visitor, fileData);
209
210
  if (hasError || hasParseError) {
@@ -68,6 +68,7 @@ export default async function validate() {
68
68
  const visitor = await validateScript(inputFilePath, scriptData, scriptOptions);
69
69
  const symbols = visitor.getSymbols().getSymbols();
70
70
  const undefinedSymbols = [];
71
+ console.log('----- symbols -----');
71
72
  symbols.forEach((value, key) => {
72
73
  if (value.type !== ParseSymbolType.Undefined) {
73
74
  value = value;
@@ -81,7 +82,9 @@ export default async function validate() {
81
82
  undefinedSymbols.push(value);
82
83
  }
83
84
  });
85
+ console.log('----- tokens -----');
84
86
  const { parsedTokens } = await getSemanticTokens(scriptData, scriptOptions);
87
+ console.log('----- dump tokens -----');
85
88
  parsedTokens.forEach(item => {
86
89
  const { line, column, tokenType, tokenModifiers, textValue } = item;
87
90
  console.log(`${line}:${column} - ${textValue} - ${tokenType} | ${tokenModifiers.join(',')}`);
@@ -1,6 +1,6 @@
1
1
  import { TerminalNode, Token } from "antlr4ng";
2
2
  import { CircuitScriptLexer } from "./antlr/CircuitScriptLexer.js";
3
- import { Function_def_exprContext, Create_component_exprContext, Create_graphic_exprContext, Atom_exprContext, Property_key_exprContext, ValueAtomExprContext, Assignment_exprContext, Import_exprContext, Function_args_exprContext, Function_call_exprContext, GraphicCommandExprContext, For_exprContext } from "./antlr/CircuitScriptParser.js";
3
+ import { Function_def_exprContext, Create_component_exprContext, Create_graphic_exprContext, Atom_exprContext, Property_key_exprContext, ValueAtomExprContext, Assignment_exprContext, Import_exprContext, Function_args_exprContext, Function_call_exprContext, GraphicCommandExprContext, For_exprContext, Annotation_comment_exprContext, ScriptContext, Operator_assignment_exprContext } from "./antlr/CircuitScriptParser.js";
4
4
  import { BaseVisitor, OnErrorHandler } from "./BaseVisitor.js";
5
5
  import { NodeScriptEnvironment } from "./environment.js";
6
6
  export declare class SemanticTokensVisitor extends BaseVisitor {
@@ -9,6 +9,7 @@ export declare class SemanticTokensVisitor extends BaseVisitor {
9
9
  script: string;
10
10
  semanticTokens: Map<string, IParsedToken>;
11
11
  constructor(silent: boolean | undefined, onErrorHandler: OnErrorHandler | null | undefined, environment: NodeScriptEnvironment, lexer: CircuitScriptLexer, script: string);
12
+ visitScript: (ctx: ScriptContext) => Promise<void>;
12
13
  visitFunction_args_expr: (ctx: Function_args_exprContext) => void;
13
14
  visitFunction_call_expr: (ctx: Function_call_exprContext) => void;
14
15
  visitFunction_def_expr: (ctx: Function_def_exprContext) => void;
@@ -19,8 +20,10 @@ export declare class SemanticTokensVisitor extends BaseVisitor {
19
20
  visitValueAtomExpr: (ctx: ValueAtomExprContext) => void;
20
21
  visitAssignment_expr: (ctx: Assignment_exprContext) => void;
21
22
  visitAtom_expr: (ctx: Atom_exprContext) => void;
23
+ visitOperator_assignment_expr: (ctx: Operator_assignment_exprContext) => void;
22
24
  visitImport_expr: (ctx: Import_exprContext) => void;
23
25
  visitFor_expr: (ctx: For_exprContext) => void;
26
+ visitAnnotation_comment_expr: (ctx: Annotation_comment_exprContext) => void;
24
27
  addSemanticToken(node: TerminalNode, modifiers: string[], tokenType?: string | null): void;
25
28
  parseToken(node: TerminalNode, modifiers: string[], tokenType?: string | null): IParsedToken;
26
29
  dumpTokens(): void;
@@ -8,6 +8,7 @@ export declare class NodeScriptEnvironment {
8
8
  static getInstance(): NodeScriptEnvironment;
9
9
  protected useModuleDirectoryPath: string | null;
10
10
  protected useDefaultLibsPath: string | null;
11
+ protected currentFile: string;
11
12
  protected globalCreateSVGWindow: (() => SVGWindow) | null;
12
13
  private cachedVersion;
13
14
  protected supportedFonts: {
@@ -28,5 +29,10 @@ export declare class NodeScriptEnvironment {
28
29
  getCanvasWindow(): Dom;
29
30
  prepareSVGEnvironment(): Promise<void>;
30
31
  readFile(path: PathOrFileDescriptor, options: any): Promise<string>;
32
+ getAbsolutePath(filePath: string): string;
33
+ getDirPath(filePath: string): string;
34
+ setCurrentFile(filePath: string): string;
35
+ getCurrentFile(): string;
36
+ getRelativeToCurrentFolder(filePath: string): string;
31
37
  exists(path: PathLike): Promise<boolean>;
32
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circuitscript",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
4
4
  "description": "Interpreter for the circuitscript language",
5
5
  "homepage": "https://circuitscript.net",
6
6
  "engines": {