@shapeshift-labs/frontier-lang-parser 0.3.50 → 0.3.51

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.
@@ -32,14 +32,12 @@ function parseActionBodyRecords(source, state) {
32
32
  const index = state.index++;
33
33
  const record = parseActionIfBlock(ifHeader[1].trim(), source.slice(open + 1, close), index, state, elseBlock);
34
34
  if (record) records.push(record);
35
- offset = elseBlock ? elseBlock.close + 1 : close + 1;
35
+ offset = elseBlock ? elseBlock.end : close + 1;
36
36
  continue;
37
37
  }
38
- const elseHeader = /^else\b([^{\n]*)\{/.exec(source.slice(offset));
39
- if (elseHeader) {
40
- const open = offset + elseHeader[0].length - 1;
41
- const close = findMatchingBrace(source, open);
42
- offset = close < 0 ? source.length : close + 1;
38
+ const elseBlock = readElseHeaderBlock(source, offset, source.length, { skipWhitespace: skipWhitespaceAndComments, findMatchingBrace });
39
+ if (elseBlock) {
40
+ offset = elseBlock.end;
43
41
  continue;
44
42
  }
45
43
  const lineEnd = source.indexOf('\n', offset);
@@ -57,7 +55,7 @@ function parseActionBodyRecords(source, state) {
57
55
  function parseActionIfBlock(header, body, index, state, elseBlock) {
58
56
  const details = parseActionIfHeader(header, index);
59
57
  if (!details.condition) return undefined;
60
- const elseDetails = elseBlock ? parseActionElseHeader(elseBlock.header, index) : undefined;
58
+ const elseDetails = parseActionElseBlock(elseBlock, state, index);
61
59
  return compactRecord({
62
60
  kind: 'if',
63
61
  id: details.id,
@@ -68,10 +66,20 @@ function parseActionIfBlock(header, body, index, state, elseBlock) {
68
66
  body: parseActionBodyRecords(body, state),
69
67
  elseId: elseDetails?.id,
70
68
  elseName: elseDetails?.name,
71
- elseBody: elseBlock ? parseActionBodyRecords(elseBlock.body, state) : undefined
69
+ elseBody: elseDetails?.body
72
70
  });
73
71
  }
74
72
 
73
+ function parseActionElseBlock(elseBlock, state, index) {
74
+ if (!elseBlock) return undefined;
75
+ if (elseBlock.isElseIf) {
76
+ const nested = parseActionIfBlock(elseBlock.header, elseBlock.body, state.index++, state, elseBlock.tail);
77
+ return nested ? { id: nested.id, name: nested.name, body: [nested] } : undefined;
78
+ }
79
+ const details = parseActionElseHeader(elseBlock.header, index);
80
+ return { ...details, body: parseActionBodyRecords(elseBlock.body, state) };
81
+ }
82
+
75
83
  function parseActionIfHeader(header, index) {
76
84
  const withoutId = header.replace(/@id\(\s*["'][^"']+["']\s*\)/g, '').trim();
77
85
  const explicitCondition = /\bcondition\s+(.+)$/.exec(withoutId);
@@ -3,16 +3,27 @@ export function readElseHeaderBlock(source, offset, endOffset = source.length, h
3
3
  const findMatchingBrace = helpers.findMatchingBrace;
4
4
  if (typeof skipWhitespace !== 'function' || typeof findMatchingBrace !== 'function') return undefined;
5
5
  const elseOffset = skipWhitespace(source, offset, endOffset);
6
+ const elseIfHeader = /^else\s+if\b([^{\n]*)\{/.exec(source.slice(elseOffset, endOffset));
7
+ if (elseIfHeader) return readBlock(source, elseOffset, elseIfHeader, endOffset, findMatchingBrace, true, helpers);
6
8
  const elseHeader = /^else\b([^{\n]*)\{/.exec(source.slice(elseOffset, endOffset));
7
9
  if (!elseHeader) return undefined;
10
+ return readBlock(source, elseOffset, elseHeader, endOffset, findMatchingBrace, false, helpers);
11
+ }
12
+
13
+ function readBlock(source, elseOffset, elseHeader, endOffset, findMatchingBrace, isElseIf, helpers) {
8
14
  const header = elseHeader[1].trim();
9
15
  const open = elseOffset + elseHeader[0].length - 1;
10
16
  const close = findMatchingBrace(source, open);
11
17
  if (close < 0 || close > endOffset) return undefined;
12
- return { header, start: elseOffset, open, close, body: source.slice(open + 1, close), supported: isSupportedElseHeader(header) };
18
+ const tail = isElseIf ? readElseHeaderBlock(source, close + 1, endOffset, helpers) : undefined;
19
+ return { header, start: elseOffset, open, close, end: tail?.end ?? close + 1, body: source.slice(open + 1, close), isElseIf, tail, supported: isElseIf ? isSupportedElseIfHeader(header) : isSupportedElseHeader(header) };
13
20
  }
14
21
 
15
22
  export function isSupportedElseHeader(header) {
16
23
  const withoutId = String(header ?? '').replace(/@id\(\s*["'][^"']+["']\s*\)/g, '').trim();
17
24
  return !withoutId || /^[A-Za-z_$][\w$-]*$/.test(withoutId);
18
25
  }
26
+
27
+ function isSupportedElseIfHeader(header) {
28
+ return String(header ?? '').replace(/@id\(\s*["'][^"']+["']\s*\)/g, '').trim().length > 0;
29
+ }
@@ -36,14 +36,15 @@ function readActionSyntaxRows(source, block, options, state, startOffset, endOff
36
36
  children.push(...readActionSyntaxRows(source, block, options, state, open + 1, close, child.id));
37
37
  const elseBlock = readElseHeaderBlock(source, close + 1, endOffset, { skipWhitespace: skipWhitespaceAndLineComments, findMatchingBrace });
38
38
  if (elseBlock) {
39
- const elseChild = actionSyntaxChild(source, block, options, {
40
- text: source.slice(elseBlock.start, elseBlock.open + 1).trim(),
41
- startOffset: elseBlock.start,
42
- endOffset: elseBlock.open + 1
43
- }, state, child.id, { recognized: elseBlock.supported });
44
- children.push(elseChild);
45
- if (elseBlock.supported) children.push(...readActionSyntaxRows(source, block, options, state, elseBlock.open + 1, elseBlock.close, elseChild.id));
46
- offset = elseBlock.close + 1;
39
+ let branch = elseBlock, parentId = child.id;
40
+ while (branch) {
41
+ const elseChild = actionSyntaxChild(source, block, options, { text: source.slice(branch.start, branch.open + 1).trim(), startOffset: branch.start, endOffset: branch.open + 1 }, state, parentId, { recognized: branch.supported });
42
+ children.push(elseChild);
43
+ if (branch.supported) children.push(...readActionSyntaxRows(source, block, options, state, branch.open + 1, branch.close, elseChild.id));
44
+ parentId = elseChild.id;
45
+ branch = branch.tail;
46
+ }
47
+ offset = elseBlock.end;
47
48
  continue;
48
49
  }
49
50
  offset = close + 1;
@@ -56,7 +57,7 @@ function readActionSyntaxRows(source, block, options, state, startOffset, endOff
56
57
  startOffset: elseBlock.start,
57
58
  endOffset: elseBlock.open + 1
58
59
  }, state, parentActionBodyId));
59
- offset = elseBlock.close + 1;
60
+ offset = elseBlock.end;
60
61
  continue;
61
62
  }
62
63
  const lineEnd = source.indexOf('\n', offset);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-parser",
3
- "version": "0.3.50",
3
+ "version": "0.3.51",
4
4
  "description": "Parser for the first Frontier Lang .frontier syntax slice.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",