@shapeshift-labs/frontier-lang-parser 0.3.74 → 0.3.76
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/index.js +4 -2
- package/dist/machine-graph-metadata.js +66 -0
- package/dist/machine-graph.js +307 -0
- package/dist/metadata.js +3 -2
- package/dist/resource-graph.js +18 -1
- package/dist/source-block-kinds.js +3 -0
- package/dist/source-syntax-children.js +8 -10
- package/dist/source-syntax-row-config.js +20 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { parseDecisionGraphBlock } from './decision-graph.js';
|
|
|
8
8
|
import { parseDialectRegistryBlock } from './dialect-registry.js';
|
|
9
9
|
import { parseGateAdmissionEvidenceBlock } from './gate-admission-evidence.js';
|
|
10
10
|
import { parseInterlinguaBlock } from './interlingua.js';
|
|
11
|
+
import { parseMachineGraphBlock } from './machine-graph.js';
|
|
11
12
|
import { createParsedMetadata } from './metadata.js';
|
|
12
13
|
import { parseEntityBlock, parseStateBlock, readTypeFields } from './member-records.js';
|
|
13
14
|
import { parseSemanticEditRecordsBlock } from './semantic-edit-records.js';
|
|
@@ -38,7 +39,7 @@ export function parseFrontierSource(source, options = {}) {
|
|
|
38
39
|
const gateAdmissionEvidenceBlocks = [];
|
|
39
40
|
const dialectRegistryBlocks = [];
|
|
40
41
|
const interlinguaBlocks = [];
|
|
41
|
-
const resourceGraphBlocks = [];
|
|
42
|
+
const resourceGraphBlocks = [], machineGraphBlocks = [];
|
|
42
43
|
const nativeSourceBlocks = [];
|
|
43
44
|
const packageManifestBlocks = [];
|
|
44
45
|
const canvasSurfaceBlocks = [];
|
|
@@ -74,12 +75,13 @@ export function parseFrontierSource(source, options = {}) {
|
|
|
74
75
|
if (block.kind === 'dialectRegistry' || block.kind === 'universalDialectRegistry') dialectRegistryBlocks.push(parseDialectRegistryBlock(block));
|
|
75
76
|
if (block.kind === 'interlingua' || block.kind === 'universalInterlingua') interlinguaBlocks.push(parseInterlinguaBlock(block));
|
|
76
77
|
if (block.kind === 'resourceGraph' || block.kind === 'semanticResourceGraph') resourceGraphBlocks.push(parseResourceGraphBlock(block));
|
|
78
|
+
if (block.kind === 'machineGraph' || block.kind === 'executionGraph' || block.kind === 'lowLevelGraph') machineGraphBlocks.push(parseMachineGraphBlock(block));
|
|
77
79
|
if (block.kind === 'packageManifest' || block.kind === 'packageGraph' || block.kind === 'packageSurface') packageManifestBlocks.push(parsePackageManifestBlock(block));
|
|
78
80
|
if (block.kind === 'canvasSurface' || block.kind === 'canvasGraph') canvasSurfaceBlocks.push(parseCanvasSurfaceBlock(block));
|
|
79
81
|
if (block.kind === 'applicationSurface' || block.kind === 'appHost' || block.kind === 'plugin' || block.kind === 'pluginSurface' || block.kind === 'pluginContract') applicationSurfaceBlocks.push(parseApplicationSurfaceBlock(block));
|
|
80
82
|
if (block.kind === 'runtimeCapabilities' || block.kind === 'runtimeCapabilityMatrix' || block.kind === 'runtimeHosts') runtimeCapabilityBlocks.push(parseRuntimeCapabilityBlock(block));
|
|
81
83
|
}
|
|
82
|
-
const metadata = createParsedMetadata({ proofBlocks, paradigmBlocks, operationBlocks, semanticEditBlocks, conversionBlocks, constraintSpaceBlocks, decisionGraphBlocks, gateAdmissionEvidenceBlocks, dialectRegistryBlocks, interlinguaBlocks, resourceGraphBlocks, nativeSourceBlocks, packageManifestBlocks, canvasSurfaceBlocks, applicationSurfaceBlocks, runtimeCapabilityBlocks, targetProjectionTargets });
|
|
84
|
+
const metadata = createParsedMetadata({ proofBlocks, paradigmBlocks, operationBlocks, semanticEditBlocks, conversionBlocks, constraintSpaceBlocks, decisionGraphBlocks, gateAdmissionEvidenceBlocks, dialectRegistryBlocks, interlinguaBlocks, resourceGraphBlocks, machineGraphBlocks, nativeSourceBlocks, packageManifestBlocks, canvasSurfaceBlocks, applicationSurfaceBlocks, runtimeCapabilityBlocks, targetProjectionTargets });
|
|
83
85
|
return createDocument({ id: documentId, name: documentName, nodes, ...(metadata ? { metadata } : {}) });
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export function mergeMachineGraphBlocks(blocks) {
|
|
2
|
+
const graphs = blocks.map((block) => block.graph).filter(Boolean);
|
|
3
|
+
const records = blocks.flatMap((block) => block.records ?? []);
|
|
4
|
+
return {
|
|
5
|
+
id: blocks.length === 1 ? blocks[0].id : 'machineGraphs:source',
|
|
6
|
+
graphs,
|
|
7
|
+
machineGraphs: graphs,
|
|
8
|
+
records,
|
|
9
|
+
graphIds: ids(graphs),
|
|
10
|
+
recordIds: ids(records),
|
|
11
|
+
labelIds: blocks.flatMap((block) => ids(block.graph?.labels)),
|
|
12
|
+
directiveIds: blocks.flatMap((block) => ids(block.graph?.directives)),
|
|
13
|
+
registerIds: blocks.flatMap((block) => ids(block.graph?.registers)),
|
|
14
|
+
flagIds: blocks.flatMap((block) => ids(block.graph?.flags)),
|
|
15
|
+
basicBlockIds: blocks.flatMap((block) => ids(block.graph?.basicBlocks)),
|
|
16
|
+
instructionIds: blocks.flatMap((block) => ids(block.graph?.instructions)),
|
|
17
|
+
operandIds: blocks.flatMap((block) => ids(block.graph?.operands)),
|
|
18
|
+
memoryEffectIds: blocks.flatMap((block) => ids(block.graph?.memoryEffects)),
|
|
19
|
+
controlEdgeIds: blocks.flatMap((block) => ids(block.graph?.controlEdges)),
|
|
20
|
+
branchIds: blocks.flatMap((block) => ids(block.graph?.branches)),
|
|
21
|
+
callIds: blocks.flatMap((block) => ids(block.graph?.calls)),
|
|
22
|
+
returnIds: blocks.flatMap((block) => ids(block.graph?.returns)),
|
|
23
|
+
interruptIds: blocks.flatMap((block) => ids(block.graph?.interrupts)),
|
|
24
|
+
proofObligationIds: blocks.flatMap((block) => ids(block.graph?.proofObligations)),
|
|
25
|
+
proofGapCodes: unique(blocks.flatMap((block) => block.graph?.query?.proofGapCodes ?? [])),
|
|
26
|
+
evidenceIds: unique(blocks.flatMap((block) => block.graph?.query?.evidenceIds ?? [])),
|
|
27
|
+
proofEvidenceIds: unique(blocks.flatMap((block) => block.graph?.query?.proofEvidenceIds ?? [])),
|
|
28
|
+
sourceMapIds: unique(blocks.flatMap((block) => block.graph?.query?.sourceMapIds ?? [])),
|
|
29
|
+
sourceMapMappingIds: unique(blocks.flatMap((block) => block.graph?.query?.sourceMapMappingIds ?? [])),
|
|
30
|
+
conflictKeys: unique(blocks.flatMap((block) => block.graph?.query?.conflictKeys ?? [])),
|
|
31
|
+
summary: summary(blocks, records),
|
|
32
|
+
metadata: { authoredMachineGraphBlockIds: blocks.map((block) => block.id) }
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function summary(blocks, records) {
|
|
37
|
+
return {
|
|
38
|
+
graphCount: blocks.length,
|
|
39
|
+
recordCount: records.length,
|
|
40
|
+
labelCount: sum(blocks, 'labels'),
|
|
41
|
+
directiveCount: sum(blocks, 'directives'),
|
|
42
|
+
registerCount: sum(blocks, 'registers'),
|
|
43
|
+
flagCount: sum(blocks, 'flags'),
|
|
44
|
+
basicBlockCount: sum(blocks, 'basicBlocks'),
|
|
45
|
+
instructionCount: sum(blocks, 'instructions'),
|
|
46
|
+
operandCount: sum(blocks, 'operands'),
|
|
47
|
+
memoryEffectCount: sum(blocks, 'memoryEffects'),
|
|
48
|
+
controlEdgeCount: sum(blocks, 'controlEdges'),
|
|
49
|
+
branchCount: sum(blocks, 'branches'),
|
|
50
|
+
callCount: sum(blocks, 'calls'),
|
|
51
|
+
returnCount: sum(blocks, 'returns'),
|
|
52
|
+
interruptCount: sum(blocks, 'interrupts'),
|
|
53
|
+
proofObligationCount: sum(blocks, 'proofObligations'),
|
|
54
|
+
proofGapCount: sum(blocks, 'proofGaps'),
|
|
55
|
+
evidenceCount: sum(blocks, 'evidence'),
|
|
56
|
+
memoryEffectsWithoutProof: sum(blocks, 'memoryEffectsWithoutProof'),
|
|
57
|
+
controlEdgesWithoutProof: sum(blocks, 'controlEdgesWithoutProof'),
|
|
58
|
+
branchesWithoutProof: sum(blocks, 'branchesWithoutProof'),
|
|
59
|
+
callsWithoutProof: sum(blocks, 'callsWithoutProof'),
|
|
60
|
+
interruptsWithoutProof: sum(blocks, 'interruptsWithoutProof')
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function ids(records = []) { return records.map((record) => record?.id).filter(Boolean); }
|
|
65
|
+
function unique(values = []) { return [...new Set(values.filter(Boolean))]; }
|
|
66
|
+
function sum(blocks, key) { return blocks.reduce((total, block) => total + (block.summary?.[key] ?? 0), 0); }
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { createRowIdentityTracker } from './row-identity.js';
|
|
2
|
+
|
|
3
|
+
const GROUPS = {
|
|
4
|
+
label: 'labels',
|
|
5
|
+
directive: 'directives',
|
|
6
|
+
register: 'registers',
|
|
7
|
+
flag: 'flags',
|
|
8
|
+
basicBlock: 'basicBlocks',
|
|
9
|
+
instruction: 'instructions',
|
|
10
|
+
operand: 'operands',
|
|
11
|
+
memoryEffect: 'memoryEffects',
|
|
12
|
+
controlEdge: 'controlEdges',
|
|
13
|
+
branch: 'branches',
|
|
14
|
+
call: 'calls',
|
|
15
|
+
return: 'returns',
|
|
16
|
+
interrupt: 'interrupts',
|
|
17
|
+
proofObligation: 'proofObligations',
|
|
18
|
+
proofGap: 'proofGaps',
|
|
19
|
+
evidence: 'evidence'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function parseMachineGraphBlock(block) {
|
|
23
|
+
const name = nameFrom(block.header);
|
|
24
|
+
const rowIdentity = createRowIdentityTracker();
|
|
25
|
+
const graph = {
|
|
26
|
+
kind: 'frontier.lang.machineGraph',
|
|
27
|
+
version: 1,
|
|
28
|
+
id: idFrom(block.header, `machine_graph_${name}`),
|
|
29
|
+
architecture: readLine('architecture', block.body) ?? readLine('arch', block.body),
|
|
30
|
+
dialect: readLine('dialect', block.body),
|
|
31
|
+
sourceLanguage: readLine('sourceLanguage', block.body) ?? readLine('language', block.body),
|
|
32
|
+
sourcePath: readLine('sourcePath', block.body) ?? readLine('path', block.body),
|
|
33
|
+
sourceHash: readLine('sourceHash', block.body),
|
|
34
|
+
status: readLine('status', block.body) ?? 'partial',
|
|
35
|
+
evidenceIds: readListLine('evidence', block.body) ?? readListLine('evidenceIds', block.body) ?? [],
|
|
36
|
+
labels: [],
|
|
37
|
+
directives: [],
|
|
38
|
+
registers: [],
|
|
39
|
+
flags: [],
|
|
40
|
+
basicBlocks: [],
|
|
41
|
+
instructions: [],
|
|
42
|
+
operands: [],
|
|
43
|
+
memoryEffects: [],
|
|
44
|
+
controlEdges: [],
|
|
45
|
+
branches: [],
|
|
46
|
+
calls: [],
|
|
47
|
+
returns: [],
|
|
48
|
+
interrupts: [],
|
|
49
|
+
proofObligations: [],
|
|
50
|
+
proofGaps: [],
|
|
51
|
+
evidence: [],
|
|
52
|
+
parser: { status: 'authored', errors: rowIdentity.errors },
|
|
53
|
+
claims: {
|
|
54
|
+
autoMergeClaim: false,
|
|
55
|
+
semanticEquivalenceClaim: false,
|
|
56
|
+
binaryEquivalenceClaim: false,
|
|
57
|
+
timingEquivalenceClaim: false,
|
|
58
|
+
runtimeEquivalenceClaim: false
|
|
59
|
+
},
|
|
60
|
+
metadata: { name }
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
for (const authoredLine of readAuthoredLines(block)) {
|
|
64
|
+
const line = authoredLine.text;
|
|
65
|
+
if (!line || line.startsWith('#') || isGraphPropertyLine(line)) continue;
|
|
66
|
+
const match = /^([A-Za-z_$][\w$-]*)\s+([A-Za-z_$@./:*+-][\w$./@:*+-]*)(.*)$/.exec(line);
|
|
67
|
+
if (!match) continue;
|
|
68
|
+
const [, rowKind, rowName, rest] = match;
|
|
69
|
+
const normalized = normalizeMachineRowKind(rowKind);
|
|
70
|
+
const record = parseMachineRecord(normalized, rowName, rest, graph, authoredLine);
|
|
71
|
+
const group = GROUPS[normalized];
|
|
72
|
+
if (record && group) rowIdentity.push(graph[group], record, { rowKind, normalizedRowKind: normalized, name: rowName });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
graph.summary = summarizeMachineGraph(graph);
|
|
76
|
+
graph.status = deriveMachineGraphStatus(graph.status, graph.summary);
|
|
77
|
+
graph.query = {
|
|
78
|
+
labelIds: ids(graph.labels),
|
|
79
|
+
directiveIds: ids(graph.directives),
|
|
80
|
+
registerIds: ids(graph.registers),
|
|
81
|
+
flagIds: ids(graph.flags),
|
|
82
|
+
basicBlockIds: ids(graph.basicBlocks),
|
|
83
|
+
instructionIds: ids(graph.instructions),
|
|
84
|
+
operandIds: ids(graph.operands),
|
|
85
|
+
memoryEffectIds: ids(graph.memoryEffects),
|
|
86
|
+
controlEdgeIds: ids(graph.controlEdges),
|
|
87
|
+
branchIds: ids(graph.branches),
|
|
88
|
+
callIds: ids(graph.calls),
|
|
89
|
+
returnIds: ids(graph.returns),
|
|
90
|
+
interruptIds: ids(graph.interrupts),
|
|
91
|
+
controlFlowEdgeIds: ids([...graph.controlEdges, ...graph.branches, ...graph.calls, ...graph.returns, ...graph.interrupts]),
|
|
92
|
+
proofObligationIds: ids(graph.proofObligations),
|
|
93
|
+
proofGapCodes: unique(graph.proofGaps.map((record) => record.code)),
|
|
94
|
+
evidenceIds: unique([...graph.evidenceIds, ...ids(graph.evidence), ...allMachineRecords(graph).flatMap((record) => record.evidenceIds ?? [])]),
|
|
95
|
+
proofEvidenceIds: unique(allMachineRecords(graph).flatMap((record) => record.proofEvidenceIds ?? [])),
|
|
96
|
+
sourceMapIds: unique(allMachineRecords(graph).flatMap((record) => record.sourceMapIds ?? [])),
|
|
97
|
+
sourceMapMappingIds: unique(allMachineRecords(graph).flatMap((record) => record.sourceMapMappingIds ?? [])),
|
|
98
|
+
conflictKeys: unique(allMachineRecords(graph).map((record) => record.conflictKey)),
|
|
99
|
+
blockerReasonCodes: machineBlockerReasonCodes(graph)
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
id: graph.id,
|
|
104
|
+
graph,
|
|
105
|
+
records: allMachineRecords(graph),
|
|
106
|
+
summary: {
|
|
107
|
+
graphCount: 1,
|
|
108
|
+
...graph.summary
|
|
109
|
+
},
|
|
110
|
+
metadata: { name }
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function parseMachineRecord(kind, name, text, graph, authoredLine = {}) {
|
|
115
|
+
const common = commonRecord(kind, name, text, graph, authoredLine);
|
|
116
|
+
if (kind === 'label') return cleanRecord({ ...common, labelKind: word('kind', text) ?? 'label', address: word('address', text) ?? word('addr', text), symbol: word('symbol', text) ?? name, exported: flag('exported', text) });
|
|
117
|
+
if (kind === 'directive') return cleanRecord({ ...common, directiveKind: word('kind', text) ?? word('directiveKind', text) ?? name, value: quoted('value', text) ?? word('value', text), arguments: list(text, 'argument', 'arguments', 'arg', 'args') });
|
|
118
|
+
if (kind === 'register') return cleanRecord({ ...common, registerName: word('register', text) ?? word('registerName', text) ?? name, registerKind: word('kind', text) ?? word('registerKind', text), widthBits: number('widthBits', text) ?? number('width', text), bank: word('bank', text), aliases: list(text, 'alias', 'aliases'), role: word('role', text) });
|
|
119
|
+
if (kind === 'flag') return cleanRecord({ ...common, flagName: word('flag', text) ?? word('flagName', text) ?? name, flagKind: word('kind', text) ?? word('flagKind', text), bit: number('bit', text), registerId: word('register', text) ?? word('registerId', text) });
|
|
120
|
+
if (kind === 'basicBlock') return cleanRecord({ ...common, blockKind: word('kind', text) ?? word('blockKind', text), entryInstructionId: word('entryInstruction', text) ?? word('entryInstructionId', text), exitInstructionId: word('exitInstruction', text) ?? word('exitInstructionId', text), instructionIds: list(text, 'instruction', 'instructions', 'instructionId', 'instructionIds'), successorIds: list(text, 'successor', 'successors', 'successorId', 'successorIds'), predecessorIds: list(text, 'predecessor', 'predecessors', 'predecessorId', 'predecessorIds'), address: word('address', text) ?? word('addr', text), proofStatus: word('proofStatus', text) ?? word('status', text) });
|
|
121
|
+
if (kind === 'instruction') return cleanRecord({ ...common, mnemonic: word('mnemonic', text) ?? word('op', text) ?? name, opcode: word('opcode', text), instructionKind: word('kind', text) ?? word('instructionKind', text), operationKind: word('operation', text) ?? word('operationKind', text), address: word('address', text) ?? word('addr', text), addressMode: word('addressMode', text) ?? word('mode', text), sizeBytes: number('sizeBytes', text) ?? number('size', text), cycles: number('cycles', text), reads: list(text, 'read', 'reads'), writes: list(text, 'write', 'writes'), flagsRead: list(text, 'flagRead', 'flagsRead'), flagsWritten: list(text, 'flagWrite', 'flagsWritten'), registerIds: list(text, 'register', 'registers', 'registerId', 'registerIds'), memoryEffectIds: list(text, 'memoryEffect', 'memoryEffects', 'memoryEffectId', 'memoryEffectIds'), controlFlow: word('controlFlow', text), branchTarget: word('branchTarget', text), callTarget: word('callTarget', text), proofStatus: word('proofStatus', text) ?? word('status', text), semanticEquivalenceClaim: false, binaryEquivalenceClaim: false, timingEquivalenceClaim: false });
|
|
122
|
+
if (kind === 'operand') return cleanRecord({ ...common, instructionId: word('instruction', text) ?? word('instructionId', text), operandIndex: number('index', text) ?? number('operandIndex', text), operandKind: word('kind', text) ?? word('operandKind', text), value: quoted('value', text) ?? word('value', text), registerIds: list(text, 'register', 'registers', 'registerId', 'registerIds'), memoryReference: quoted('memoryReference', text) ?? word('memoryReference', text) ?? word('memory', text), address: word('address', text) ?? word('addr', text), addressMode: word('addressMode', text) ?? word('mode', text), immediate: word('immediate', text), widthBits: number('widthBits', text) ?? number('width', text) });
|
|
123
|
+
if (kind === 'memoryEffect') return cleanRecord({ ...common, instructionId: word('instruction', text) ?? word('instructionId', text), resourceId: word('resource', text) ?? word('resourceId', text), memoryKind: word('memoryKind', text), effectKind: word('effectKind', text) ?? word('kind', text) ?? name, address: word('address', text) ?? word('addr', text), addressSpace: word('addressSpace', text) ?? word('space', text), widthBits: number('widthBits', text) ?? number('width', text), memoryOrder: word('memoryOrder', text) ?? word('ordering', text), reads: list(text, 'read', 'reads'), writes: list(text, 'write', 'writes'), bank: word('bank', text), volatile: flag('volatile', text), atomic: flag('atomic', text), io: flag('io', text), proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing', semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
|
|
124
|
+
if (kind === 'controlEdge') return cleanRecord({ ...common, instructionId: word('instruction', text) ?? word('instructionId', text), fromInstructionId: word('fromInstruction', text) ?? word('fromInstructionId', text) ?? word('from', text), toInstructionId: word('toInstruction', text) ?? word('toInstructionId', text) ?? word('to', text), fromBlockId: word('fromBlock', text) ?? word('fromBlockId', text), toBlockId: word('toBlock', text) ?? word('toBlockId', text), targetId: word('target', text) ?? word('targetId', text), edgeKind: word('edgeKind', text) ?? word('kind', text) ?? name, condition: quoted('condition', text) ?? word('condition', text), flagIds: list(text, 'flag', 'flags', 'flagId', 'flagIds', 'conditionFlag', 'conditionFlags'), callTarget: word('callTarget', text), returnTarget: word('returnTarget', text), proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing', semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
|
|
125
|
+
if (kind === 'branch') return cleanRecord({ ...common, instructionId: word('instruction', text) ?? word('instructionId', text), fromInstructionId: word('fromInstruction', text) ?? word('fromInstructionId', text) ?? word('from', text), toInstructionId: word('toInstruction', text) ?? word('toInstructionId', text), targetId: word('target', text) ?? word('targetId', text) ?? word('to', text), branchKind: word('kind', text) ?? word('branchKind', text), condition: quoted('condition', text) ?? word('condition', text), flagIds: list(text, 'flag', 'flags', 'flagId', 'flagIds'), proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing', semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
|
|
126
|
+
if (kind === 'call') return cleanRecord({ ...common, instructionId: word('instruction', text) ?? word('instructionId', text), targetId: word('target', text) ?? word('targetId', text), callableId: word('callable', text) ?? word('callableId', text), callingConvention: word('callingConvention', text) ?? word('convention', text), stackEffect: word('stackEffect', text), proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing', semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
|
|
127
|
+
if (kind === 'return') return cleanRecord({ ...common, instructionId: word('instruction', text) ?? word('instructionId', text), fromCallableId: word('fromCallable', text) ?? word('fromCallableId', text) ?? word('from', text), stackEffect: word('stackEffect', text), proofStatus: word('proofStatus', text) ?? word('status', text) });
|
|
128
|
+
if (kind === 'interrupt') return cleanRecord({ ...common, vector: word('vector', text), handlerId: word('handler', text) ?? word('handlerId', text), interruptKind: word('kind', text) ?? word('interruptKind', text), proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing', semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
|
|
129
|
+
if (kind === 'proofObligation') return cleanRecord({ ...common, subjectId: word('subject', text) ?? word('subjectId', text), subjectKind: word('subjectKind', text), obligationKind: word('obligationKind', text) ?? word('kind', text) ?? name, status: word('status', text) ?? 'missing', statement: quoted('statement', text) ?? quoted('summary', text), evidenceIds: list(text, 'evidence', 'evidenceIds') ?? common.evidenceIds, missingEvidence: list(text, 'missingEvidence') ?? common.missingEvidence, semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
|
|
130
|
+
if (kind === 'proofGap') return cleanRecord({ ...common, code: word('code', text) ?? word('reasonCode', text) ?? name, status: word('status', text) ?? 'missing', summary: quoted('summary', text) ?? quoted('message', text), failClosed: common.failClosed ?? true, semanticEquivalenceClaim: false, binaryEquivalenceClaim: false, timingEquivalenceClaim: false, runtimeEquivalenceClaim: false });
|
|
131
|
+
if (kind === 'evidence') return cleanRecord({ ...common, evidenceKind: word('kind', text) ?? word('evidenceKind', text), status: word('status', text) ?? 'unknown', path: word('path', text), command: quoted('command', text) ?? word('command', text), sourceHash: word('sourceHash', text), traceHash: word('traceHash', text), binaryHash: word('binaryHash', text) });
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function commonRecord(kind, name, text, graph, authoredLine = {}) {
|
|
136
|
+
return cleanRecord({
|
|
137
|
+
recordKind: recordKind(kind),
|
|
138
|
+
id: idFrom(text, `${recordPrefix(kind)}_${name}`),
|
|
139
|
+
name,
|
|
140
|
+
sourcePath: word('sourcePath', text) ?? word('path', text) ?? graph.sourcePath,
|
|
141
|
+
sourceHash: word('sourceHash', text) ?? graph.sourceHash,
|
|
142
|
+
sourceSpan: authoredLine.sourceSpan,
|
|
143
|
+
authoredSourceSpan: authoredLine.sourceSpan,
|
|
144
|
+
evidenceIds: list(text, 'evidence', 'evidenceIds') ?? graph.evidenceIds,
|
|
145
|
+
proofEvidenceIds: list(text, 'proofEvidence', 'proofEvidenceId', 'proofEvidenceIds'),
|
|
146
|
+
proofObligationIds: list(text, 'proofObligation', 'proofObligations', 'proofObligationId', 'proofObligationIds', 'obligation', 'obligations'),
|
|
147
|
+
missingEvidence: list(text, 'missingEvidence'),
|
|
148
|
+
sourceMapIds: list(text, 'sourceMap', 'sourceMaps', 'sourceMapId', 'sourceMapIds'),
|
|
149
|
+
sourceMapMappingIds: list(text, 'sourceMapMapping', 'sourceMapMappings', 'sourceMapMappingId', 'sourceMapMappingIds'),
|
|
150
|
+
semanticNodeId: word('semanticNode', text) ?? word('semanticNodeId', text),
|
|
151
|
+
semanticSymbolId: word('semanticSymbol', text) ?? word('semanticSymbolId', text),
|
|
152
|
+
conflictKey: word('conflictKey', text),
|
|
153
|
+
reasonCode: word('reasonCode', text) ?? word('code', text),
|
|
154
|
+
failClosed: flag('failClosed', text),
|
|
155
|
+
metadata: { authoredName: name }
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function summarizeMachineGraph(graph) {
|
|
160
|
+
return {
|
|
161
|
+
records: allMachineRecords(graph).length,
|
|
162
|
+
labels: graph.labels.length,
|
|
163
|
+
directives: graph.directives.length,
|
|
164
|
+
registers: graph.registers.length,
|
|
165
|
+
flags: graph.flags.length,
|
|
166
|
+
basicBlocks: graph.basicBlocks.length,
|
|
167
|
+
instructions: graph.instructions.length,
|
|
168
|
+
operands: graph.operands.length,
|
|
169
|
+
memoryEffects: graph.memoryEffects.length,
|
|
170
|
+
controlEdges: graph.controlEdges.length,
|
|
171
|
+
branches: graph.branches.length,
|
|
172
|
+
calls: graph.calls.length,
|
|
173
|
+
returns: graph.returns.length,
|
|
174
|
+
interrupts: graph.interrupts.length,
|
|
175
|
+
proofObligations: graph.proofObligations.length,
|
|
176
|
+
proofGaps: graph.proofGaps.length,
|
|
177
|
+
evidence: graph.evidence.length,
|
|
178
|
+
memoryEffectsWithoutProof: graph.memoryEffects.filter((record) => record.proofStatus !== 'passed').length,
|
|
179
|
+
controlEdgesWithoutProof: graph.controlEdges.filter((record) => record.proofStatus !== 'passed').length,
|
|
180
|
+
branchesWithoutProof: graph.branches.filter((record) => record.proofStatus !== 'passed').length,
|
|
181
|
+
callsWithoutProof: graph.calls.filter((record) => record.proofStatus !== 'passed').length,
|
|
182
|
+
interruptsWithoutProof: graph.interrupts.filter((record) => record.proofStatus !== 'passed').length,
|
|
183
|
+
parseErrors: graph.parser?.errors?.length ?? 0,
|
|
184
|
+
reasonCodes: unique([...unprovedMachineRecords(graph), ...graph.proofGaps].map((record) => record.reasonCode ?? record.code))
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function deriveMachineGraphStatus(authoredStatus, summary) {
|
|
189
|
+
if (
|
|
190
|
+
summary.proofGaps > 0 ||
|
|
191
|
+
summary.memoryEffectsWithoutProof > 0 ||
|
|
192
|
+
summary.controlEdgesWithoutProof > 0 ||
|
|
193
|
+
summary.branchesWithoutProof > 0 ||
|
|
194
|
+
summary.callsWithoutProof > 0 ||
|
|
195
|
+
summary.interruptsWithoutProof > 0
|
|
196
|
+
) return 'blocked';
|
|
197
|
+
return authoredStatus ?? 'partial';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function machineBlockerReasonCodes(graph) {
|
|
201
|
+
return unique([...unprovedMachineRecords(graph), ...graph.proofGaps].map((record) => record.reasonCode ?? record.code));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function unprovedMachineRecords(graph) {
|
|
205
|
+
return [
|
|
206
|
+
...graph.memoryEffects,
|
|
207
|
+
...graph.controlEdges,
|
|
208
|
+
...graph.branches,
|
|
209
|
+
...graph.calls,
|
|
210
|
+
...graph.interrupts
|
|
211
|
+
].filter((record) => record.proofStatus !== 'passed');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function allMachineRecords(graph) {
|
|
215
|
+
return [
|
|
216
|
+
...graph.labels,
|
|
217
|
+
...graph.directives,
|
|
218
|
+
...graph.registers,
|
|
219
|
+
...graph.flags,
|
|
220
|
+
...graph.basicBlocks,
|
|
221
|
+
...graph.instructions,
|
|
222
|
+
...graph.operands,
|
|
223
|
+
...graph.memoryEffects,
|
|
224
|
+
...graph.controlEdges,
|
|
225
|
+
...graph.branches,
|
|
226
|
+
...graph.calls,
|
|
227
|
+
...graph.returns,
|
|
228
|
+
...graph.interrupts,
|
|
229
|
+
...graph.proofObligations,
|
|
230
|
+
...graph.proofGaps,
|
|
231
|
+
...graph.evidence
|
|
232
|
+
];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function normalizeMachineRowKind(kind) {
|
|
236
|
+
if (kind === 'reg') return 'register';
|
|
237
|
+
if (kind === 'block') return 'basicBlock';
|
|
238
|
+
if (kind === 'inst' || kind === 'instr' || kind === 'op' || kind === 'opcode') return 'instruction';
|
|
239
|
+
if (kind === 'arg') return 'operand';
|
|
240
|
+
if (kind === 'mem' || kind === 'memory' || kind === 'memoryAccess' || kind === 'effect' || kind === 'load' || kind === 'store' || kind === 'atomic' || kind === 'fence' || kind === 'memoryEffect') return 'memoryEffect';
|
|
241
|
+
if (kind === 'edge') return 'controlEdge';
|
|
242
|
+
if (kind === 'ret') return 'return';
|
|
243
|
+
if (kind === 'irq' || kind === 'exception') return 'interrupt';
|
|
244
|
+
if (kind === 'proof' || kind === 'obligation') return 'proofObligation';
|
|
245
|
+
if (kind === 'gap' || kind === 'proofGap') return 'proofGap';
|
|
246
|
+
if (kind === 'proofEvidence') return 'evidence';
|
|
247
|
+
return kind;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function recordKind(kind) {
|
|
251
|
+
if (kind === 'memoryEffect') return 'memory-effect';
|
|
252
|
+
if (kind === 'proofGap') return 'proof-gap';
|
|
253
|
+
return kind;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function recordPrefix(kind) {
|
|
257
|
+
return recordKind(kind).replace(/-/g, '_');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function isGraphPropertyLine(line) {
|
|
261
|
+
const property = /^(architecture|arch|dialect|sourceLanguage|language|sourcePath|path|sourceHash|status|evidence|evidenceIds)\s+/.exec(line)?.[1];
|
|
262
|
+
if (!property) return false;
|
|
263
|
+
if ((property === 'evidence' || property === 'evidenceIds') && /@id\(/.test(line)) return false;
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function idFrom(text, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(text)?.[1] ?? fallback; }
|
|
268
|
+
function nameFrom(header) { return /^([A-Za-z_$][\w$]*)/.exec(header)?.[1] ?? 'MachineGraph'; }
|
|
269
|
+
function readLine(label, body) { return new RegExp('^\\s*' + label + '\\s+([^\\n]+)', 'm').exec(body)?.[1]?.trim(); }
|
|
270
|
+
function readListLine(label, body) {
|
|
271
|
+
const line = readLine(label, body);
|
|
272
|
+
return line ? line.split(/[|,]/).map((item) => item.trim()).filter(Boolean) : undefined;
|
|
273
|
+
}
|
|
274
|
+
function word(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(text)?.[1]?.trim(); }
|
|
275
|
+
function quoted(label, text) { return new RegExp("(?:^|\\s)" + label + "\\s+[\"']([^\"']+)[\"']").exec(text)?.[1]?.trim(); }
|
|
276
|
+
function flag(label, text) { return new RegExp('(?:^|\\s)' + label + '(?:\\s|$)').test(text) || undefined; }
|
|
277
|
+
function number(label, text) {
|
|
278
|
+
const value = word(label, text);
|
|
279
|
+
return value === undefined ? undefined : Number(value);
|
|
280
|
+
}
|
|
281
|
+
function list(text, ...labels) {
|
|
282
|
+
for (const label of labels) {
|
|
283
|
+
const value = new RegExp('(?:^|\\s)' + label + '\\s+([^\\s]+)').exec(text)?.[1]?.trim();
|
|
284
|
+
if (value) return value.split(/[|,]/).map((item) => item.trim()).filter(Boolean);
|
|
285
|
+
}
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
function ids(records = []) { return records.map((record) => record?.id).filter(Boolean); }
|
|
289
|
+
function unique(values = []) { return [...new Set(values.filter(Boolean))]; }
|
|
290
|
+
function readAuthoredLines(block) {
|
|
291
|
+
const lines = block.body.split('\n');
|
|
292
|
+
const records = [];
|
|
293
|
+
let lineStart = block.syntax?.bodyStartOffset ?? 0;
|
|
294
|
+
for (const rawLine of lines) {
|
|
295
|
+
const rawEnd = lineStart + rawLine.length;
|
|
296
|
+
const leading = /^\s*/.exec(rawLine)?.[0].length ?? 0;
|
|
297
|
+
const trailing = /\s*$/.exec(rawLine)?.[0].length ?? 0;
|
|
298
|
+
const startOffset = lineStart + leading;
|
|
299
|
+
const endOffset = Math.max(startOffset, rawEnd - trailing);
|
|
300
|
+
records.push({ text: rawLine.trim(), sourceSpan: typeof block.sourceSpan === 'function' ? block.sourceSpan(startOffset, endOffset) : undefined });
|
|
301
|
+
lineStart = rawEnd + 1;
|
|
302
|
+
}
|
|
303
|
+
return records;
|
|
304
|
+
}
|
|
305
|
+
function cleanRecord(record) {
|
|
306
|
+
return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0)));
|
|
307
|
+
}
|
package/dist/metadata.js
CHANGED
|
@@ -5,7 +5,7 @@ import { mergeTargetProjectionTargets } from './target-projection-aggregate.js';
|
|
|
5
5
|
import { mergeConversionBlocks } from './conversion-metadata.js';
|
|
6
6
|
import { mergeSemanticEditBlocks } from './semantic-edit-metadata.js';
|
|
7
7
|
import { mergeGateAdmissionEvidenceBlocks } from './gate-admission-evidence.js';
|
|
8
|
-
|
|
8
|
+
import { mergeMachineGraphBlocks } from './machine-graph-metadata.js';
|
|
9
9
|
const PROOF_GROUPS = ['contracts', 'refinements', 'invariants', 'termination', 'temporal', 'obligations', 'artifacts', 'assumptions'];
|
|
10
10
|
const PARADIGM_GROUPS = [
|
|
11
11
|
'bindingScopes', 'bindings', 'patterns', 'typeConstraints', 'evaluationModels', 'memoryLocations', 'effectRegions',
|
|
@@ -13,7 +13,7 @@ const PARADIGM_GROUPS = [
|
|
|
13
13
|
'clockModels', 'objectModels', 'macroExpansions', 'reflectionBoundaries', 'loweringRecords'
|
|
14
14
|
];
|
|
15
15
|
|
|
16
|
-
export function createParsedMetadata({ proofBlocks = [], paradigmBlocks = [], operationBlocks = [], semanticEditBlocks = [], conversionBlocks = [], constraintSpaceBlocks = [], decisionGraphBlocks = [], gateAdmissionEvidenceBlocks = [], dialectRegistryBlocks = [], interlinguaBlocks = [], resourceGraphBlocks = [], nativeSourceBlocks = [], packageManifestBlocks = [], canvasSurfaceBlocks = [], applicationSurfaceBlocks = [], runtimeCapabilityBlocks = [], targetProjectionTargets = [] } = {}) {
|
|
16
|
+
export function createParsedMetadata({ proofBlocks = [], paradigmBlocks = [], operationBlocks = [], semanticEditBlocks = [], conversionBlocks = [], constraintSpaceBlocks = [], decisionGraphBlocks = [], gateAdmissionEvidenceBlocks = [], dialectRegistryBlocks = [], interlinguaBlocks = [], resourceGraphBlocks = [], machineGraphBlocks = [], nativeSourceBlocks = [], packageManifestBlocks = [], canvasSurfaceBlocks = [], applicationSurfaceBlocks = [], runtimeCapabilityBlocks = [], targetProjectionTargets = [] } = {}) {
|
|
17
17
|
const metadata = {};
|
|
18
18
|
if (proofBlocks.length) metadata.proof = mergeProofBlocks(proofBlocks);
|
|
19
19
|
if (paradigmBlocks.length) metadata.paradigmSemantics = mergeParadigmBlocks(paradigmBlocks);
|
|
@@ -26,6 +26,7 @@ export function createParsedMetadata({ proofBlocks = [], paradigmBlocks = [], op
|
|
|
26
26
|
if (dialectRegistryBlocks.length) metadata.dialects = mergeDialectRegistryBlocks(dialectRegistryBlocks);
|
|
27
27
|
if (interlinguaBlocks.length) metadata.universalInterlingua = mergeInterlinguaBlocks(interlinguaBlocks);
|
|
28
28
|
if (resourceGraphBlocks.length) metadata.semanticResourceGraphs = mergeResourceGraphBlocks(resourceGraphBlocks);
|
|
29
|
+
if (machineGraphBlocks.length) metadata.machineGraphs = mergeMachineGraphBlocks(machineGraphBlocks);
|
|
29
30
|
if (packageManifestBlocks.length) metadata.packageManifests = mergePackageManifestBlocks(packageManifestBlocks);
|
|
30
31
|
if (canvasSurfaceBlocks.length) metadata.canvasSurfaces = mergeCanvasSurfaceBlocks(canvasSurfaceBlocks);
|
|
31
32
|
if (applicationSurfaceBlocks.length) metadata.applicationSurfaces = mergeApplicationSurfaceBlocks(applicationSurfaceBlocks);
|
package/dist/resource-graph.js
CHANGED
|
@@ -86,6 +86,7 @@ export function parseResourceGraphBlock(block) {
|
|
|
86
86
|
graph.outlives = graph.lifetimeRelations;
|
|
87
87
|
graph.borrowScopeRegions = graph.borrowScopes;
|
|
88
88
|
graph.summary = summarize(graph);
|
|
89
|
+
graph.status = deriveGraphStatus(graph.status, graph.summary);
|
|
89
90
|
graph.query = {
|
|
90
91
|
resourceIds: ids(graph.resources),
|
|
91
92
|
ownerIds: ids(graph.owners),
|
|
@@ -97,7 +98,7 @@ export function parseResourceGraphBlock(block) {
|
|
|
97
98
|
lowLevelPrimitiveIds: ids([...graph.memoryRegions, ...graph.dataLayouts, ...graph.pointerEdges, ...graph.memoryAccesses, ...graph.abiBoundaries, ...graph.synchronizationEdges, ...graph.traps, ...graph.undefinedBehaviors]),
|
|
98
99
|
sourcePaths: unique(allRecords(graph).map((record) => record.sourcePath)),
|
|
99
100
|
evidenceIds: unique([...graph.evidenceIds, ...allRecords(graph).flatMap((record) => record.evidenceIds ?? [])]),
|
|
100
|
-
blockerReasonCodes:
|
|
101
|
+
blockerReasonCodes: blockerReasonCodes(graph)
|
|
101
102
|
};
|
|
102
103
|
|
|
103
104
|
return {
|
|
@@ -187,6 +188,22 @@ function summarize(graph) {
|
|
|
187
188
|
};
|
|
188
189
|
}
|
|
189
190
|
|
|
191
|
+
function deriveGraphStatus(authoredStatus, summary) {
|
|
192
|
+
if (
|
|
193
|
+
summary.conflicts > 0 ||
|
|
194
|
+
summary.unsafeBoundariesWithoutProof > 0 ||
|
|
195
|
+
summary.synchronizationEdgesWithoutProof > 0 ||
|
|
196
|
+
summary.trapsWithoutProof > 0 ||
|
|
197
|
+
summary.undefinedBehaviorsWithoutProof > 0
|
|
198
|
+
) return 'blocked';
|
|
199
|
+
return authoredStatus ?? 'partial';
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function blockerReasonCodes(graph) {
|
|
203
|
+
const unprovedSynchronizationEdges = graph.synchronizationEdges.filter((record) => record.proofStatus !== 'passed');
|
|
204
|
+
return unique([...graph.conflicts, ...unprovedSynchronizationEdges, ...graph.traps, ...graph.undefinedBehaviors].map((record) => record.reasonCode));
|
|
205
|
+
}
|
|
206
|
+
|
|
190
207
|
function allRecords(graph) {
|
|
191
208
|
return [
|
|
192
209
|
...graph.resources,
|
|
@@ -227,9 +227,9 @@ function readGenericRowSyntaxChildren(source, block, options, config) {
|
|
|
227
227
|
for (const line of readBodyLines(source, block)) {
|
|
228
228
|
if (!line.text || line.text.startsWith('#')) continue;
|
|
229
229
|
const row = rowPattern.exec(line.text);
|
|
230
|
-
if (!row) { if (config
|
|
230
|
+
if (!row) { if (unknownGenericRowsFailClosed(config)) children.push(genericUnknownRowChild(source, block, options, line, config, undefined, undefined, unsupportedGenericRowReason(config))); continue; }
|
|
231
231
|
const [, rowKind, name, rest] = row;
|
|
232
|
-
if (!config.rowKinds.has(rowKind)) { if (config
|
|
232
|
+
if (!config.rowKinds.has(rowKind)) { if (unknownGenericRowsFailClosed(config)) children.push(genericUnknownRowChild(source, block, options, line, config, rowKind, name, unsupportedGenericRowReason(config))); continue; }
|
|
233
233
|
const normalizedRowKind = config.normalize?.(rowKind) ?? rowKind;
|
|
234
234
|
const id = idFrom(rest, `${config.idPrefix}_${safeId(normalizedRowKind)}_${safeId(name)}`);
|
|
235
235
|
let recognized = true;
|
|
@@ -268,13 +268,16 @@ function genericUnknownRowChild(source, block, options, line, config, rowKind, n
|
|
|
268
268
|
const resolvedName = name ?? rowKind ?? 'unknown';
|
|
269
269
|
return cleanRecord({
|
|
270
270
|
kind: config.childKind === 'gateAdmissionEvidenceRow' ? 'gateAdmissionUnknownRow' : 'genericUnknownRow', rowKind,
|
|
271
|
-
normalizedRowKind: 'unknown', name: resolvedName, id:
|
|
271
|
+
normalizedRowKind: 'unknown', name: resolvedName, id: `${config.idPrefix}_unknown_${safeId(rowKind ?? 'row')}_${line.startOffset}`,
|
|
272
272
|
header: line.text, startOffset: line.startOffset, endOffset: line.endOffset, location: sourcePosition(source, line.startOffset),
|
|
273
273
|
parentKind: block.kind, parentId: block.id, parentName: block.name, moduleId: block.moduleId, moduleName: block.moduleName,
|
|
274
274
|
sourceSpan: sourceSpan(source, block, line.startOffset, line.endOffset, options), recognized: false, reason
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
function unknownGenericRowsFailClosed(config) { return config.childKind === 'gateAdmissionEvidenceRow' || config.childKind === 'machineGraphRow'; }
|
|
279
|
+
function unsupportedGenericRowReason(config) { return config.childKind === 'machineGraphRow' ? 'unsupported-machine-graph-row' : 'unsupported-gate-admission-row'; }
|
|
280
|
+
|
|
278
281
|
function readBodyLines(source, block) { return readTextLines(source, block.bodyStartOffset, block.bodyEndOffset); }
|
|
279
282
|
|
|
280
283
|
function readTextLines(source, startOffset, endOffset) {
|
|
@@ -294,10 +297,7 @@ function readTextLines(source, startOffset, endOffset) {
|
|
|
294
297
|
return records;
|
|
295
298
|
}
|
|
296
299
|
|
|
297
|
-
function sourcePosition(source, offset) {
|
|
298
|
-
const lines = source.slice(0, offset).split('\n');
|
|
299
|
-
return { line: lines.length, column: lines[lines.length - 1].length + 1, offset };
|
|
300
|
-
}
|
|
300
|
+
function sourcePosition(source, offset) { const lines = source.slice(0, offset).split('\n'); return { line: lines.length, column: lines[lines.length - 1].length + 1, offset }; }
|
|
301
301
|
|
|
302
302
|
function sourceSpan(source, block, startOffset, endOffset, options = {}) {
|
|
303
303
|
return cleanRecord({
|
|
@@ -315,6 +315,4 @@ function sourceSpan(source, block, startOffset, endOffset, options = {}) {
|
|
|
315
315
|
function idFrom(header, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(header)?.[1] ?? fallback; }
|
|
316
316
|
function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(text)?.[1]?.trim(); }
|
|
317
317
|
function safeId(value) { return String(value).replace(/[^A-Za-z0-9_$-]+/g, '_').replace(/^_+|_+$/g, '') || 'row'; }
|
|
318
|
-
function cleanRecord(record) {
|
|
319
|
-
return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0)));
|
|
320
|
-
}
|
|
318
|
+
function cleanRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0))); }
|
|
@@ -3,6 +3,7 @@ const canvasRows = words('element command state stateWrite trace gap proofGap ev
|
|
|
3
3
|
const constraintRows = words('variable var constraint hard soft preference prefer collapse admission');
|
|
4
4
|
const dialectRows = words('dialect record extern');
|
|
5
5
|
const interlinguaRows = words('layer constraint edge obligation proofObligation proof lowering lower source sourceLift lift evidence');
|
|
6
|
+
const machineRows = words('label directive register reg flag conditionFlag basicBlock block instruction inst instr op opcode operand arg memoryEffect memoryAccess load store atomic fence memory mem effect controlEdge edge branch call return ret interrupt irq exception proof proofObligation obligation gap proofGap evidence proofEvidence');
|
|
6
7
|
const packageRows = words('metadata dependency script export gap proofGap evidence proofEvidence');
|
|
7
8
|
const runtimeRows = words('host runtimeHost hostProfile sourceHost targetHost capability hostCapability hostBinding binding requirement runtimeRequirement requiredRuntime evidence proofEvidence gap proofGap');
|
|
8
9
|
const semanticEditRows = words('script semanticEditScript projection semanticEditProjection replay semanticEditReplay');
|
|
@@ -18,6 +19,9 @@ export const ROW_SYNTAX_CONFIG = Object.freeze({
|
|
|
18
19
|
runtimeHosts: rowConfig('runtimeCapabilityRow', 'runtime_capability_row', runtimeRows, normalizeRuntimeCapabilityRow),
|
|
19
20
|
resourceGraph: rowConfig('resourceGraphRow', 'resource_graph_row', words('resource owner loan alias move drop escape lifetime lifetimeRegion life outlives lifetimeRelation lifeRelation borrow borrowScope borrowRegion unsafe unsafeBoundary memory memoryRegion region layout dataLayout pointer ptr address access memoryAccess atomic volatile abi abiBoundary callBoundary sync synchronization synchronisation synchronizationEdge synchronisationEdge happensBefore hb fence fenceEdge barrier barrierEdge trap traps undefined undefinedBehavior undefinedBehaviour ub conflict proof proofObligation obligation'), normalizeResourceGraphRow),
|
|
20
21
|
semanticResourceGraph: rowConfig('resourceGraphRow', 'resource_graph_row', words('resource owner loan alias move drop escape lifetime lifetimeRegion life outlives lifetimeRelation lifeRelation borrow borrowScope borrowRegion unsafe unsafeBoundary memory memoryRegion region layout dataLayout pointer ptr address access memoryAccess atomic volatile abi abiBoundary callBoundary sync synchronization synchronisation synchronizationEdge synchronisationEdge happensBefore hb fence fenceEdge barrier barrierEdge trap traps undefined undefinedBehavior undefinedBehaviour ub conflict proof proofObligation obligation'), normalizeResourceGraphRow),
|
|
22
|
+
machineGraph: rowConfig('machineGraphRow', 'machine_graph_row', machineRows, normalizeMachineGraphRow),
|
|
23
|
+
executionGraph: rowConfig('machineGraphRow', 'machine_graph_row', machineRows, normalizeMachineGraphRow),
|
|
24
|
+
lowLevelGraph: rowConfig('machineGraphRow', 'machine_graph_row', machineRows, normalizeMachineGraphRow),
|
|
21
25
|
applicationSurface: rowConfig('applicationSurfaceRow', 'application_surface_row', appRows, normalizeApplicationSurfaceRow),
|
|
22
26
|
appHost: rowConfig('applicationSurfaceRow', 'application_surface_row', appRows, normalizeApplicationSurfaceRow),
|
|
23
27
|
plugin: rowConfig('applicationSurfaceRow', 'application_surface_row', appRows, normalizeApplicationSurfaceRow),
|
|
@@ -91,6 +95,22 @@ function normalizeResourceGraphRow(rowKind) {
|
|
|
91
95
|
return rowKind;
|
|
92
96
|
}
|
|
93
97
|
|
|
98
|
+
function normalizeMachineGraphRow(rowKind) {
|
|
99
|
+
if (rowKind === 'reg') return 'register';
|
|
100
|
+
if (rowKind === 'conditionFlag') return 'flag';
|
|
101
|
+
if (rowKind === 'block') return 'basicBlock';
|
|
102
|
+
if (rowKind === 'inst' || rowKind === 'instr' || rowKind === 'op' || rowKind === 'opcode') return 'instruction';
|
|
103
|
+
if (rowKind === 'arg') return 'operand';
|
|
104
|
+
if (rowKind === 'memory' || rowKind === 'mem' || rowKind === 'memoryAccess' || rowKind === 'effect' || rowKind === 'load' || rowKind === 'store' || rowKind === 'atomic' || rowKind === 'fence') return 'memoryEffect';
|
|
105
|
+
if (rowKind === 'edge') return 'controlEdge';
|
|
106
|
+
if (rowKind === 'ret') return 'return';
|
|
107
|
+
if (rowKind === 'irq' || rowKind === 'exception') return 'interrupt';
|
|
108
|
+
if (rowKind === 'proof' || rowKind === 'obligation') return 'proofObligation';
|
|
109
|
+
if (rowKind === 'gap') return 'proofGap';
|
|
110
|
+
if (rowKind === 'proofEvidence') return 'evidence';
|
|
111
|
+
return rowKind;
|
|
112
|
+
}
|
|
113
|
+
|
|
94
114
|
function normalizeApplicationSurfaceRow(rowKind) {
|
|
95
115
|
if (rowKind === 'provide' || rowKind === 'provides') return 'provided-surface';
|
|
96
116
|
if (rowKind === 'required' || rowKind === 'requires' || rowKind === 'require') return 'required-capability';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshift-labs/frontier-lang-parser",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.76",
|
|
4
4
|
"description": "Parser for the first Frontier Lang .frontier syntax slice.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "node scripts/build.mjs",
|
|
25
|
-
"test": "npm run build && node test/smoke.mjs && node test/member-identity-smoke.mjs && node test/generic-row-parse-identity-smoke.mjs && node test/type-variant-payload-smoke.mjs && node test/type-generic-ref-smoke.mjs && node test/type-parameter-constraints-smoke.mjs && node test/type-structural-expression-smoke.mjs && node test/action-body-smoke.mjs && node test/action-structured-literals-smoke.mjs && node test/action-return-smoke.mjs && node test/action-else-smoke.mjs && node test/action-match-smoke.mjs && node test/action-for-in-smoke.mjs && node test/action-repeat-smoke.mjs && node test/action-call-smoke.mjs && node test/semantic-operation-edit-smoke.mjs && node test/target-projection-aggregate-smoke.mjs && node test/conversion-constraint-fields-smoke.mjs && node test/conversion-evidence-smoke.mjs && node test/gate-admission-evidence-smoke.mjs && node test/package-canvas-surface-smoke.mjs && node test/view-render-graph-smoke.mjs && node test/resource-graph-smoke.mjs && node test/interlingua-smoke.mjs && node test/dialect-registry-smoke.mjs",
|
|
25
|
+
"test": "npm run build && node test/smoke.mjs && node test/member-identity-smoke.mjs && node test/generic-row-parse-identity-smoke.mjs && node test/type-variant-payload-smoke.mjs && node test/type-generic-ref-smoke.mjs && node test/type-parameter-constraints-smoke.mjs && node test/type-structural-expression-smoke.mjs && node test/action-body-smoke.mjs && node test/action-structured-literals-smoke.mjs && node test/action-return-smoke.mjs && node test/action-else-smoke.mjs && node test/action-match-smoke.mjs && node test/action-for-in-smoke.mjs && node test/action-repeat-smoke.mjs && node test/action-call-smoke.mjs && node test/semantic-operation-edit-smoke.mjs && node test/target-projection-aggregate-smoke.mjs && node test/conversion-constraint-fields-smoke.mjs && node test/conversion-evidence-smoke.mjs && node test/gate-admission-evidence-smoke.mjs && node test/package-canvas-surface-smoke.mjs && node test/view-render-graph-smoke.mjs && node test/resource-graph-smoke.mjs && node test/machine-graph-smoke.mjs && node test/interlingua-smoke.mjs && node test/dialect-registry-smoke.mjs",
|
|
26
26
|
"typecheck": "node ./node_modules/typescript/bin/tsc --noEmit -p test/tsconfig.json",
|
|
27
27
|
"fuzz": "npm run build && node fuzz/smoke.mjs",
|
|
28
28
|
"bench": "npm run build && node bench/smoke.mjs",
|