circuitscript 0.5.6 → 0.6.0

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.
Files changed (41) hide show
  1. package/dist/cjs/BaseVisitor.js +1 -0
  2. package/dist/cjs/annotate/RefdesAnnotationVisitor.js +1 -3
  3. package/dist/cjs/antlr/CircuitScriptParser.js +1070 -840
  4. package/dist/cjs/cache/serializer.js +1 -1
  5. package/dist/cjs/execute.js +18 -7
  6. package/dist/cjs/objects/BlockTypes.js +1 -0
  7. package/dist/cjs/objects/Frame.js +4 -0
  8. package/dist/cjs/regenerate-tests.js +12 -3
  9. package/dist/cjs/render/draw_symbols.js +18 -12
  10. package/dist/cjs/render/geometry.js +2 -2
  11. package/dist/cjs/render/layout.js +26 -2
  12. package/dist/cjs/sizing.js +3 -2
  13. package/dist/cjs/visitor.js +85 -18
  14. package/dist/esm/BaseVisitor.js +1 -0
  15. package/dist/esm/annotate/RefdesAnnotationVisitor.js +1 -3
  16. package/dist/esm/antlr/CircuitScriptParser.js +1063 -835
  17. package/dist/esm/antlr/CircuitScriptParserVisitor.js +2 -0
  18. package/dist/esm/cache/serializer.js +1 -1
  19. package/dist/esm/execute.js +18 -7
  20. package/dist/esm/objects/BlockTypes.js +1 -0
  21. package/dist/esm/objects/Frame.js +4 -0
  22. package/dist/esm/regenerate-tests.js +12 -3
  23. package/dist/esm/render/draw_symbols.js +18 -12
  24. package/dist/esm/render/geometry.js +2 -2
  25. package/dist/esm/render/layout.js +26 -2
  26. package/dist/esm/sizing.js +3 -2
  27. package/dist/esm/visitor.js +85 -18
  28. package/dist/libs/std.cst +3 -1
  29. package/dist/types/BaseVisitor.d.ts +2 -2
  30. package/dist/types/antlr/CircuitScriptParser.d.ts +83 -63
  31. package/dist/types/antlr/CircuitScriptParserVisitor.d.ts +4 -0
  32. package/dist/types/execute.d.ts +1 -0
  33. package/dist/types/objects/BlockTypes.d.ts +2 -1
  34. package/dist/types/objects/Frame.d.ts +4 -0
  35. package/dist/types/render/draw_symbols.d.ts +3 -3
  36. package/dist/types/render/geometry.d.ts +1 -0
  37. package/dist/types/render/layout.d.ts +6 -0
  38. package/dist/types/sizing.d.ts +1 -1
  39. package/dist/types/visitor.d.ts +2 -1
  40. package/libs/std.cst +3 -1
  41. package/package.json +5 -1
