@foxystar/molang 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +82 -0
  2. package/esm/LRUCache.d.ts +6 -0
  3. package/esm/LRUCache.js +30 -0
  4. package/esm/diagnostics/error.d.ts +12 -0
  5. package/esm/diagnostics/error.js +37 -0
  6. package/esm/diagnostics/suggestions.d.ts +2 -0
  7. package/esm/diagnostics/suggestions.js +35 -0
  8. package/esm/index.d.ts +8 -0
  9. package/esm/index.js +6 -0
  10. package/esm/molang.d.ts +2 -0
  11. package/esm/molang.js +22 -0
  12. package/esm/package.json +3 -0
  13. package/esm/parser/expression.d.ts +87 -0
  14. package/esm/parser/expression.js +19 -0
  15. package/esm/parser/parser.d.ts +20 -0
  16. package/esm/parser/parser.js +490 -0
  17. package/esm/runtime/context.d.ts +19 -0
  18. package/esm/runtime/context.js +51 -0
  19. package/esm/runtime/math.d.ts +32 -0
  20. package/esm/runtime/math.js +89 -0
  21. package/esm/runtime/runtime.d.ts +34 -0
  22. package/esm/runtime/runtime.js +537 -0
  23. package/package.json +39 -0
  24. package/script/LRUCache.d.ts +6 -0
  25. package/script/LRUCache.js +33 -0
  26. package/script/diagnostics/error.d.ts +12 -0
  27. package/script/diagnostics/error.js +42 -0
  28. package/script/diagnostics/suggestions.d.ts +2 -0
  29. package/script/diagnostics/suggestions.js +40 -0
  30. package/script/index.d.ts +8 -0
  31. package/script/index.js +27 -0
  32. package/script/molang.d.ts +2 -0
  33. package/script/molang.js +29 -0
  34. package/script/package.json +3 -0
  35. package/script/parser/expression.d.ts +87 -0
  36. package/script/parser/expression.js +22 -0
  37. package/script/parser/parser.d.ts +20 -0
  38. package/script/parser/parser.js +494 -0
  39. package/script/runtime/context.d.ts +19 -0
  40. package/script/runtime/context.js +57 -0
  41. package/script/runtime/math.d.ts +32 -0
  42. package/script/runtime/math.js +92 -0
  43. package/script/runtime/runtime.d.ts +34 -0
  44. package/script/runtime/runtime.js +567 -0
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MolangRuntimeError = exports.MolangParseError = void 0;
4
+ class MolangError extends Error {
5
+ constructor(message, start, end, source) {
6
+ super(MolangError.formatError(message, start, end, source));
7
+ this.name = this.constructor.name;
8
+ }
9
+ static formatError(message, pos, end, src) {
10
+ let line = 1;
11
+ let lastLineStart = 0;
12
+ for (let i = 0; i < pos; i++) {
13
+ if (src[i] === "\n") {
14
+ line++;
15
+ lastLineStart = i + 1;
16
+ }
17
+ }
18
+ const column = pos - lastLineStart + 1;
19
+ const lines = src.split("\n");
20
+ const lineText = lines[line - 1] ?? "";
21
+ //const pointer = " ".repeat(column - 1) + "^";
22
+ const span = Math.max(1, end - pos);
23
+ const underlineLength = Math.min(span, Math.max(1, lineText.length - column + 1));
24
+ const pointer = " ".repeat(column - 1) +
25
+ "^".repeat(underlineLength);
26
+ return (`${message} at line ${line - 1}, column ${column}\n` +
27
+ `${lineText}\n` +
28
+ `${pointer}`);
29
+ }
30
+ }
31
+ class MolangParseError extends MolangError {
32
+ constructor(message, position, source) {
33
+ super(message, position, position + 1, source);
34
+ }
35
+ }
36
+ exports.MolangParseError = MolangParseError;
37
+ class MolangRuntimeError extends MolangError {
38
+ constructor(message, expr, source) {
39
+ super(message, expr.start, expr.end, source);
40
+ }
41
+ }
42
+ exports.MolangRuntimeError = MolangRuntimeError;
@@ -0,0 +1,2 @@
1
+ export declare function levenshtein(a: string, b: string): number;
2
+ export declare function findBestMatch(name: string, candidates: string[]): string | null;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findBestMatch = exports.levenshtein = void 0;
4
+ function levenshtein(a, b) {
5
+ const dp = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1).fill(0));
6
+ for (let i = 0; i <= a.length; i++) {
7
+ dp[i][0] = i;
8
+ }
9
+ for (let j = 0; j <= b.length; j++) {
10
+ dp[0][j] = j;
11
+ }
12
+ for (let i = 1; i <= a.length; i++) {
13
+ for (let j = 1; j <= b.length; j++) {
14
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
15
+ dp[i][j] = Math.min(dp[i - 1][j] + 1, // deletion
16
+ dp[i][j - 1] + 1, // insertion
17
+ dp[i - 1][j - 1] + cost // substitution
18
+ );
19
+ }
20
+ }
21
+ return dp[a.length][b.length];
22
+ }
23
+ exports.levenshtein = levenshtein;
24
+ function findBestMatch(name, candidates) {
25
+ let best = null;
26
+ let bestScore = Infinity;
27
+ for (const c of candidates) {
28
+ const d = levenshtein(name.toLowerCase(), c.toLowerCase());
29
+ if (d < bestScore) {
30
+ bestScore = d;
31
+ best = c;
32
+ }
33
+ }
34
+ // Heuristic: only suggest if it's "close enough"
35
+ if (best !== null && bestScore <= 2) {
36
+ return best;
37
+ }
38
+ return null;
39
+ }
40
+ exports.findBestMatch = findBestMatch;
@@ -0,0 +1,8 @@
1
+ export { evaluate } from "./molang.js";
2
+ export { MolangParser } from "./parser/parser.js";
3
+ export type { Expr, ExprBase, Program, Statement, Token, TokenType } from "./parser/expression.js";
4
+ export * from "./runtime/context.js";
5
+ export { MolangMath } from "./runtime/math.js";
6
+ export { MolangRuntime } from "./runtime/runtime.js";
7
+ export type { MolangOptions } from "./runtime/runtime.js";
8
+ export * from "./diagnostics/error.js";
@@ -0,0 +1,27 @@
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
+ exports.MolangRuntime = exports.MolangMath = exports.MolangParser = exports.evaluate = void 0;
18
+ var molang_js_1 = require("./molang.js");
19
+ Object.defineProperty(exports, "evaluate", { enumerable: true, get: function () { return molang_js_1.evaluate; } });
20
+ var parser_js_1 = require("./parser/parser.js");
21
+ Object.defineProperty(exports, "MolangParser", { enumerable: true, get: function () { return parser_js_1.MolangParser; } });
22
+ __exportStar(require("./runtime/context.js"), exports);
23
+ var math_js_1 = require("./runtime/math.js");
24
+ Object.defineProperty(exports, "MolangMath", { enumerable: true, get: function () { return math_js_1.MolangMath; } });
25
+ var runtime_js_1 = require("./runtime/runtime.js");
26
+ Object.defineProperty(exports, "MolangRuntime", { enumerable: true, get: function () { return runtime_js_1.MolangRuntime; } });
27
+ __exportStar(require("./diagnostics/error.js"), exports);
@@ -0,0 +1,2 @@
1
+ import { MolangContext } from "./runtime/context.js";
2
+ export declare function evaluate(input: string, context?: MolangContext): unknown;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.evaluate = void 0;
7
+ const parser_js_1 = require("./parser/parser.js");
8
+ const runtime_js_1 = require("./runtime/runtime.js");
9
+ const context_js_1 = require("./runtime/context.js");
10
+ const LRUCache_js_1 = __importDefault(require("./LRUCache.js"));
11
+ const MAX_CACHE_SIZE = 2048;
12
+ const cache = new LRUCache_js_1.default(MAX_CACHE_SIZE);
13
+ function evaluate(input, context = {}) {
14
+ if (context === context_js_1.DEFAULT_CONTEXT) {
15
+ context = (0, context_js_1.mergeContext)(context_js_1.DEFAULT_CONTEXT, {});
16
+ }
17
+ else if (!Object.prototype.isPrototypeOf.call(context_js_1.DEFAULT_CONTEXT, context)) {
18
+ Object.setPrototypeOf(context, context_js_1.DEFAULT_CONTEXT);
19
+ }
20
+ let program = cache.get(input);
21
+ if (!program) {
22
+ const parser = new parser_js_1.MolangParser(input);
23
+ program = parser.parseProgram();
24
+ cache.set(input, program);
25
+ }
26
+ const runtime = new runtime_js_1.MolangRuntime(context, input, { strict: false });
27
+ return runtime.evaluateProgram(program);
28
+ }
29
+ exports.evaluate = evaluate;
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,87 @@
1
+ export declare const TOKEN_REGEX: RegExp;
2
+ export type ExprBase = {
3
+ start: number;
4
+ end: number;
5
+ };
6
+ export type Expr = ({
7
+ type: "Literal";
8
+ value: unknown;
9
+ } & ExprBase) | ({
10
+ type: "Identifier";
11
+ name: string;
12
+ path: string[];
13
+ } & ExprBase) | ({
14
+ type: "BinaryExpression";
15
+ operator: string;
16
+ left: Expr;
17
+ right: Expr;
18
+ } & ExprBase) | ({
19
+ type: "CallExpression";
20
+ callee: Expr;
21
+ arguments: Expr[];
22
+ } & ExprBase) | ({
23
+ type: "UnaryExpression";
24
+ operator: string;
25
+ expression: Expr;
26
+ } & ExprBase) | ({
27
+ type: "ArrayLiteral";
28
+ elements: Expr[];
29
+ } & ExprBase) | ({
30
+ type: "IndexExpression";
31
+ array: Expr;
32
+ index: Expr;
33
+ } & ExprBase) | ({
34
+ type: "ArrowExpression";
35
+ left: Expr;
36
+ right: Expr;
37
+ } & ExprBase) | ({
38
+ type: "ConditionalExpression";
39
+ condition: Expr;
40
+ then: Expr;
41
+ else?: Expr;
42
+ } & ExprBase);
43
+ export type Statement = ({
44
+ type: "ExprStatement";
45
+ expr: Expr;
46
+ } & ExprBase) | ({
47
+ type: "AssignStatement";
48
+ target: Expr;
49
+ value: Expr;
50
+ } & ExprBase) | ({
51
+ type: "ReturnStatement";
52
+ value?: Expr;
53
+ } & ExprBase) | ({
54
+ type: "BreakStatement";
55
+ } & ExprBase) | ({
56
+ type: "ContinueStatement";
57
+ } & ExprBase) | ({
58
+ type: "LoopStatement";
59
+ count: Expr;
60
+ body: Statement;
61
+ } & ExprBase) | ({
62
+ type: "ForEachStatement";
63
+ iterator: Expr;
64
+ iterable: Expr;
65
+ body: Statement;
66
+ } & ExprBase) | ({
67
+ type: "ConditionalStatement";
68
+ condition: Expr;
69
+ then: Statement;
70
+ else?: Statement;
71
+ } & ExprBase) | ({
72
+ type: "BlockStatement";
73
+ body: Statement[];
74
+ } & ExprBase);
75
+ export type Program = {
76
+ type: "Program";
77
+ body: Statement[];
78
+ start: number;
79
+ end: number;
80
+ };
81
+ export type TokenType = "number" | "string" | "identifier" | "assignment" | "operator" | "parenthesis" | "brace" | "comma" | "bracket" | "semicolon" | "eof";
82
+ export type Token = {
83
+ type: TokenType;
84
+ value: string;
85
+ start: number;
86
+ end: number;
87
+ };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TOKEN_REGEX = void 0;
4
+ exports.TOKEN_REGEX = new RegExp([
5
+ // number
6
+ "^(?<number>-?\\d+(?:\\.\\d+)?)",
7
+ // string (double OR single quotes)
8
+ "(?<string>\"[^\"]*\"|'[^']*')",
9
+ // identifier + dotted path
10
+ "(?<identifier>[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*)",
11
+ "(?<assignment>=(?!=))",
12
+ "(?<operator>\\?\\?|->|>>>|>>|<<|\\|\\||&&|==|!=|<=|>=|\\^|\\||&|\\?|:|[+\\-*/<>!])",
13
+ // grouping
14
+ "(?<parenthesis>[()])",
15
+ "(?<bracket>[\\[\\]])",
16
+ "(?<brace>[{}])",
17
+ // punctuation
18
+ "(?<comma>,)",
19
+ "(?<semicolon>;)",
20
+ // whitespace
21
+ "(?<whitespace>\\s+)"
22
+ ].join("|^"));
@@ -0,0 +1,20 @@
1
+ import { Program } from "./expression.js";
2
+ export declare class MolangParser {
3
+ private input;
4
+ private tokens;
5
+ private position;
6
+ constructor(input: string);
7
+ private tokenize;
8
+ private peek;
9
+ private consume;
10
+ parseProgram(): Program;
11
+ private parseStatement;
12
+ private parseExpression;
13
+ private parseBinaryExpression;
14
+ private tryFold;
15
+ private getOperatorPrecedence;
16
+ private parseConditionalExpression;
17
+ private parsePrimaryExpression;
18
+ private parseUnary;
19
+ private parseAtom;
20
+ }