@lokascript/framework 4.7.0 → 4.8.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.
- package/CHANGELOG.md +35 -1
- package/dist/api/create-dsl.d.ts +5 -2
- package/dist/api/create-dsl.d.ts.map +1 -1
- package/dist/api/index.js +45 -5
- package/dist/api/index.js.map +1 -1
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/matching/stock-reader.d.ts +8 -1
- package/dist/core/matching/stock-reader.d.ts.map +1 -1
- package/dist/core/pattern-matching/index.js.map +1 -1
- package/dist/core/types.d.ts +5 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/generation/index.js +12 -2
- package/dist/generation/index.js.map +1 -1
- package/dist/index.cjs +45 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +45 -5
- package/dist/index.js.map +1 -1
- package/dist/ir/index.js.map +1 -1
- package/dist/parsing/index.js.map +1 -1
- package/dist/testing/gate/index.js +44 -12
- package/dist/testing/gate/index.js.map +1 -1
- package/dist/testing/gate/round-trip.d.ts +24 -3
- package/dist/testing/gate/round-trip.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/api/create-dsl-engine.test.ts +65 -1
- package/src/api/create-dsl.test.ts +7 -0
- package/src/api/create-dsl.ts +32 -4
- package/src/core/matching/stock-reader.test.ts +87 -3
- package/src/core/matching/stock-reader.ts +20 -1
- package/src/core/types.ts +5 -0
- package/src/generation/schema-patterns.test.ts +41 -1
- package/src/generation/schema-patterns.ts +12 -0
- package/src/testing/gate/round-trip.test.ts +99 -9
- package/src/testing/gate/round-trip.ts +76 -11
package/dist/index.js
CHANGED
|
@@ -1706,6 +1706,11 @@ function readGreedy(tokens, stopMarkers) {
|
|
|
1706
1706
|
}
|
|
1707
1707
|
return values.length > 0 ? { type: "expression", raw: values.join(" ") } : null;
|
|
1708
1708
|
}
|
|
1709
|
+
function isListedWord(token, words) {
|
|
1710
|
+
if (!token) return false;
|
|
1711
|
+
const forms = [token.value, token.normalized].filter((f) => typeof f === "string");
|
|
1712
|
+
return forms.some((form) => words.some((word) => word.toLowerCase() === form.toLowerCase()));
|
|
1713
|
+
}
|
|
1709
1714
|
var StockValueReader = class {
|
|
1710
1715
|
constructor(view, profiles = {}) {
|
|
1711
1716
|
this.view = view;
|
|
@@ -1738,6 +1743,11 @@ var StockValueReader = class {
|
|
|
1738
1743
|
const token = tokens.peek();
|
|
1739
1744
|
if (token && this.view.wouldMatch(next, token)) return false;
|
|
1740
1745
|
}
|
|
1746
|
+
if (slot.words && !isListedWord(tokens.peek(), slot.words)) return slot.optional ?? false;
|
|
1747
|
+
if (slot.optional && !slot.greedy) {
|
|
1748
|
+
const token = tokens.peek();
|
|
1749
|
+
if (token && isStopMarker(token, greedyStopMarkers(this.view.patternRest()))) return true;
|
|
1750
|
+
}
|
|
1741
1751
|
if (slot.greedy) {
|
|
1742
1752
|
const value = readGreedy(tokens, greedyStopMarkers(this.view.patternRest()));
|
|
1743
1753
|
if (value) {
|
|
@@ -2143,11 +2153,13 @@ function generateVerbFirstPattern(schema, profile, config = defaultConfig2) {
|
|
|
2143
2153
|
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
2144
2154
|
const roleTokens = requiredRoles.flatMap((r) => {
|
|
2145
2155
|
const prefix = r.valuePrefixLiteral?.[profile.code];
|
|
2156
|
+
const words = wordsFor(r, profile.code);
|
|
2146
2157
|
const roleToken = {
|
|
2147
2158
|
type: "role",
|
|
2148
2159
|
role: r.role,
|
|
2149
2160
|
optional: false,
|
|
2150
|
-
expectedTypes: r.expectedTypes
|
|
2161
|
+
expectedTypes: r.expectedTypes,
|
|
2162
|
+
...words ? { words } : {}
|
|
2151
2163
|
};
|
|
2152
2164
|
return prefix ? [{ type: "literal", value: prefix }, roleToken] : [roleToken];
|
|
2153
2165
|
});
|
|
@@ -2317,11 +2329,17 @@ function buildRoleTokens(grammar, schema, profile) {
|
|
|
2317
2329
|
}
|
|
2318
2330
|
return tokens;
|
|
2319
2331
|
}
|
|
2332
|
+
function wordsFor(roleSpec, language) {
|
|
2333
|
+
if (!roleSpec.words) return void 0;
|
|
2334
|
+
const words = [...roleSpec.words["*"] ?? [], ...roleSpec.words[language] ?? []];
|
|
2335
|
+
return words.length > 0 ? words : void 0;
|
|
2336
|
+
}
|
|
2320
2337
|
function buildRoleToken(roleSpec, profile) {
|
|
2321
2338
|
const tokens = [];
|
|
2322
2339
|
const overrideMarker = roleSpec.markerOverride?.[profile.code];
|
|
2323
2340
|
const defaultMarker = profile.roleMarkers[roleSpec.role];
|
|
2324
2341
|
const suppressMarker = roleSpec.renderOverride?.[profile.code] === "";
|
|
2342
|
+
const words = wordsFor(roleSpec, profile.code);
|
|
2325
2343
|
const roleValueToken = {
|
|
2326
2344
|
type: "role",
|
|
2327
2345
|
role: roleSpec.role,
|
|
@@ -2333,7 +2351,9 @@ function buildRoleToken(roleSpec, profile) {
|
|
|
2333
2351
|
...roleSpec.valueShape !== void 0 ? { valueShape: roleSpec.valueShape } : {},
|
|
2334
2352
|
// A greedy role reads up to the next marker the pattern owes (a domain's
|
|
2335
2353
|
// SQL condition); its value reader does the reading.
|
|
2336
|
-
...roleSpec.greedy ? { greedy: true } : {}
|
|
2354
|
+
...roleSpec.greedy ? { greedy: true } : {},
|
|
2355
|
+
// A role with a word list reads only one of its words.
|
|
2356
|
+
...words ? { words } : {}
|
|
2337
2357
|
};
|
|
2338
2358
|
const prefixLiteral = roleSpec.valuePrefixLiteral?.[profile.code];
|
|
2339
2359
|
const pushPrefixed = () => {
|
|
@@ -3889,12 +3909,15 @@ function readingDifference(source, back) {
|
|
|
3889
3909
|
|
|
3890
3910
|
// src/api/create-dsl.ts
|
|
3891
3911
|
var UnreadInputError = class extends Error {
|
|
3892
|
-
constructor(input, language, reading, unread) {
|
|
3893
|
-
super(
|
|
3912
|
+
constructor(input, language, reading, unread, hint) {
|
|
3913
|
+
super(
|
|
3914
|
+
`"${input}" (${language}) reads as ${reading.action} only by leaving "${unread}" unread` + (hint ? `; ${hint}` : "")
|
|
3915
|
+
);
|
|
3894
3916
|
this.input = input;
|
|
3895
3917
|
this.language = language;
|
|
3896
3918
|
this.reading = reading;
|
|
3897
3919
|
this.unread = unread;
|
|
3920
|
+
this.hint = hint;
|
|
3898
3921
|
this.code = "unread-input";
|
|
3899
3922
|
this.name = "UnreadInputError";
|
|
3900
3923
|
}
|
|
@@ -4013,15 +4036,32 @@ var MultilingualDSLImpl = class {
|
|
|
4013
4036
|
}
|
|
4014
4037
|
if (longestPartial) {
|
|
4015
4038
|
const unread = tokens.tokens.slice(longestPartial.consumedTokens).map((t) => t.value).join(" ");
|
|
4039
|
+
const hint = this.quoteHint(longestPartial, tokens.tokens);
|
|
4016
4040
|
throw new UnreadInputError(
|
|
4017
4041
|
input,
|
|
4018
4042
|
language,
|
|
4019
4043
|
this.nodeOf(longestPartial, input, language),
|
|
4020
|
-
unread
|
|
4044
|
+
unread,
|
|
4045
|
+
...hint ? [hint] : []
|
|
4021
4046
|
);
|
|
4022
4047
|
}
|
|
4023
4048
|
throw new Error(`No pattern matched for input: ${input}`);
|
|
4024
4049
|
}
|
|
4050
|
+
/**
|
|
4051
|
+
* `if "buy milk" is one value, quote it`, where the last token a match read is a bare word it took
|
|
4052
|
+
* as a role's value (a role with no word list) and the first it left is a bare word too.
|
|
4053
|
+
*/
|
|
4054
|
+
quoteHint(match, tokens) {
|
|
4055
|
+
const last = tokens[match.consumedTokens - 1];
|
|
4056
|
+
const next = tokens[match.consumedTokens];
|
|
4057
|
+
if (last?.kind !== "identifier" || next?.kind !== "identifier") return void 0;
|
|
4058
|
+
const schema = this.schemaLookup.getSchema(match.pattern.command);
|
|
4059
|
+
const role = [...match.captured].find(
|
|
4060
|
+
([, v]) => v.raw === last.value
|
|
4061
|
+
)?.[0];
|
|
4062
|
+
if (!role || schema?.roles.find((r) => r.role === role)?.words) return void 0;
|
|
4063
|
+
return `if "${last.value} ${next.value}" is one value, quote it`;
|
|
4064
|
+
}
|
|
4025
4065
|
nodeOf(match, input, language) {
|
|
4026
4066
|
return {
|
|
4027
4067
|
kind: "command",
|