@naiv/swan-dsl 0.0.1
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/src/index.d.ts +25 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +48 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lexer.d.ts +6 -0
- package/dist/src/lexer.d.ts.map +1 -0
- package/dist/src/lexer.js +68 -0
- package/dist/src/lexer.js.map +1 -0
- package/dist/src/parser.d.ts +57 -0
- package/dist/src/parser.d.ts.map +1 -0
- package/dist/src/parser.js +466 -0
- package/dist/src/parser.js.map +1 -0
- package/dist/src/semantic.d.ts +7 -0
- package/dist/src/semantic.d.ts.map +1 -0
- package/dist/src/semantic.js +269 -0
- package/dist/src/semantic.js.map +1 -0
- package/dist/src/types.d.ts +160 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +31 -0
- package/dist/src/types.js.map +1 -0
- package/dist/test.d.ts +2 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +47 -0
- package/dist/test.js.map +1 -0
- package/package.json +28 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
// SWAN DSL — Semantic Checker
|
|
4
|
+
// Enforces static semantic rules SR-1 through SR-6.
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.checkSemantics = checkSemantics;
|
|
8
|
+
const types_1 = require("./types");
|
|
9
|
+
function checkSemantics(program, options = {}) {
|
|
10
|
+
const checker = new SemanticChecker(program, options);
|
|
11
|
+
checker.check();
|
|
12
|
+
}
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Internal checker class
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
class SemanticChecker {
|
|
17
|
+
program;
|
|
18
|
+
options;
|
|
19
|
+
pageNames;
|
|
20
|
+
componentNames;
|
|
21
|
+
constructor(program, options) {
|
|
22
|
+
this.program = program;
|
|
23
|
+
this.options = options;
|
|
24
|
+
this.pageNames = new Set(program.pages.map((p) => p.name));
|
|
25
|
+
this.componentNames = new Set(program.components.map((c) => c.name));
|
|
26
|
+
}
|
|
27
|
+
check() {
|
|
28
|
+
this.checkSR1andSR2();
|
|
29
|
+
this.checkSR6Names();
|
|
30
|
+
this.collectAndCheckNavTargets();
|
|
31
|
+
this.checkSR5ComponentCycles();
|
|
32
|
+
if (this.options.strictMode) {
|
|
33
|
+
this.checkSR4Reachability();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// ─── SR-1 & SR-2 ──────────────────────────────────────────────────────────
|
|
37
|
+
// SR-1: app defines exactly one entry point (guaranteed by grammar)
|
|
38
|
+
// SR-2: entry must reference a page
|
|
39
|
+
checkSR1andSR2() {
|
|
40
|
+
const { app } = this.program;
|
|
41
|
+
// SR-1: grammar forces exactly one entry, but verify it's non-empty
|
|
42
|
+
if (!app.entry || app.entry.trim() === "") {
|
|
43
|
+
throw new types_1.SemanticError("SR-1", "app must define an entry page", app.pos);
|
|
44
|
+
}
|
|
45
|
+
// SR-2: entry must be a page
|
|
46
|
+
if (!this.pageNames.has(app.entry)) {
|
|
47
|
+
const hint = this.componentNames.has(app.entry)
|
|
48
|
+
? ` ("${app.entry}" is a component, not a page)`
|
|
49
|
+
: ` ("${app.entry}" is not defined)`;
|
|
50
|
+
throw new types_1.SemanticError("SR-2", `entry "${app.entry}" must reference a page${hint}`, app.pos);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// ─── SR-6 ─────────────────────────────────────────────────────────────────
|
|
54
|
+
// Identifiers must be unique within each namespace.
|
|
55
|
+
checkSR6Names() {
|
|
56
|
+
// Pages namespace
|
|
57
|
+
const pagesSeen = new Set();
|
|
58
|
+
for (const page of this.program.pages) {
|
|
59
|
+
if (pagesSeen.has(page.name)) {
|
|
60
|
+
throw new types_1.SemanticError("SR-6", `Duplicate page name "${page.name}"`, page.pos);
|
|
61
|
+
}
|
|
62
|
+
pagesSeen.add(page.name);
|
|
63
|
+
}
|
|
64
|
+
// Components namespace
|
|
65
|
+
const componentsSeen = new Set();
|
|
66
|
+
for (const comp of this.program.components) {
|
|
67
|
+
if (componentsSeen.has(comp.name)) {
|
|
68
|
+
throw new types_1.SemanticError("SR-6", `Duplicate component name "${comp.name}"`, comp.pos);
|
|
69
|
+
}
|
|
70
|
+
componentsSeen.add(comp.name);
|
|
71
|
+
}
|
|
72
|
+
// Actions namespace: action names must be unique per page/component scope
|
|
73
|
+
// (we collect across the whole program for simplicity)
|
|
74
|
+
for (const page of this.program.pages) {
|
|
75
|
+
this.checkActionUniqueness(page.name, page.body);
|
|
76
|
+
}
|
|
77
|
+
for (const comp of this.program.components) {
|
|
78
|
+
this.checkActionUniqueness(comp.name, comp.body);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
collectActions(stmts) {
|
|
82
|
+
const actions = new Map();
|
|
83
|
+
for (const stmt of stmts) {
|
|
84
|
+
if (stmt.kind === "SubmitStmt" || stmt.kind === "ClickStmt") {
|
|
85
|
+
actions.set(stmt.action, (actions.get(stmt.action) ?? 0) + 1);
|
|
86
|
+
}
|
|
87
|
+
if (stmt.kind === "ConditionalStmt") {
|
|
88
|
+
for (const [k, v] of this.collectActions(stmt.body)) {
|
|
89
|
+
actions.set(k, (actions.get(k) ?? 0) + v);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return actions;
|
|
94
|
+
}
|
|
95
|
+
checkActionUniqueness(scopeName, stmts) {
|
|
96
|
+
const counts = this.collectActions(stmts);
|
|
97
|
+
for (const [action, count] of counts) {
|
|
98
|
+
if (count > 1) {
|
|
99
|
+
throw new types_1.SemanticError("SR-6", `Duplicate action "${action}" in scope "${scopeName}"`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// ─── SR-3 ─────────────────────────────────────────────────────────────────
|
|
104
|
+
// All navigation targets must be pages.
|
|
105
|
+
collectAndCheckNavTargets() {
|
|
106
|
+
for (const page of this.program.pages) {
|
|
107
|
+
this.checkNavInStatements(page.body);
|
|
108
|
+
}
|
|
109
|
+
for (const comp of this.program.components) {
|
|
110
|
+
this.checkNavInStatements(comp.body);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
checkNavInStatements(stmts) {
|
|
114
|
+
for (const stmt of stmts) {
|
|
115
|
+
this.checkNavInStatement(stmt);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
checkNavInStatement(stmt) {
|
|
119
|
+
switch (stmt.kind) {
|
|
120
|
+
case "ButtonStmt":
|
|
121
|
+
case "LinkStmt":
|
|
122
|
+
this.validateNavTarget(stmt.nav);
|
|
123
|
+
break;
|
|
124
|
+
case "HandlerStmt":
|
|
125
|
+
this.checkHandlerNav(stmt);
|
|
126
|
+
break;
|
|
127
|
+
case "ConditionalStmt":
|
|
128
|
+
this.checkNavInStatements(stmt.body);
|
|
129
|
+
break;
|
|
130
|
+
// SubmitStmt and ClickStmt target actions, not pages directly
|
|
131
|
+
default:
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
validateNavTarget(nav) {
|
|
136
|
+
if (!this.pageNames.has(nav.target)) {
|
|
137
|
+
const hint = this.componentNames.has(nav.target)
|
|
138
|
+
? ` ("${nav.target}" is a component, not a page)`
|
|
139
|
+
: ` ("${nav.target}" is not defined)`;
|
|
140
|
+
throw new types_1.SemanticError("SR-3", `Navigation target "${nav.target}" must be a page${hint}`, nav.pos);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
checkHandlerNav(handler) {
|
|
144
|
+
for (const outcome of handler.outcomes) {
|
|
145
|
+
if (!this.pageNames.has(outcome.target)) {
|
|
146
|
+
const hint = this.componentNames.has(outcome.target)
|
|
147
|
+
? ` ("${outcome.target}" is a component, not a page)`
|
|
148
|
+
: ` ("${outcome.target}" is not defined)`;
|
|
149
|
+
throw new types_1.SemanticError("SR-3", `Handler outcome "${outcome.outcome}" targets "${outcome.target}" which must be a page${hint}`, outcome.pos);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// ─── SR-5 ─────────────────────────────────────────────────────────────────
|
|
154
|
+
// Component composition graph must be acyclic.
|
|
155
|
+
checkSR5ComponentCycles() {
|
|
156
|
+
// Build adjacency list: component -> list of components it uses
|
|
157
|
+
const usesMap = new Map();
|
|
158
|
+
for (const comp of this.program.components) {
|
|
159
|
+
usesMap.set(comp.name, this.collectUsedComponents(comp.body));
|
|
160
|
+
}
|
|
161
|
+
// Also check that all `use` statements reference defined components
|
|
162
|
+
for (const comp of this.program.components) {
|
|
163
|
+
for (const used of usesMap.get(comp.name) ?? []) {
|
|
164
|
+
if (!this.componentNames.has(used)) {
|
|
165
|
+
throw new types_1.SemanticError("SR-6", `Component "${comp.name}" uses undefined component "${used}"`, comp.pos);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Pages can also use components — check they exist
|
|
170
|
+
for (const page of this.program.pages) {
|
|
171
|
+
for (const used of this.collectUsedComponents(page.body)) {
|
|
172
|
+
if (!this.componentNames.has(used)) {
|
|
173
|
+
throw new types_1.SemanticError("SR-6", `Page "${page.name}" uses undefined component "${used}"`, page.pos);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// DFS cycle detection
|
|
178
|
+
const visited = new Set();
|
|
179
|
+
const inStack = new Set();
|
|
180
|
+
const dfs = (name) => {
|
|
181
|
+
if (inStack.has(name)) {
|
|
182
|
+
throw new types_1.SemanticError("SR-5", `Cyclic component composition detected: "${name}" is part of a cycle`);
|
|
183
|
+
}
|
|
184
|
+
if (visited.has(name))
|
|
185
|
+
return;
|
|
186
|
+
inStack.add(name);
|
|
187
|
+
visited.add(name);
|
|
188
|
+
for (const dep of usesMap.get(name) ?? []) {
|
|
189
|
+
dfs(dep);
|
|
190
|
+
}
|
|
191
|
+
inStack.delete(name);
|
|
192
|
+
};
|
|
193
|
+
for (const name of this.componentNames) {
|
|
194
|
+
dfs(name);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
collectUsedComponents(stmts) {
|
|
198
|
+
const used = [];
|
|
199
|
+
for (const stmt of stmts) {
|
|
200
|
+
if (stmt.kind === "UseStmt") {
|
|
201
|
+
used.push(stmt.component);
|
|
202
|
+
}
|
|
203
|
+
if (stmt.kind === "ConditionalStmt") {
|
|
204
|
+
used.push(...this.collectUsedComponents(stmt.body));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return used;
|
|
208
|
+
}
|
|
209
|
+
// ─── SR-4 (strict mode) ───────────────────────────────────────────────────
|
|
210
|
+
// All pages must be reachable from the entry page.
|
|
211
|
+
checkSR4Reachability() {
|
|
212
|
+
const { app, pages, components } = this.program;
|
|
213
|
+
// Build a page -> reachable pages graph
|
|
214
|
+
const reachable = new Set();
|
|
215
|
+
const queue = [app.entry];
|
|
216
|
+
// Collect all nav targets from a body
|
|
217
|
+
const navTargetsOf = (stmts) => {
|
|
218
|
+
const targets = [];
|
|
219
|
+
for (const stmt of stmts) {
|
|
220
|
+
if (stmt.kind === "ButtonStmt" || stmt.kind === "LinkStmt") {
|
|
221
|
+
targets.push(stmt.nav.target);
|
|
222
|
+
}
|
|
223
|
+
if (stmt.kind === "HandlerStmt") {
|
|
224
|
+
for (const o of stmt.outcomes)
|
|
225
|
+
targets.push(o.target);
|
|
226
|
+
}
|
|
227
|
+
if (stmt.kind === "ConditionalStmt") {
|
|
228
|
+
targets.push(...navTargetsOf(stmt.body));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return targets;
|
|
232
|
+
};
|
|
233
|
+
// Component bodies contribute nav targets to any page that uses them
|
|
234
|
+
const compNavTargets = new Map();
|
|
235
|
+
for (const comp of components) {
|
|
236
|
+
compNavTargets.set(comp.name, navTargetsOf(comp.body));
|
|
237
|
+
}
|
|
238
|
+
const pageMap = new Map(pages.map((p) => [p.name, p]));
|
|
239
|
+
while (queue.length > 0) {
|
|
240
|
+
const name = queue.shift();
|
|
241
|
+
if (reachable.has(name))
|
|
242
|
+
continue;
|
|
243
|
+
reachable.add(name);
|
|
244
|
+
const page = pageMap.get(name);
|
|
245
|
+
if (!page)
|
|
246
|
+
continue;
|
|
247
|
+
// Direct nav targets
|
|
248
|
+
for (const t of navTargetsOf(page.body)) {
|
|
249
|
+
if (!reachable.has(t))
|
|
250
|
+
queue.push(t);
|
|
251
|
+
}
|
|
252
|
+
// Nav targets from used components
|
|
253
|
+
for (const stmt of page.body) {
|
|
254
|
+
if (stmt.kind === "UseStmt") {
|
|
255
|
+
for (const t of compNavTargets.get(stmt.component) ?? []) {
|
|
256
|
+
if (!reachable.has(t))
|
|
257
|
+
queue.push(t);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
for (const page of pages) {
|
|
263
|
+
if (!reachable.has(page.name)) {
|
|
264
|
+
throw new types_1.SemanticError("SR-4", `Page "${page.name}" is not reachable from entry "${app.entry}"`, page.pos);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=semantic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic.js","sourceRoot":"","sources":["../../src/semantic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
export interface Position {
|
|
2
|
+
line: number;
|
|
3
|
+
col: number;
|
|
4
|
+
}
|
|
5
|
+
export interface StringLiteral {
|
|
6
|
+
kind: "StringLiteral";
|
|
7
|
+
value: string;
|
|
8
|
+
pos: Position;
|
|
9
|
+
}
|
|
10
|
+
export interface NumberLiteral {
|
|
11
|
+
kind: "NumberLiteral";
|
|
12
|
+
value: number;
|
|
13
|
+
pos: Position;
|
|
14
|
+
}
|
|
15
|
+
export interface BooleanLiteral {
|
|
16
|
+
kind: "BooleanLiteral";
|
|
17
|
+
value: boolean;
|
|
18
|
+
pos: Position;
|
|
19
|
+
}
|
|
20
|
+
export type Literal = StringLiteral | NumberLiteral | BooleanLiteral;
|
|
21
|
+
export interface IdentifierExpr {
|
|
22
|
+
kind: "IdentifierExpr";
|
|
23
|
+
name: string;
|
|
24
|
+
pos: Position;
|
|
25
|
+
}
|
|
26
|
+
/** Dot-access: user.role, session.token, env.name */
|
|
27
|
+
export interface MemberExpr {
|
|
28
|
+
kind: "MemberExpr";
|
|
29
|
+
object: IdentifierExpr;
|
|
30
|
+
member: string;
|
|
31
|
+
pos: Position;
|
|
32
|
+
}
|
|
33
|
+
export type BinaryOperator = "==" | "!=" | "<" | ">" | "<=" | ">=" | "&&" | "||";
|
|
34
|
+
export interface BinaryExpr {
|
|
35
|
+
kind: "BinaryExpr";
|
|
36
|
+
operator: BinaryOperator;
|
|
37
|
+
left: Expression;
|
|
38
|
+
right: Expression;
|
|
39
|
+
pos: Position;
|
|
40
|
+
}
|
|
41
|
+
export interface UnaryExpr {
|
|
42
|
+
kind: "UnaryExpr";
|
|
43
|
+
operator: "!";
|
|
44
|
+
operand: Expression;
|
|
45
|
+
pos: Position;
|
|
46
|
+
}
|
|
47
|
+
export type Expression = IdentifierExpr | MemberExpr | Literal | BinaryExpr | UnaryExpr;
|
|
48
|
+
export interface NavTarget {
|
|
49
|
+
/** The page identifier this navigation points to */
|
|
50
|
+
target: string;
|
|
51
|
+
pos: Position;
|
|
52
|
+
}
|
|
53
|
+
export interface OutcomeClause {
|
|
54
|
+
/** The outcome label, e.g. "success" or "error" */
|
|
55
|
+
outcome: string;
|
|
56
|
+
/** The page identifier to navigate to */
|
|
57
|
+
target: string;
|
|
58
|
+
pos: Position;
|
|
59
|
+
}
|
|
60
|
+
export interface HeaderStmt {
|
|
61
|
+
kind: "HeaderStmt";
|
|
62
|
+
text: string;
|
|
63
|
+
pos: Position;
|
|
64
|
+
}
|
|
65
|
+
export interface TextStmt {
|
|
66
|
+
kind: "TextStmt";
|
|
67
|
+
text: string;
|
|
68
|
+
pos: Position;
|
|
69
|
+
}
|
|
70
|
+
export interface ButtonStmt {
|
|
71
|
+
kind: "ButtonStmt";
|
|
72
|
+
label: string;
|
|
73
|
+
nav: NavTarget;
|
|
74
|
+
pos: Position;
|
|
75
|
+
}
|
|
76
|
+
export interface LinkStmt {
|
|
77
|
+
kind: "LinkStmt";
|
|
78
|
+
label: string;
|
|
79
|
+
nav: NavTarget;
|
|
80
|
+
pos: Position;
|
|
81
|
+
}
|
|
82
|
+
export interface FieldStmt {
|
|
83
|
+
kind: "FieldStmt";
|
|
84
|
+
name: string;
|
|
85
|
+
pos: Position;
|
|
86
|
+
}
|
|
87
|
+
export interface InputStmt {
|
|
88
|
+
kind: "InputStmt";
|
|
89
|
+
name: string;
|
|
90
|
+
pos: Position;
|
|
91
|
+
}
|
|
92
|
+
export interface UseStmt {
|
|
93
|
+
kind: "UseStmt";
|
|
94
|
+
component: string;
|
|
95
|
+
pos: Position;
|
|
96
|
+
}
|
|
97
|
+
export interface SubmitStmt {
|
|
98
|
+
kind: "SubmitStmt";
|
|
99
|
+
label: string;
|
|
100
|
+
action: string;
|
|
101
|
+
pos: Position;
|
|
102
|
+
}
|
|
103
|
+
export interface ClickStmt {
|
|
104
|
+
kind: "ClickStmt";
|
|
105
|
+
label: string;
|
|
106
|
+
action: string;
|
|
107
|
+
pos: Position;
|
|
108
|
+
}
|
|
109
|
+
export interface HandlerStmt {
|
|
110
|
+
kind: "HandlerStmt";
|
|
111
|
+
action: string;
|
|
112
|
+
outcomes: OutcomeClause[];
|
|
113
|
+
pos: Position;
|
|
114
|
+
}
|
|
115
|
+
export interface ConditionalStmt {
|
|
116
|
+
kind: "ConditionalStmt";
|
|
117
|
+
condition: Expression;
|
|
118
|
+
body: Statement[];
|
|
119
|
+
pos: Position;
|
|
120
|
+
}
|
|
121
|
+
export type Statement = HeaderStmt | TextStmt | ButtonStmt | LinkStmt | FieldStmt | InputStmt | UseStmt | SubmitStmt | ClickStmt | HandlerStmt | ConditionalStmt;
|
|
122
|
+
export interface AppDecl {
|
|
123
|
+
kind: "AppDecl";
|
|
124
|
+
name: string;
|
|
125
|
+
entry: string;
|
|
126
|
+
pos: Position;
|
|
127
|
+
}
|
|
128
|
+
export interface PageDecl {
|
|
129
|
+
kind: "PageDecl";
|
|
130
|
+
name: string;
|
|
131
|
+
body: Statement[];
|
|
132
|
+
pos: Position;
|
|
133
|
+
}
|
|
134
|
+
export interface ComponentDecl {
|
|
135
|
+
kind: "ComponentDecl";
|
|
136
|
+
name: string;
|
|
137
|
+
body: Statement[];
|
|
138
|
+
pos: Position;
|
|
139
|
+
}
|
|
140
|
+
export interface Program {
|
|
141
|
+
kind: "Program";
|
|
142
|
+
app: AppDecl;
|
|
143
|
+
pages: PageDecl[];
|
|
144
|
+
components: ComponentDecl[];
|
|
145
|
+
}
|
|
146
|
+
export declare class ParseError extends Error {
|
|
147
|
+
readonly pos: Position;
|
|
148
|
+
constructor(message: string, pos: Position);
|
|
149
|
+
}
|
|
150
|
+
export type SemanticRuleCode = "SR-1" | "SR-2" | "SR-3" | "SR-4" | "SR-5" | "SR-6";
|
|
151
|
+
export declare class SemanticError extends Error {
|
|
152
|
+
readonly rule: SemanticRuleCode;
|
|
153
|
+
readonly pos?: Position | undefined;
|
|
154
|
+
constructor(rule: SemanticRuleCode, message: string, pos?: Position | undefined);
|
|
155
|
+
}
|
|
156
|
+
export interface ParseOptions {
|
|
157
|
+
/** Enable SR-4: all pages must be reachable from entry */
|
|
158
|
+
strictMode?: boolean;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
// SWAN DSL — Strict TypeScript AST Types
|
|
4
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SemanticError = exports.ParseError = void 0;
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Error types
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
class ParseError extends Error {
|
|
11
|
+
pos;
|
|
12
|
+
constructor(message, pos) {
|
|
13
|
+
super(`ParseError at ${pos.line}:${pos.col} — ${message}`);
|
|
14
|
+
this.pos = pos;
|
|
15
|
+
this.name = "ParseError";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.ParseError = ParseError;
|
|
19
|
+
class SemanticError extends Error {
|
|
20
|
+
rule;
|
|
21
|
+
pos;
|
|
22
|
+
constructor(rule, message, pos) {
|
|
23
|
+
const loc = pos ? ` at ${pos.line}:${pos.col}` : "";
|
|
24
|
+
super(`SemanticError [${rule}]${loc} — ${message}`);
|
|
25
|
+
this.rule = rule;
|
|
26
|
+
this.pos = pos;
|
|
27
|
+
this.name = "SemanticError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.SemanticError = SemanticError;
|
|
31
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,gFAAgF;;;AAwOhF,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAa,UAAW,SAAQ,KAAK;IAGb;IAFpB,YACI,OAAe,EACC,GAAa;QAE7B,KAAK,CAAC,iBAAiB,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,MAAM,OAAO,EAAE,CAAC,CAAC;QAF3C,QAAG,GAAH,GAAG,CAAU;QAG7B,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC7B,CAAC;CACJ;AARD,gCAQC;AAUD,MAAa,aAAc,SAAQ,KAAK;IAEhB;IAEA;IAHpB,YACoB,IAAsB,EACtC,OAAe,EACC,GAAc;QAE9B,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,KAAK,CAAC,kBAAkB,IAAI,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC,CAAC;QALpC,SAAI,GAAJ,IAAI,CAAkB;QAEtB,QAAG,GAAH,GAAG,CAAW;QAI9B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAChC,CAAC;CACJ;AAVD,sCAUC"}
|
package/dist/test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../test.ts"],"names":[],"mappings":""}
|
package/dist/test.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("./src/index");
|
|
4
|
+
const EXAMPLE_DSL = `
|
|
5
|
+
app MyApp {
|
|
6
|
+
entry Home
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
page Home {
|
|
10
|
+
header "Welcome"
|
|
11
|
+
button "Log in" -> Login
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
component LoginForm {
|
|
15
|
+
field email
|
|
16
|
+
field password
|
|
17
|
+
|
|
18
|
+
submit "Continue" -> auth
|
|
19
|
+
|
|
20
|
+
on auth {
|
|
21
|
+
success -> Dashboard
|
|
22
|
+
error -> LoginError
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
page Login {
|
|
27
|
+
header "Login"
|
|
28
|
+
use LoginForm
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
page LoginError {
|
|
32
|
+
text "Invalid credentials"
|
|
33
|
+
button "Retry" -> Login
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
page Dashboard {
|
|
37
|
+
header "Dashboard"
|
|
38
|
+
text "Hello!"
|
|
39
|
+
button "Logout" -> Home
|
|
40
|
+
}
|
|
41
|
+
`.trim();
|
|
42
|
+
async function main() {
|
|
43
|
+
const program = (0, index_1.parse)(EXAMPLE_DSL);
|
|
44
|
+
console.log("Parsed Program:\n" + JSON.stringify(program, null, 2));
|
|
45
|
+
}
|
|
46
|
+
// main().catch(console.error).finally(() => process.exit(0));
|
|
47
|
+
//# sourceMappingURL=test.js.map
|
package/dist/test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../test.ts"],"names":[],"mappings":";;AAAA,uCAAoC;AAEpC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCnB,CAAC,IAAI,EAAE,CAAC;AAET,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAA,aAAK,EAAC,WAAW,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,8DAA8D"}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@naiv/swan-dsl",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "SWAN DSL Parser",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "rm -rf dist && tsc",
|
|
8
|
+
"test": "node dist"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"package.json"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [],
|
|
18
|
+
"author": "",
|
|
19
|
+
"license": "ISC",
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/moo": "^0.5.10",
|
|
22
|
+
"@types/node": "^25.3.0",
|
|
23
|
+
"typescript": "^5.9.3"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"moo": "^0.5.2"
|
|
27
|
+
}
|
|
28
|
+
}
|