@matter/model 0.12.0-alpha.0-20241229-9d9c99934 → 0.12.0-alpha.0-20241231-9ac20db97
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/cjs/aspects/Constraint.d.ts +24 -15
- package/dist/cjs/aspects/Constraint.d.ts.map +1 -1
- package/dist/cjs/aspects/Constraint.js +268 -198
- package/dist/cjs/aspects/Constraint.js.map +2 -2
- package/dist/cjs/common/FieldValue.d.ts +9 -3
- package/dist/cjs/common/FieldValue.d.ts.map +1 -1
- package/dist/cjs/common/FieldValue.js +1 -1
- package/dist/cjs/common/FieldValue.js.map +1 -1
- package/dist/cjs/logic/definition-validation/ValueValidator.js +1 -1
- package/dist/cjs/logic/definition-validation/ValueValidator.js.map +1 -1
- package/dist/cjs/parser/Lexer.d.ts +3 -3
- package/dist/cjs/parser/Lexer.d.ts.map +1 -1
- package/dist/cjs/parser/Lexer.js +35 -31
- package/dist/cjs/parser/Lexer.js.map +1 -1
- package/dist/cjs/parser/Token.d.ts +5 -2
- package/dist/cjs/parser/Token.d.ts.map +1 -1
- package/dist/cjs/parser/TokenStream.js +2 -2
- package/dist/esm/aspects/Constraint.d.ts +24 -15
- package/dist/esm/aspects/Constraint.d.ts.map +1 -1
- package/dist/esm/aspects/Constraint.js +269 -199
- package/dist/esm/aspects/Constraint.js.map +2 -2
- package/dist/esm/common/FieldValue.d.ts +9 -3
- package/dist/esm/common/FieldValue.d.ts.map +1 -1
- package/dist/esm/common/FieldValue.js +1 -1
- package/dist/esm/common/FieldValue.js.map +1 -1
- package/dist/esm/logic/definition-validation/ValueValidator.js +1 -1
- package/dist/esm/logic/definition-validation/ValueValidator.js.map +1 -1
- package/dist/esm/parser/Lexer.d.ts +3 -3
- package/dist/esm/parser/Lexer.d.ts.map +1 -1
- package/dist/esm/parser/Lexer.js +35 -31
- package/dist/esm/parser/Lexer.js.map +1 -1
- package/dist/esm/parser/Token.d.ts +5 -2
- package/dist/esm/parser/Token.d.ts.map +1 -1
- package/dist/esm/parser/TokenStream.js +2 -2
- package/package.json +4 -4
- package/src/aspects/Constraint.ts +340 -215
- package/src/common/FieldValue.ts +9 -4
- package/src/logic/definition-validation/ValueValidator.ts +1 -1
- package/src/parser/Lexer.ts +38 -40
- package/src/parser/Token.ts +11 -1
- package/src/parser/TokenStream.ts +2 -2
package/src/common/FieldValue.ts
CHANGED
|
@@ -47,6 +47,11 @@ export namespace FieldValue {
|
|
|
47
47
|
export const none = "none";
|
|
48
48
|
export type none = typeof none;
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* A field value that allows type extension.
|
|
52
|
+
*/
|
|
53
|
+
export type Open = FieldValue | { type: string };
|
|
54
|
+
|
|
50
55
|
/**
|
|
51
56
|
* If a field value isn't a primitive type, it's an object with a type field indicating one of these types.
|
|
52
57
|
*/
|
|
@@ -55,7 +60,7 @@ export namespace FieldValue {
|
|
|
55
60
|
/**
|
|
56
61
|
* Test for one of the special placeholder types.
|
|
57
62
|
*/
|
|
58
|
-
export function is(value:
|
|
63
|
+
export function is(value: Open | undefined, type: Type) {
|
|
59
64
|
return value && (value as any).type === type;
|
|
60
65
|
}
|
|
61
66
|
|
|
@@ -150,7 +155,7 @@ export namespace FieldValue {
|
|
|
150
155
|
return `${(value as Celsius).value}°C`;
|
|
151
156
|
}
|
|
152
157
|
if (is(value, percent)) {
|
|
153
|
-
return `${(value as Percent).value}
|
|
158
|
+
return `${(value as Percent).value}%`;
|
|
154
159
|
}
|
|
155
160
|
if (is(value, properties)) {
|
|
156
161
|
return stringSerialize((value as Properties).properties) ?? "?";
|
|
@@ -161,7 +166,7 @@ export namespace FieldValue {
|
|
|
161
166
|
/**
|
|
162
167
|
* Given a type name as a hint, do our best to convert a field value to a number.
|
|
163
168
|
*/
|
|
164
|
-
export function numericValue(value:
|
|
169
|
+
export function numericValue(value: Open | undefined, typeName?: string) {
|
|
165
170
|
if (typeof value === "boolean") {
|
|
166
171
|
return value ? 1 : 0;
|
|
167
172
|
}
|
|
@@ -240,7 +245,7 @@ export namespace FieldValue {
|
|
|
240
245
|
/**
|
|
241
246
|
* Get the referenced name if the FieldValue is a reference.
|
|
242
247
|
*/
|
|
243
|
-
export function referenced(value:
|
|
248
|
+
export function referenced(value: Open | undefined) {
|
|
244
249
|
if (is(value, reference)) {
|
|
245
250
|
return (value as Reference).name;
|
|
246
251
|
}
|
|
@@ -49,7 +49,7 @@ export class ValueValidator<T extends ValueModel> extends ModelValidator<T> {
|
|
|
49
49
|
private validateAspect(name: string) {
|
|
50
50
|
const aspect = (this.model as any)[name] as Aspect;
|
|
51
51
|
if (aspect?.errors) {
|
|
52
|
-
aspect.errors.forEach((e: DefinitionError) => this.model.error(e.code, e.message));
|
|
52
|
+
aspect.errors.forEach((e: DefinitionError) => this.model.error(e.code, `${e.source}: ${e.message}`));
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
package/src/parser/Lexer.ts
CHANGED
|
@@ -16,10 +16,10 @@ function isNameChar(c: string) {
|
|
|
16
16
|
*
|
|
17
17
|
* Tokenizes simple text dialects. Currently sufficient for Matter conformance and constraint tokenization.
|
|
18
18
|
*/
|
|
19
|
-
export class Lexer<T extends BasicToken> {
|
|
19
|
+
export class Lexer<T extends BasicToken<KW>, const KW extends string[] = []> {
|
|
20
20
|
#keywords: Set<string>;
|
|
21
21
|
|
|
22
|
-
constructor(keywords
|
|
22
|
+
constructor(keywords?: KW) {
|
|
23
23
|
if (keywords instanceof Set) {
|
|
24
24
|
this.#keywords = keywords;
|
|
25
25
|
} else {
|
|
@@ -117,33 +117,7 @@ function* lex(
|
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
function
|
|
121
|
-
markStart();
|
|
122
|
-
if (sign === -1) {
|
|
123
|
-
// Skip "-" prefix
|
|
124
|
-
next();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (current.value === "0") {
|
|
128
|
-
if (peeked.value === "x") {
|
|
129
|
-
next();
|
|
130
|
-
next();
|
|
131
|
-
return tokenizeDigits(16, sign, hexadecimalValueOf);
|
|
132
|
-
} else if (peeked.value === "b") {
|
|
133
|
-
next();
|
|
134
|
-
next();
|
|
135
|
-
return tokenizeDigits(2, sign, binaryValueOf);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return tokenizeDigits(10, sign, decimalValueOf);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function tokenizeDigits(
|
|
143
|
-
base: number,
|
|
144
|
-
sign: number,
|
|
145
|
-
valueOf: (digit: string[1] | undefined) => number | undefined,
|
|
146
|
-
): BasicToken {
|
|
120
|
+
function tokenizeDigits(base: number, valueOf: (digit: string[1] | undefined) => number | undefined): BasicToken {
|
|
147
121
|
// The first digit may not actually be a digit if number is hexadecimal or binary
|
|
148
122
|
let num = valueOf(current.value);
|
|
149
123
|
if (num === undefined) {
|
|
@@ -161,7 +135,19 @@ function* lex(
|
|
|
161
135
|
num = num * base + digitValue;
|
|
162
136
|
}
|
|
163
137
|
|
|
164
|
-
|
|
138
|
+
if (base === 10 && peeked.value === ".") {
|
|
139
|
+
next();
|
|
140
|
+
let fraction = "";
|
|
141
|
+
while (true) {
|
|
142
|
+
const digitValue = valueOf(peeked.value);
|
|
143
|
+
if (digitValue === undefined) {
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
fraction += peeked.value;
|
|
147
|
+
next();
|
|
148
|
+
}
|
|
149
|
+
num = Number.parseFloat(`${num}.${fraction}`);
|
|
150
|
+
}
|
|
165
151
|
|
|
166
152
|
// Handle specialized suffices for percents and temperatures
|
|
167
153
|
if (peeked.value === "%") {
|
|
@@ -169,7 +155,7 @@ function* lex(
|
|
|
169
155
|
return { type: "value", value: FieldValue.Percent(num), startLine, startChar };
|
|
170
156
|
} else if (peeked.value === "°") {
|
|
171
157
|
next();
|
|
172
|
-
if (peeked.value?.toLowerCase() === "
|
|
158
|
+
if (peeked.value?.toLowerCase() === "c") {
|
|
173
159
|
next();
|
|
174
160
|
}
|
|
175
161
|
return { type: "value", value: FieldValue.Celsius(num), startLine, startChar };
|
|
@@ -190,22 +176,34 @@ function* lex(
|
|
|
190
176
|
case "]":
|
|
191
177
|
case "(":
|
|
192
178
|
case ")":
|
|
179
|
+
case "{":
|
|
180
|
+
case "}":
|
|
181
|
+
case "-":
|
|
193
182
|
case "+":
|
|
194
183
|
case "/":
|
|
195
184
|
case "*":
|
|
196
185
|
yield { type: current.value, startLine: line, startChar: char };
|
|
197
186
|
break;
|
|
198
187
|
|
|
199
|
-
case "
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
188
|
+
case "0":
|
|
189
|
+
markStart();
|
|
190
|
+
|
|
191
|
+
if (current.value === "0") {
|
|
192
|
+
if (peeked.value === "x") {
|
|
193
|
+
next();
|
|
194
|
+
next();
|
|
195
|
+
yield tokenizeDigits(16, hexadecimalValueOf);
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (peeked.value === "b") {
|
|
200
|
+
next();
|
|
201
|
+
next();
|
|
202
|
+
yield tokenizeDigits(2, binaryValueOf);
|
|
203
|
+
}
|
|
204
204
|
}
|
|
205
|
-
break;
|
|
206
205
|
|
|
207
|
-
|
|
208
|
-
yield tokenizeNumber(1);
|
|
206
|
+
yield tokenizeDigits(10, decimalValueOf);
|
|
209
207
|
break;
|
|
210
208
|
|
|
211
209
|
case "1":
|
|
@@ -217,7 +215,7 @@ function* lex(
|
|
|
217
215
|
case "7":
|
|
218
216
|
case "8":
|
|
219
217
|
case "9":
|
|
220
|
-
yield tokenizeDigits(10,
|
|
218
|
+
yield tokenizeDigits(10, decimalValueOf);
|
|
221
219
|
break;
|
|
222
220
|
|
|
223
221
|
case "!":
|
package/src/parser/Token.ts
CHANGED
|
@@ -18,7 +18,11 @@ export interface Token {
|
|
|
18
18
|
/**
|
|
19
19
|
* The base token produced by the tokenizer.
|
|
20
20
|
*/
|
|
21
|
-
export type BasicToken
|
|
21
|
+
export type BasicToken<KW extends string[] = []> =
|
|
22
|
+
| BasicToken.Special
|
|
23
|
+
| BasicToken.Word
|
|
24
|
+
| BasicToken.Number
|
|
25
|
+
| BasicToken.Keyword<KW>;
|
|
22
26
|
|
|
23
27
|
/**
|
|
24
28
|
* A {@link BasicToken} with additional keywords.
|
|
@@ -39,6 +43,8 @@ export namespace BasicToken {
|
|
|
39
43
|
| "]"
|
|
40
44
|
| "("
|
|
41
45
|
| ")"
|
|
46
|
+
| "{"
|
|
47
|
+
| "}"
|
|
42
48
|
| "-"
|
|
43
49
|
| "+"
|
|
44
50
|
| "*"
|
|
@@ -61,4 +67,8 @@ export namespace BasicToken {
|
|
|
61
67
|
type: "value";
|
|
62
68
|
value: FieldValue;
|
|
63
69
|
}
|
|
70
|
+
|
|
71
|
+
export interface Keyword<T extends string[]> extends Token {
|
|
72
|
+
type: T[number];
|
|
73
|
+
}
|
|
64
74
|
}
|
|
@@ -50,10 +50,10 @@ export function TokenStream<T extends Token>(iterator: Iterator<T>): TokenStream
|
|
|
50
50
|
return "end of statement";
|
|
51
51
|
|
|
52
52
|
case "word":
|
|
53
|
-
return `word "${(this.token as unknown as BasicToken.Word).value}`;
|
|
53
|
+
return `word "${(this.token as unknown as BasicToken.Word).value}"`;
|
|
54
54
|
|
|
55
55
|
case "number":
|
|
56
|
-
return `number "${(this.token as unknown as BasicToken.Number).value}`;
|
|
56
|
+
return `number "${(this.token as unknown as BasicToken.Number).value}"`;
|
|
57
57
|
|
|
58
58
|
default:
|
|
59
59
|
if (this.token?.type.match(/[a-z]/i)) {
|