@aeriajs/compiler 0.0.3 → 0.0.6
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/ast.d.ts +79 -0
- package/dist/ast.js +23 -0
- package/dist/ast.mjs +21 -0
- package/dist/codegen/generateContracts.d.ts +5 -0
- package/dist/codegen/generateContracts.js +84 -0
- package/dist/codegen/generateContracts.mjs +77 -0
- package/dist/codegen/generateExports.d.ts +15 -0
- package/dist/codegen/generateExports.js +41 -0
- package/dist/codegen/generateExports.mjs +32 -0
- package/dist/codegen/generateJSCollections.d.ts +2 -0
- package/dist/codegen/generateJSCollections.js +91 -0
- package/dist/codegen/generateJSCollections.mjs +82 -0
- package/dist/codegen/generateTSCollections.d.ts +2 -0
- package/dist/codegen/generateTSCollections.js +107 -0
- package/dist/codegen/generateTSCollections.mjs +99 -0
- package/dist/codegen/index.d.ts +4 -0
- package/dist/codegen/index.js +20 -0
- package/dist/codegen/index.mjs +5 -0
- package/dist/codegen/utils.d.ts +29 -0
- package/dist/codegen/utils.js +135 -0
- package/dist/codegen/utils.mjs +114 -0
- package/dist/codegen.d.ts +3 -0
- package/dist/codegen.js +102 -0
- package/dist/codegen.mjs +52 -0
- package/dist/compile.d.ts +21 -0
- package/dist/compile.js +96 -0
- package/dist/compile.mjs +57 -0
- package/dist/diagnostic.d.ts +8 -0
- package/dist/diagnostic.js +22 -0
- package/dist/diagnostic.mjs +16 -0
- package/dist/guards.d.ts +3 -0
- package/dist/guards.js +45 -0
- package/dist/guards.mjs +8 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +23 -0
- package/dist/index.mjs +8 -0
- package/dist/lexer.d.ts +14 -0
- package/dist/lexer.js +272 -0
- package/dist/lexer.mjs +270 -0
- package/dist/parser.d.ts +8 -0
- package/dist/parser.js +907 -0
- package/dist/parser.mjs +851 -0
- package/dist/semantic.d.ts +5 -0
- package/dist/semantic.js +149 -0
- package/dist/semantic.mjs +111 -0
- package/dist/token.d.ts +38 -0
- package/dist/token.js +24 -0
- package/dist/token.mjs +22 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +2 -0
- package/dist/utils.mjs +1 -0
- package/package.json +4 -5
package/dist/compile.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.compileFromFiles = exports.generateScaffolding = exports.parseAndCheck = void 0;
|
|
37
|
+
const diagnostic_js_1 = require("./diagnostic.js");
|
|
38
|
+
const lexer_js_1 = require("./lexer.js");
|
|
39
|
+
const parser_js_1 = require("./parser.js");
|
|
40
|
+
const semantic_js_1 = require("./semantic.js");
|
|
41
|
+
const codegen_js_1 = require("./codegen.js");
|
|
42
|
+
const path = __importStar(require("node:path"));
|
|
43
|
+
const fsPromises = __importStar(require("node:fs/promises"));
|
|
44
|
+
const parseAndCheck = async (sources) => {
|
|
45
|
+
const errors = [];
|
|
46
|
+
let errorCount = 0;
|
|
47
|
+
let ast;
|
|
48
|
+
for (const fileName in sources) {
|
|
49
|
+
diagnostic_js_1.Diagnostic.currentFile = fileName;
|
|
50
|
+
const { errors: lexerErrors, tokens } = (0, lexer_js_1.tokenize)(sources[fileName]);
|
|
51
|
+
const { errors: parserErrors, ast: currentAst } = (0, parser_js_1.parse)(Array.from(tokens));
|
|
52
|
+
const { errors: semanticErrors } = await (0, semantic_js_1.analyze)(currentAst);
|
|
53
|
+
errors.push(...lexerErrors.concat(parserErrors, semanticErrors));
|
|
54
|
+
errorCount += errors.length;
|
|
55
|
+
if (!ast) {
|
|
56
|
+
ast = currentAst;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
ast.collections.push(...currentAst.collections);
|
|
60
|
+
ast.contracts.push(...currentAst.contracts);
|
|
61
|
+
ast.functionsets.push(...currentAst.functionsets);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
success: errorCount === 0,
|
|
66
|
+
errors,
|
|
67
|
+
errorCount,
|
|
68
|
+
ast: ast,
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
exports.parseAndCheck = parseAndCheck;
|
|
72
|
+
const generateScaffolding = async (options) => {
|
|
73
|
+
const directories = [path.join(options.outDir, 'collections')];
|
|
74
|
+
for (const dir of directories) {
|
|
75
|
+
await fsPromises.mkdir(dir, {
|
|
76
|
+
recursive: true,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return directories;
|
|
80
|
+
};
|
|
81
|
+
exports.generateScaffolding = generateScaffolding;
|
|
82
|
+
const compileFromFiles = async (schemaDir, options) => {
|
|
83
|
+
const fileList = await fsPromises.readdir(schemaDir);
|
|
84
|
+
const sources = {};
|
|
85
|
+
for (const file of fileList) {
|
|
86
|
+
const fileContent = await fsPromises.readFile(`${schemaDir}/${file}`);
|
|
87
|
+
sources[file] = fileContent.toString();
|
|
88
|
+
}
|
|
89
|
+
const parsed = await (0, exports.parseAndCheck)(sources);
|
|
90
|
+
const emittedFiles = await (0, codegen_js_1.generateCode)(parsed.ast, options);
|
|
91
|
+
return {
|
|
92
|
+
...parsed,
|
|
93
|
+
emittedFiles,
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
exports.compileFromFiles = compileFromFiles;
|
package/dist/compile.mjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { Diagnostic } from "./diagnostic.mjs";
|
|
3
|
+
import { tokenize } from "./lexer.mjs";
|
|
4
|
+
import { parse } from "./parser.mjs";
|
|
5
|
+
import { analyze } from "./semantic.mjs";
|
|
6
|
+
import { generateCode } from "./codegen.mjs";
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import * as fsPromises from "node:fs/promises";
|
|
9
|
+
export const parseAndCheck = async (sources) => {
|
|
10
|
+
const errors = [];
|
|
11
|
+
let errorCount = 0;
|
|
12
|
+
let ast;
|
|
13
|
+
for (const fileName in sources) {
|
|
14
|
+
Diagnostic.currentFile = fileName;
|
|
15
|
+
const { errors: lexerErrors, tokens } = tokenize(sources[fileName]);
|
|
16
|
+
const { errors: parserErrors, ast: currentAst } = parse(Array.from(tokens));
|
|
17
|
+
const { errors: semanticErrors } = await analyze(currentAst);
|
|
18
|
+
errors.push(...lexerErrors.concat(parserErrors, semanticErrors));
|
|
19
|
+
errorCount += errors.length;
|
|
20
|
+
if (!ast) {
|
|
21
|
+
ast = currentAst;
|
|
22
|
+
} else {
|
|
23
|
+
ast.collections.push(...currentAst.collections);
|
|
24
|
+
ast.contracts.push(...currentAst.contracts);
|
|
25
|
+
ast.functionsets.push(...currentAst.functionsets);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
success: errorCount === 0,
|
|
30
|
+
errors,
|
|
31
|
+
errorCount,
|
|
32
|
+
ast
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export const generateScaffolding = async (options) => {
|
|
36
|
+
const directories = [path.join(options.outDir, "collections")];
|
|
37
|
+
for (const dir of directories) {
|
|
38
|
+
await fsPromises.mkdir(dir, {
|
|
39
|
+
recursive: true
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return directories;
|
|
43
|
+
};
|
|
44
|
+
export const compileFromFiles = async (schemaDir, options) => {
|
|
45
|
+
const fileList = await fsPromises.readdir(schemaDir);
|
|
46
|
+
const sources = {};
|
|
47
|
+
for (const file of fileList) {
|
|
48
|
+
const fileContent = await fsPromises.readFile(`${schemaDir}/${file}`);
|
|
49
|
+
sources[file] = fileContent.toString();
|
|
50
|
+
}
|
|
51
|
+
const parsed = await parseAndCheck(sources);
|
|
52
|
+
const emittedFiles = await generateCode(parsed.ast, options);
|
|
53
|
+
return {
|
|
54
|
+
...parsed,
|
|
55
|
+
emittedFiles
|
|
56
|
+
};
|
|
57
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Location } from './token.js';
|
|
2
|
+
export declare class Diagnostic extends Error {
|
|
3
|
+
message: string;
|
|
4
|
+
location: Location;
|
|
5
|
+
fileLocation: string | undefined;
|
|
6
|
+
static currentFile: string | undefined;
|
|
7
|
+
constructor(message: string, location?: Location, fileLocation?: string | undefined);
|
|
8
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Diagnostic = void 0;
|
|
4
|
+
const emptyLocation = {
|
|
5
|
+
index: 0,
|
|
6
|
+
line: 0,
|
|
7
|
+
start: 0,
|
|
8
|
+
end: 0,
|
|
9
|
+
};
|
|
10
|
+
class Diagnostic extends Error {
|
|
11
|
+
message;
|
|
12
|
+
location;
|
|
13
|
+
fileLocation;
|
|
14
|
+
static currentFile;
|
|
15
|
+
constructor(message, location = emptyLocation, fileLocation = Diagnostic.currentFile) {
|
|
16
|
+
super();
|
|
17
|
+
this.message = message;
|
|
18
|
+
this.location = location;
|
|
19
|
+
this.fileLocation = fileLocation;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.Diagnostic = Diagnostic;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const emptyLocation = {
|
|
3
|
+
index: 0,
|
|
4
|
+
line: 0,
|
|
5
|
+
start: 0,
|
|
6
|
+
end: 0
|
|
7
|
+
};
|
|
8
|
+
export class Diagnostic extends Error {
|
|
9
|
+
constructor(message, location = emptyLocation, fileLocation = Diagnostic.currentFile) {
|
|
10
|
+
super();
|
|
11
|
+
this.message = message;
|
|
12
|
+
this.location = location;
|
|
13
|
+
this.fileLocation = fileLocation;
|
|
14
|
+
}
|
|
15
|
+
static currentFile;
|
|
16
|
+
}
|
package/dist/guards.d.ts
ADDED
package/dist/guards.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.isValidPropertyModifier = exports.isNativePropertyType = void 0;
|
|
37
|
+
const AST = __importStar(require("./ast.js"));
|
|
38
|
+
const isNativePropertyType = (value) => {
|
|
39
|
+
return value in AST.PropertyType;
|
|
40
|
+
};
|
|
41
|
+
exports.isNativePropertyType = isNativePropertyType;
|
|
42
|
+
const isValidPropertyModifier = (value) => {
|
|
43
|
+
return value in AST.PropertyModifiers;
|
|
44
|
+
};
|
|
45
|
+
exports.isValidPropertyModifier = isValidPropertyModifier;
|
package/dist/guards.mjs
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./ast.js"), exports);
|
|
18
|
+
__exportStar(require("./compile.js"), exports);
|
|
19
|
+
__exportStar(require("./parser.js"), exports);
|
|
20
|
+
__exportStar(require("./lexer.js"), exports);
|
|
21
|
+
__exportStar(require("./semantic.js"), exports);
|
|
22
|
+
__exportStar(require("./token.js"), exports);
|
|
23
|
+
__exportStar(require("./diagnostic.js"), exports);
|
package/dist/index.mjs
ADDED
package/dist/lexer.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Token } from './token.js';
|
|
2
|
+
import { Diagnostic } from './diagnostic.js';
|
|
3
|
+
export type Keyword = typeof COLLECTION_KEYWORDS[number] | typeof COLLECTION_ACTIONS_KEYWORDS[number] | typeof COLLECTION_SEARCH_KEYWORDS[number] | typeof CONTRACT_KEYWORDS[number] | typeof TOPLEVEL_KEYWORDS[number] | typeof MISC_KEYWORDS[number];
|
|
4
|
+
export declare const COLLECTION_KEYWORDS: readonly ["actions", "filters", "form", "functions", "icon", "indexes", "individualActions", "owned", "presets", "properties", "required", "search", "table"];
|
|
5
|
+
export declare const COLLECTION_ACTIONS_KEYWORDS: readonly ["ask", "button", "clearItem", "effect", "event", "fetchItem", "function", "icon", "label", "params", "query", "requires", "roles", "route", "selection", "setItem", "translate"];
|
|
6
|
+
export declare const COLLECTION_SEARCH_KEYWORDS: readonly ["indexes", "placeholder", "exactMatches"];
|
|
7
|
+
export declare const CONTRACT_KEYWORDS: readonly ["payload", "query", "response"];
|
|
8
|
+
export declare const TOPLEVEL_KEYWORDS: readonly ["collection", "contract", "functionset"];
|
|
9
|
+
export declare const MISC_KEYWORDS: readonly ["extends"];
|
|
10
|
+
export declare const KEYWORDS: Keyword[];
|
|
11
|
+
export declare const tokenize: (input: string) => {
|
|
12
|
+
tokens: Token[];
|
|
13
|
+
errors: Diagnostic[];
|
|
14
|
+
};
|
package/dist/lexer.js
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tokenize = exports.KEYWORDS = exports.MISC_KEYWORDS = exports.TOPLEVEL_KEYWORDS = exports.CONTRACT_KEYWORDS = exports.COLLECTION_SEARCH_KEYWORDS = exports.COLLECTION_ACTIONS_KEYWORDS = exports.COLLECTION_KEYWORDS = void 0;
|
|
4
|
+
const token_js_1 = require("./token.js");
|
|
5
|
+
const diagnostic_js_1 = require("./diagnostic.js");
|
|
6
|
+
exports.COLLECTION_KEYWORDS = [
|
|
7
|
+
'actions',
|
|
8
|
+
'filters',
|
|
9
|
+
'form',
|
|
10
|
+
'functions',
|
|
11
|
+
'icon',
|
|
12
|
+
'indexes',
|
|
13
|
+
'individualActions',
|
|
14
|
+
'owned',
|
|
15
|
+
'presets',
|
|
16
|
+
'properties',
|
|
17
|
+
'required',
|
|
18
|
+
'search',
|
|
19
|
+
'table',
|
|
20
|
+
];
|
|
21
|
+
exports.COLLECTION_ACTIONS_KEYWORDS = [
|
|
22
|
+
'ask',
|
|
23
|
+
'button',
|
|
24
|
+
'clearItem',
|
|
25
|
+
'effect',
|
|
26
|
+
'event',
|
|
27
|
+
'fetchItem',
|
|
28
|
+
'function',
|
|
29
|
+
'icon',
|
|
30
|
+
'label',
|
|
31
|
+
'params',
|
|
32
|
+
'query',
|
|
33
|
+
'requires',
|
|
34
|
+
'roles',
|
|
35
|
+
'route',
|
|
36
|
+
'selection',
|
|
37
|
+
'setItem',
|
|
38
|
+
'translate',
|
|
39
|
+
];
|
|
40
|
+
exports.COLLECTION_SEARCH_KEYWORDS = [
|
|
41
|
+
'indexes',
|
|
42
|
+
'placeholder',
|
|
43
|
+
'exactMatches',
|
|
44
|
+
];
|
|
45
|
+
exports.CONTRACT_KEYWORDS = [
|
|
46
|
+
'payload',
|
|
47
|
+
'query',
|
|
48
|
+
'response',
|
|
49
|
+
];
|
|
50
|
+
exports.TOPLEVEL_KEYWORDS = [
|
|
51
|
+
'collection',
|
|
52
|
+
'contract',
|
|
53
|
+
'functionset',
|
|
54
|
+
];
|
|
55
|
+
exports.MISC_KEYWORDS = ['extends'];
|
|
56
|
+
exports.KEYWORDS = [].concat(exports.COLLECTION_KEYWORDS, exports.COLLECTION_ACTIONS_KEYWORDS, exports.COLLECTION_SEARCH_KEYWORDS, exports.CONTRACT_KEYWORDS, exports.TOPLEVEL_KEYWORDS, exports.MISC_KEYWORDS);
|
|
57
|
+
const keywordsSet = new Set();
|
|
58
|
+
for (const keyword of exports.KEYWORDS) {
|
|
59
|
+
keywordsSet.add(keyword);
|
|
60
|
+
}
|
|
61
|
+
const TOKENS = [
|
|
62
|
+
{
|
|
63
|
+
type: null,
|
|
64
|
+
matcher: /\r?[ \t]+/,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: token_js_1.TokenType.LineBreak,
|
|
68
|
+
matcher: '\n',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: token_js_1.TokenType.Comment,
|
|
72
|
+
matcher: '//',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: token_js_1.TokenType.LeftBracket,
|
|
76
|
+
matcher: '{',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: token_js_1.TokenType.RightBracket,
|
|
80
|
+
matcher: '}',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: token_js_1.TokenType.LeftParens,
|
|
84
|
+
matcher: '(',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: token_js_1.TokenType.RightParens,
|
|
88
|
+
matcher: ')',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
type: token_js_1.TokenType.LeftSquareBracket,
|
|
92
|
+
matcher: '[',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
type: token_js_1.TokenType.RightSquareBracket,
|
|
96
|
+
matcher: ']',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
type: token_js_1.TokenType.Pipe,
|
|
100
|
+
matcher: '|',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
type: token_js_1.TokenType.Comma,
|
|
104
|
+
matcher: ',',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: token_js_1.TokenType.Range,
|
|
108
|
+
matcher: /(\d+\.\.\d*|\d*\.\.\d+)/g,
|
|
109
|
+
valueExtractor: (value) => {
|
|
110
|
+
const [, left, right] = value.match(/(\d*)\.\.(\d*)/);
|
|
111
|
+
return [
|
|
112
|
+
parseInt(left),
|
|
113
|
+
parseInt(right),
|
|
114
|
+
];
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
type: token_js_1.TokenType.Dot,
|
|
119
|
+
matcher: '.',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
type: token_js_1.TokenType.Number,
|
|
123
|
+
matcher: /[0-9]+(\.[0-9]+)?/,
|
|
124
|
+
construct: Number,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
type: token_js_1.TokenType.Boolean,
|
|
128
|
+
matcher: [
|
|
129
|
+
'true',
|
|
130
|
+
'false',
|
|
131
|
+
],
|
|
132
|
+
construct: Boolean,
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
type: token_js_1.TokenType.Keyword,
|
|
136
|
+
matcher: Array.from(keywordsSet),
|
|
137
|
+
condition: (state) => !state.inPropertiesStack.at(-1),
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: token_js_1.TokenType.MacroName,
|
|
141
|
+
matcher: /[a-zA-Z]([a-zA-Z0-9]|_)+\(/,
|
|
142
|
+
valueExtractor: (value) => value.slice(0, -1),
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: token_js_1.TokenType.Identifier,
|
|
146
|
+
matcher: /([a-zA-Z0-9]|_)+/,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: token_js_1.TokenType.QuotedString,
|
|
150
|
+
matcher: /"([^"]+)"/,
|
|
151
|
+
valueExtractor: (value) => value.slice(1, -1),
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: token_js_1.TokenType.AttributeName,
|
|
155
|
+
matcher: /@[a-zA-Z0-9]+/,
|
|
156
|
+
valueExtractor: (value) => value.slice(1),
|
|
157
|
+
},
|
|
158
|
+
];
|
|
159
|
+
const tokenize = function (input) {
|
|
160
|
+
let index = 0, line = 1, start = 0, end = 0;
|
|
161
|
+
const tokens = [];
|
|
162
|
+
const errors = [];
|
|
163
|
+
const state = {
|
|
164
|
+
inPropertiesStack: [],
|
|
165
|
+
};
|
|
166
|
+
while (index < input.length) {
|
|
167
|
+
let hasMatch = false;
|
|
168
|
+
for (const { type, matcher, valueExtractor, construct, condition } of TOKENS) {
|
|
169
|
+
let value;
|
|
170
|
+
let token;
|
|
171
|
+
if (condition) {
|
|
172
|
+
if (!condition(state)) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (typeof matcher === 'string') {
|
|
177
|
+
if (input.slice(index).startsWith(matcher)) {
|
|
178
|
+
value = matcher;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else if (matcher instanceof RegExp) {
|
|
182
|
+
const currentMatcher = new RegExp(matcher.source, 'y');
|
|
183
|
+
currentMatcher.lastIndex = index;
|
|
184
|
+
const matched = currentMatcher.exec(input);
|
|
185
|
+
if (matched) {
|
|
186
|
+
[value] = matched;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const segment = input.slice(index, index + input.slice(index).search(/[ \t\n\{\}\(\)\[\]]/));
|
|
191
|
+
if (segment && matcher.includes(segment)) {
|
|
192
|
+
value = segment;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (value) {
|
|
196
|
+
let tokenValue;
|
|
197
|
+
const location = {
|
|
198
|
+
index: index += value.length,
|
|
199
|
+
line,
|
|
200
|
+
end: end += value.length,
|
|
201
|
+
start: start = end - value.length,
|
|
202
|
+
};
|
|
203
|
+
switch (type) {
|
|
204
|
+
case null: break;
|
|
205
|
+
case token_js_1.TokenType.LineBreak:
|
|
206
|
+
line++;
|
|
207
|
+
end = 0;
|
|
208
|
+
start = 0;
|
|
209
|
+
break;
|
|
210
|
+
case token_js_1.TokenType.Comment: {
|
|
211
|
+
while (input[index++] !== '\n') { }
|
|
212
|
+
line++;
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
default: {
|
|
216
|
+
if (valueExtractor) {
|
|
217
|
+
tokenValue = construct
|
|
218
|
+
? construct(valueExtractor(value))
|
|
219
|
+
: valueExtractor(value);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
tokenValue = construct
|
|
223
|
+
? construct(value)
|
|
224
|
+
: value;
|
|
225
|
+
}
|
|
226
|
+
token = {
|
|
227
|
+
type,
|
|
228
|
+
location,
|
|
229
|
+
value: tokenValue,
|
|
230
|
+
};
|
|
231
|
+
switch (type) {
|
|
232
|
+
case token_js_1.TokenType.LeftBracket: {
|
|
233
|
+
const lastToken = tokens.at(-1);
|
|
234
|
+
if (lastToken) {
|
|
235
|
+
if (lastToken.value === 'properties') {
|
|
236
|
+
state.inPropertiesStack.push(true);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
state.inPropertiesStack.push(false);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
case token_js_1.TokenType.RightBracket: {
|
|
245
|
+
if (state.inPropertiesStack.length > 0) {
|
|
246
|
+
state.inPropertiesStack.pop();
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
tokens.push(token);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
hasMatch = true;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (!hasMatch) {
|
|
258
|
+
index += input.slice(index).search(/[ \t\n\{\}\(\)\[\]]/);
|
|
259
|
+
errors.push(new diagnostic_js_1.Diagnostic('unexpected token', {
|
|
260
|
+
index,
|
|
261
|
+
line,
|
|
262
|
+
start,
|
|
263
|
+
end,
|
|
264
|
+
}));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
tokens,
|
|
269
|
+
errors,
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
exports.tokenize = tokenize;
|