@@ -2,6 +2,7 @@ import { AbstractParseTreeVisitor } from "antlr4ng";
2
2
  export class CircuitScriptParserVisitor extends AbstractParseTreeVisitor {
3
3
  visitScript;
4
4
  visitExpression;
5
+ visitNon_newline_expression;
5
6
  visitFlow_expressions;
6
7
  visitGraph_expressions;
7
8
  visitExpressions_block;
@@ -17,6 +18,7 @@ export class CircuitScriptParserVisitor extends AbstractParseTreeVisitor {
17
18
  visitAt_block_header;
18
19
  visitAt_block;
19
20
  visitAt_block_expressions;
21
+ visitAt_block_expressions_inner;
20
22
  visitAt_block_pin_expr;
21
23
  visitKeyword_assignment_expr;
22
24
  visitParameters;
@@ -62,7 +62,7 @@ export function serializeLibraryScope(importedLib, contentHash) {
62
62
  prevStopLine = null;
63
63
  };
64
64
  for (const exprCtx of tree.expression()) {
65
- if (exprCtx.function_def_expr() !== null) {
65
+ if (exprCtx.non_newline_expression()?.function_def_expr() !== null) {
66
66
  flushGroup();
67
67
  continue;
68
68
  }
@@ -379,6 +379,7 @@ export class ExecutionContext {
379
379
  this.applyComponentAngleFromWire(component, pinId);
380
380
  this.scope.setCurrent(component, pinId);
381
381
  this.scope.clearActive();
382
+ this.log('clear active wire/frame (to component)');
382
383
  if (addSequence) {
383
384
  if (this.scope.sequence.length > 0) {
384
385
  const [entryType, , segments] = this.scope.sequence[this.scope.sequence.length - 1];
@@ -415,6 +416,7 @@ export class ExecutionContext {
415
416
  this.scope.setNet(component, usePinId, tmpNet);
416
417
  }
417
418
  this.scope.clearActive();
419
+ this.log('clear active wire/frame (at component)');
418
420
  if (addSequence) {
419
421
  this.scope.sequence.push([SequenceAction.At,
420
422
  component, usePinId]);
@@ -453,8 +455,12 @@ export class ExecutionContext {
453
455
  || blockType === BlockTypes.Parallel
454
456
  || blockType === BlockTypes.Branch) {
455
457
  const key = getBlockTypeString(blockType);
458
+ const wireIdBefore = this.scope.currentWireId;
456
459
  this.addPoint(`${Delimiter1}${key}.${this.name}.${this.tmpPointId}`, false);
457
460
  this.tmpPointId += 1;
461
+ if (wireIdBefore !== -1) {
462
+ this.scope.currentWireId = wireIdBefore;
463
+ }
458
464
  }
459
465
  this.scope.blockStack.set(this.scope.scopeLevel, {
460
466
  start_point: [
@@ -547,9 +553,7 @@ export class ExecutionContext {
547
553
  }
548
554
  else if (blockType === BlockTypes.Join || blockType === BlockTypes.Parallel) {
549
555
  if (blockIndex === 0) {
550
- const pointIdName = `${Delimiter1}${getBlockTypeString(blockType)}`;
551
- this.addPoint(`${pointIdName}.${this.name}.${this.tmpPointId}`, false);
552
- this.tmpPointId += 1;
556
+ this.addPointForBlockType(blockType);
553
557
  stackRef.end_point = [
554
558
  this.scope.currentComponent,
555
559
  this.scope.currentPin,
@@ -563,6 +567,11 @@ export class ExecutionContext {
563
567
  }
564
568
  }
565
569
  }
570
+ addPointForBlockType(blockType) {
571
+ const pointIdName = `${Delimiter1}${getBlockTypeString(blockType)}`;
572
+ this.addPoint(`${pointIdName}.${this.name}.${this.tmpPointId}`, false);
573
+ this.tmpPointId += 1;
574
+ }
566
575
  atPointBlock() {
567
576
  const [component, pin,] = this.getPointBlockLocation();
568
577
  this.atComponent(component, pin, {
@@ -579,10 +588,12 @@ export class ExecutionContext {
579
588
  this.log('get block point');
580
589
  for (let i = 0; i < this.scope.scopeLevel; i++) {
581
590
  const stackRef = this.scope.blockStack.get(this.scope.scopeLevel - 1 - i);
582
- const { start_point } = stackRef;
583
- const component = start_point[0];
584
- if (component.instanceName.startsWith(`${Delimiter1}point.`)) {
585
- return start_point;
591
+ if (stackRef) {
592
+ const { start_point } = stackRef;
593
+ const component = start_point[0];
594
+ if (component.instanceName.startsWith(`${Delimiter1}point.`)) {
595
+ return start_point;
596
+ }
586
597
  }
587
598
  }
588
599
  this.log('did not find block point');
@@ -4,4 +4,5 @@ export var BlockTypes;
4
4
  BlockTypes[BlockTypes["Join"] = 2] = "Join";
5
5
  BlockTypes[BlockTypes["Parallel"] = 3] = "Parallel";
6
6
  BlockTypes[BlockTypes["Point"] = 4] = "Point";
7
+ BlockTypes[BlockTypes["AtBlock"] = 5] = "AtBlock";
7
8
  })(BlockTypes || (BlockTypes = {}));
@@ -35,6 +35,10 @@ export var FrameParamKeys;
35
35
  FrameParamKeys["TitleAlign"] = "title_align";
36
36
  FrameParamKeys["HorizontalAlign"] = "align";
37
37
  FrameParamKeys["VerticalAlign"] = "valign";
38
+ FrameParamKeys["FontSize"] = "font_size";
39
+ FrameParamKeys["Bold"] = "bold";
40
+ FrameParamKeys["Italic"] = "italic";
41
+ FrameParamKeys["Color"] = "color";
38
42
  FrameParamKeys["SheetNumber"] = "sheet_number";
39
43
  FrameParamKeys["SheetTotal"] = "sheet_total";
40
44
  })(FrameParamKeys || (FrameParamKeys = {}));
@@ -4,13 +4,15 @@ import { NodeScriptEnvironment } from "./environment/environment.js";
4
4
  const mainDir = './__tests__/testData/renderData/';
5
5
  const env = new NodeScriptEnvironment();
6
6
  NodeScriptEnvironment.setInstance(env);
7
- async function regenerateTests(extra = "") {
7
+ async function regenerateTests(extra = "", fileList = []) {
8
8
  await env.prepareSVGEnvironment();
9
9
  const cstFiles = [];
10
10
  const files = fs.readdirSync(mainDir);
11
11
  files.forEach(file => {
12
12
  if (file.endsWith('.cst') && file.startsWith('script')) {
13
- cstFiles.push(file);
13
+ if (fileList.length === 0 || fileList.includes(file)) {
14
+ cstFiles.push(file);
15
+ }
14
16
  }
15
17
  });
16
18
  for (let i = 0; i < cstFiles.length; i++) {
@@ -33,8 +35,15 @@ async function regenerateTests(extra = "") {
33
35
  (async () => {
34
36
  const generateDiff = (process.argv.indexOf('-diff') !== -1);
35
37
  console.log('diff flag: ', generateDiff);
38
+ const listIndex = process.argv.indexOf('--list');
39
+ const fileList = listIndex !== -1 && process.argv[listIndex + 1]
40
+ ? process.argv[listIndex + 1].split(',').map(f => f.trim())
41
+ : [];
42
+ if (fileList.length > 0) {
43
+ console.log('filtering to files: ', fileList);
44
+ }
36
45
  const nextExtra = generateDiff ? '.next' : '';
37
- const cstFiles = await regenerateTests(nextExtra);
46
+ const cstFiles = await regenerateTests(nextExtra, fileList);
38
47
  const allFiles = [];
39
48
  if (generateDiff) {
40
49
  cstFiles.forEach(file => {
@@ -139,7 +139,7 @@ export class SymbolGraphic {
139
139
  const labels = this.drawing.getLabels();
140
140
  for (const label of labels) {
141
141
  const tmpLabel = label;
142
- const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', angle: tmpLabelAngle = numeric(0), textColor = "#333", } = tmpLabel.style ?? {};
142
+ const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', fontStyle = 'normal', angle: tmpLabelAngle = numeric(0), textColor = "#333", } = tmpLabel.style ?? {};
143
143
  let anchorStyle = 'start';
144
144
  let dominantBaseline = 'auto';
145
145
  let useAnchor = anchor;
@@ -293,15 +293,19 @@ export class SymbolGraphic {
293
293
  if (isRotation180) {
294
294
  useLabelAngle = (labelAngle + 180) % 360;
295
295
  }
296
- textContainer.text(tmpLabel.text)
297
- .fill(textColor)
298
- .font({
296
+ const fontProperties = {
299
297
  family: useFont,
300
298
  size: fontSize.toNumber() * fontDisplayScale,
301
299
  anchor: anchorStyle,
302
300
  'dominant-baseline': dominantBaseline,
303
301
  weight: fontWeight,
304
- })
302
+ };
303
+ if (fontStyle !== 'normal') {
304
+ fontProperties.style = fontStyle;
305
+ }
306
+ textContainer.text(tmpLabel.text)
307
+ .fill(textColor)
308
+ .font(fontProperties)
305
309
  .attr("xml:space", "preserve")
306
310
  .rotate(useLabelAngle, 0, 0);
307
311
  const { a, b, c, d, e, f } = textContainer.matrix();
@@ -349,6 +353,8 @@ export class SymbolText extends SymbolGraphic {
349
353
  text;
350
354
  fontSize = numeric(40);
351
355
  fontWeight = 'regular';
356
+ fontStyle = 'normal';
357
+ color = undefined;
352
358
  constructor(text) {
353
359
  super();
354
360
  this.text = text;
@@ -360,6 +366,8 @@ export class SymbolText extends SymbolGraphic {
360
366
  fontSize: this.fontSize,
361
367
  anchor: HorizontalAlign.Center,
362
368
  fontWeight: this.fontWeight,
369
+ fontStyle: this.fontStyle,
370
+ textColor: this.color
363
371
  });
364
372
  this.drawing = drawing;
365
373
  }
@@ -504,18 +512,16 @@ export class SymbolPlaceholder extends SymbolGraphic {
504
512
  }
505
513
  parseLabelStyle(keywordParams) {
506
514
  const keywords = ['fontSize', 'anchor', 'vanchor',
507
- 'angle', 'textColor', 'portType', 'bold'];
515
+ 'angle', 'textColor', 'portType', 'bold', 'italic'];
508
516
  const style = {};
509
517
  keywords.forEach(item => {
510
518
  if (keywordParams.has(item)) {
511
519
  style[item] = keywordParams.get(item);
512
520
  if (item === 'bold') {
513
- if (keywordParams.get(item) === true) {
514
- style['fontWeight'] = 'bold';
515
- }
516
- else {
517
- style['fontWeight'] = 'normal';
518
- }
521
+ style.fontWeight = keywordParams.get(item) === true ? 'bold' : 'regular';
522
+ }
523
+ else if (item === 'italic') {
524
+ style.fontStyle = keywordParams.get(item) === true ? 'italic' : 'normal';
519
525
  }
520
526
  }
521
527
  });
@@ -44,8 +44,8 @@ export class Textbox extends Flatten.Polygon {
44
44
  else {
45
45
  throw 'Invalid string passed into textbox';
46
46
  }
47
- const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', portType = null, } = style ?? {};
48
- const { box } = measureTextSize2(useText, defaultFont, fontSize.mul(fontDisplayScale).toNumber(), fontWeight, anchor, vanchor);
47
+ const { fontSize = numeric(50), anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', fontStyle = 'normal', portType = null, } = style ?? {};
48
+ const { box } = measureTextSize2(useText, defaultFont, fontSize.mul(fontDisplayScale).toNumber(), fontWeight, fontStyle, anchor, vanchor);
49
49
  let polygonCoords = [];
50
50
  let anchorOffsetX = 0;
51
51
  let anchorOffsetY = 0;
@@ -551,12 +551,20 @@ export class LayoutEngine {
551
551
  const isSheetFrame = frameObject.frameType === FrameType.Sheet;
552
552
  if (frameParams.has(FrameParamKeys.Title) && !isSheetFrame) {
553
553
  const title = frameParams.get(FrameParamKeys.Title);
554
+ const fontSize = frameParams.get(FrameParamKeys.FontSize) ?? numeric(defaultFrameTitleTextSize);
555
+ const isBold = frameParams.get(FrameParamKeys.Bold) ?? true;
556
+ const isItalic = frameParams.get(FrameParamKeys.Italic) ?? false;
557
+ const titleColor = frameParams.get(FrameParamKeys.Color) ?? null;
554
558
  const titleFrame = new RenderFrame(new Frame(FixedFrameIds.FrameIdNotUsed), RenderFrameType.Elements);
555
559
  titleFrame.containsTitle = true;
556
560
  titleFrame.subgraphId = title.replace(/\s/g, "_");
557
561
  const textObject = new RenderText(title);
558
- textObject.fontSize = numeric(defaultFrameTitleTextSize);
559
- textObject.fontWeight = 'bold';
562
+ textObject.fontSize = fontSize;
563
+ textObject.fontWeight = isBold ? 'bold' : 'regular';
564
+ textObject.fontStyle = isItalic ? 'italic' : 'normal';
565
+ if (titleColor !== null) {
566
+ textObject.color = titleColor;
567
+ }
560
568
  textObject.x = numeric(0);
561
569
  textObject.y = numeric(0);
562
570
  textObject.symbol.refreshDrawing();
@@ -1212,6 +1220,8 @@ export class RenderText extends RenderObject {
1212
1220
  symbol;
1213
1221
  _fontSize = numeric(12);
1214
1222
  _fontWeight = 'regular';
1223
+ _fontStyle = 'normal';
1224
+ _color = undefined;
1215
1225
  get fontSize() {
1216
1226
  return this._fontSize;
1217
1227
  }
@@ -1226,6 +1236,20 @@ export class RenderText extends RenderObject {
1226
1236
  this._fontWeight = value;
1227
1237
  this.symbol.fontWeight = value;
1228
1238
  }
1239
+ get fontStyle() {
1240
+ return this._fontStyle;
1241
+ }
1242
+ set fontStyle(value) {
1243
+ this._fontStyle = value;
1244
+ this.symbol.fontStyle = value;
1245
+ }
1246
+ get color() {
1247
+ return this._color;
1248
+ }
1249
+ set color(value) {
1250
+ this._color = value;
1251
+ this.symbol.color = value;
1252
+ }
1229
1253
  constructor(text) {
1230
1254
  super();
1231
1255
  this.symbol = new SymbolText(text);
@@ -6,10 +6,10 @@ export function applyFontsToSVG(canvas) {
6
6
  }
7
7
  const measureTextSizeCache = {};
8
8
  const measureTextSizeCacheHits = {};
9
- export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regular', anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom) {
9
+ export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regular', fontStyle = 'normal', anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom) {
10
10
  const environment = NodeScriptEnvironment.getInstance();
11
11
  const mainCanvas = environment.getCanvasWindow();
12
- const key = `${text}-${fontFamily}-${fontSize}-${fontWeight}-${anchor}-${vanchor}`;
12
+ const key = `${text}-${fontFamily}-${fontSize}-${fontWeight}-${fontStyle}-${anchor}-${vanchor}`;
13
13
  if (measureTextSizeCache[key] === undefined) {
14
14
  let dominantBaseline = VerticalAlignProp.Hanging;
15
15
  switch (vanchor) {
@@ -42,6 +42,7 @@ export function measureTextSize2(text, fontFamily, fontSize, fontWeight = 'regul
42
42
  anchor: useAnchor,
43
43
  'dominant-baseline': dominantBaseline,
44
44
  weight: fontWeight,
45
+ style: fontStyle,
45
46
  })
46
47
  .attr("xml:space", "preserve")
47
48
  .fill('#333');
@@ -80,7 +80,7 @@ export class ParserVisitor extends BaseVisitor {
80
80
  return this.getExecutor().getCurrentPoint();
81
81
  };
82
82
  visitTo_component_expr = (ctx) => {
83
- ctx.component_select_expr().forEach(item => {
83
+ for (const item of ctx.component_select_expr()) {
84
84
  let refComponent;
85
85
  const creationFlag = this.trackNewComponentCreated(() => {
86
86
  const [component, pin] = this.visitResult(item);
@@ -95,7 +95,7 @@ export class ParserVisitor extends BaseVisitor {
95
95
  }
96
96
  });
97
97
  this.linkComponentToCtx(item, refComponent, creationFlag);
98
- });
98
+ }
99
99
  return this.getExecutor().getCurrentPoint();
100
100
  };
101
101
  visitComponent_select_expr = (ctx) => {
@@ -154,7 +154,18 @@ export class ParserVisitor extends BaseVisitor {
154
154
  const blockStackEntry = scope.blockStack.get(scopeLevel);
155
155
  const { current_index } = blockStackEntry;
156
156
  executor.enterBlock(current_index);
157
- this.visit(ctx.expressions_block());
157
+ const ctxNonNewlineExpressions = ctx.non_newline_expression();
158
+ const ctxExpressionsBlock = ctx.expressions_block();
159
+ const ctxAtBlockExpressions = ctx.at_block_expressions();
160
+ if (ctxNonNewlineExpressions.length > 0) {
161
+ this.runExpressions(executor, ctxNonNewlineExpressions);
162
+ }
163
+ else if (ctxExpressionsBlock) {
164
+ this.visit(ctxExpressionsBlock);
165
+ }
166
+ else if (ctxAtBlockExpressions) {
167
+ this.visit(ctxAtBlockExpressions);
168
+ }
158
169
  executor.exitBlock(current_index);
159
170
  blockStackEntry.current_index++;
160
171
  };
@@ -959,24 +970,63 @@ export class ParserVisitor extends BaseVisitor {
959
970
  };
960
971
  visitAt_block_pin_expr = (ctx) => {
961
972
  const executor = this.getExecutor();
962
- const [currentComponent, currentPin] = executor.getCurrentPoint();
973
+ const scope = this.getScope();
974
+ const scopeLevel = scope.scopeLevel;
975
+ const params = this.getResult(ctx);
976
+ const blockIndex = params.index;
977
+ let useComponent;
978
+ for (let i = scopeLevel - 1; i >= 0; i--) {
979
+ const blockStackEntry = scope.blockStack.get(i);
980
+ if (blockStackEntry.type === BlockTypes.AtBlock) {
981
+ useComponent = blockStackEntry.start_point[0];
982
+ break;
983
+ }
984
+ }
963
985
  executor.closeOpenPathBlocks();
964
986
  const propKey = this.visitResult(ctx.property_key_expr());
965
987
  const atPin = new PinId(propKey);
966
- executor.atComponent(currentComponent, atPin, {
988
+ executor.atComponent(useComponent, atPin, {
967
989
  addSequence: true
968
990
  });
969
- executor.log('at block pin expressions');
970
- const ctxExpression = ctx.expression();
991
+ executor.log(`at block pin expressions, pin id: ${atPin}`);
992
+ const ctxExpression = ctx.non_newline_expression();
971
993
  const ctxExpressionsBlock = ctx.expressions_block();
972
- if (ctxExpression) {
973
- this.visit(ctxExpression);
994
+ if (ctxExpression.length > 0) {
995
+ this.runExpressions(executor, ctxExpression);
974
996
  }
975
997
  else if (ctxExpressionsBlock) {
976
998
  this.visit(ctxExpressionsBlock);
977
999
  }
978
- executor.log('end at block pin expressions');
979
- executor.atComponent(currentComponent, currentPin);
1000
+ const parentBlockStackEntry = scope.blockStack.get(scopeLevel - 1);
1001
+ if (parentBlockStackEntry.type === BlockTypes.Join) {
1002
+ if (blockIndex === 0 && parentBlockStackEntry.current_index === 0) {
1003
+ executor.addPointForBlockType(BlockTypes.Join);
1004
+ parentBlockStackEntry.end_point = [
1005
+ scope.currentComponent,
1006
+ scope.currentPin,
1007
+ scope.currentWireId
1008
+ ];
1009
+ }
1010
+ else {
1011
+ const { end_point: finalPoint } = parentBlockStackEntry;
1012
+ const [component, pin] = finalPoint;
1013
+ executor.toComponent(component, pin, { addSequence: true });
1014
+ }
1015
+ }
1016
+ };
1017
+ visitAt_block_expressions = (ctx) => {
1018
+ let atBlockPinIndex = 0;
1019
+ for (const tmpCtx of ctx.at_block_expressions_inner()) {
1020
+ const ctxAtBlockPin = tmpCtx.at_block_pin_expr();
1021
+ if (ctxAtBlockPin) {
1022
+ this.setResult(ctxAtBlockPin, { index: atBlockPinIndex });
1023
+ atBlockPinIndex++;
1024
+ this.visit(ctxAtBlockPin);
1025
+ }
1026
+ else {
1027
+ this.visit(tmpCtx.expression());
1028
+ }
1029
+ }
980
1030
  };
981
1031
  visitAt_block_header = (ctx) => {
982
1032
  const ctxAtComponent = ctx.at_component_expr();
@@ -990,16 +1040,30 @@ export class ParserVisitor extends BaseVisitor {
990
1040
  };
991
1041
  visitAt_block = (ctx) => {
992
1042
  const executor = this.getExecutor();
993
- executor.log('entering at block');
1043
+ const scope = this.getScope();
1044
+ const scopeLevel = scope.scopeLevel;
1045
+ if (scope.blockStack.has(scopeLevel)) {
1046
+ executor.exitBlocks();
1047
+ }
994
1048
  const ctxAtBlockComponent = ctx.at_block_header();
995
1049
  this.visit(ctxAtBlockComponent);
996
1050
  const [currentComponent, currentPin] = executor.getCurrentPoint();
997
- executor.scope.scopeLevel += 1;
998
- ctx.at_block_expressions().forEach(expression => {
999
- this.visit(expression);
1051
+ scope.blockStack.set(scopeLevel, {
1052
+ start_point: [
1053
+ scope.currentComponent,
1054
+ scope.currentPin,
1055
+ scope.currentWireId
1056
+ ],
1057
+ end_point: null,
1058
+ current_index: 0,
1059
+ type: BlockTypes.AtBlock,
1000
1060
  });
1061
+ executor.log('entering at block');
1062
+ executor.scope.scopeLevel += 1;
1063
+ this.visit(ctx.at_block_expressions());
1001
1064
  executor.scope.scopeLevel -= 1;
1002
1065
  executor.scope.setCurrent(currentComponent, currentPin);
1066
+ scope.blockStack.delete(scopeLevel);
1003
1067
  executor.log('leaving at block');
1004
1068
  };
1005
1069
  visitWire_expr = (ctx) => {
@@ -1072,9 +1136,12 @@ export class ParserVisitor extends BaseVisitor {
1072
1136
  if (ctx.Sheet()) {
1073
1137
  frameType = FrameType.Sheet;
1074
1138
  }
1075
- const frameId = this.getExecutor().enterFrame(frameType);
1076
- this.visit(ctx.expressions_block());
1077
- this.getExecutor().exitFrame(frameId);
1139
+ const ctxExpressionsBlock = ctx.expressions_block();
1140
+ if (ctxExpressionsBlock) {
1141
+ const frameId = this.getExecutor().enterFrame(frameType);
1142
+ this.visit(ctxExpressionsBlock);
1143
+ this.getExecutor().exitFrame(frameId);
1144
+ }
1078
1145
  };
1079
1146
  visitNet_namespace_expr = (ctx) => {
1080
1147
  let dataValue;
package/dist/libs/std.cst CHANGED
@@ -181,7 +181,7 @@ def dgnd(net_name="GND"):
181
181
  net_name: net_name
182
182
  priority: 100
183
183
 
184
- def text(value, offsetX = 0, offsetY = 0, fontSize = 50):
184
+ def text(value, offsetX = 0, offsetY = 0, fontSize = 50, bold = false, italic = false):
185
185
  return create component:
186
186
  pins: 1
187
187
  followWireOrientation: false
@@ -192,6 +192,8 @@ def text(value, offsetX = 0, offsetY = 0, fontSize = 50):
192
192
  content: value
193
193
  offset: offsetX, offsetY
194
194
  fontSize: fontSize
195
+ bold: bold
196
+ italic: italic
195
197
 
196
198
  # Drawing markers
197
199
 
@@ -1,4 +1,4 @@
1
- import { ArrayExprContext, Assignment_exprContext, Callable_exprContext, CallableExprContext, Double_dot_property_set_exprContext, ExpressionContext, Flow_expressionsContext, Function_args_exprContext, Function_exprContext, Function_return_exprContext, Import_exprContext, Import_simpleContext, Import_specific_or_allContext, Keyword_assignment_exprContext, ParametersContext, RoundedBracketsExprContext, ScriptContext, TrailerContext, Value_exprContext, ValueExprContext } from "./antlr/CircuitScriptParser.js";
1
+ import { ArrayExprContext, Assignment_exprContext, Callable_exprContext, CallableExprContext, Double_dot_property_set_exprContext, ExpressionContext, Flow_expressionsContext, Function_args_exprContext, Function_exprContext, Function_return_exprContext, Import_exprContext, Import_simpleContext, Import_specific_or_allContext, Keyword_assignment_exprContext, Non_newline_expressionContext, ParametersContext, RoundedBracketsExprContext, ScriptContext, TrailerContext, Value_exprContext, ValueExprContext } from "./antlr/CircuitScriptParser.js";
2
2
  import { CircuitScriptParserVisitor } from "./antlr/CircuitScriptParserVisitor.js";
3
3
  import { ExecutionContext } from "./execute.js";
4
4
  import { Logger } from "./logger.js";
@@ -87,7 +87,7 @@ export declare class BaseVisitor extends CircuitScriptParserVisitor<ComplexType
87
87
  getRefdesFileAnnotationKey(filePath: string, startLine: number, startColumn: number, stopLine: number, stopColumn: number): string;
88
88
  visitRoundedBracketsExpr: (ctx: RoundedBracketsExprContext) => void;
89
89
  protected setupDefinedParameters(funcDefinedParameters: FunctionDefinedParameter[], passedInParameters: CallableParameter[], executor: ExecutionContext): void;
90
- protected runExpressions(executor: ExecutionContext, expressions: ExpressionContext[] | Function_exprContext[]): ComplexType;
90
+ protected runExpressions(executor: ExecutionContext, expressions: ExpressionContext[] | Function_exprContext[] | Non_newline_expressionContext[]): ComplexType;
91
91
  protected getNetNamespace(executorNetNamespace: string, passedNetNamespace: string | null): string;
92
92
  protected setInstanceParam(object: ClassComponent, trailers: string[], value: any): void;
93
93
  protected getInstanceParam<T>(object: ClassComponent, trailers: string[]): T;