desmost 0.9.1 → 0.10.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/README.md +12 -3
- package/dist/compiler/compile.d.ts +1 -7
- package/dist/compiler/compile.d.ts.map +1 -1
- package/dist/compiler/compile.js +3 -94
- package/dist/compiler/compile.js.map +1 -1
- package/dist/compiler/compiler.d.ts +56 -0
- package/dist/compiler/compiler.d.ts.map +1 -0
- package/dist/compiler/compiler.js +209 -0
- package/dist/compiler/compiler.js.map +1 -0
- package/dist/compiler/format.d.ts +2 -2
- package/dist/compiler/format.d.ts.map +1 -1
- package/dist/compiler/format.js +18 -9
- package/dist/compiler/format.js.map +1 -1
- package/dist/decompiler/decompile.d.ts +1 -1
- package/dist/decompiler/decompile.d.ts.map +1 -1
- package/dist/decompiler/extract.d.ts.map +1 -1
- package/dist/decompiler/extract.js +7 -3
- package/dist/decompiler/extract.js.map +1 -1
- package/dist/errors.d.ts +35 -27
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +46 -48
- package/dist/errors.js.map +1 -1
- package/dist/index.internal.d.ts +1 -1
- package/dist/index.internal.d.ts.map +1 -1
- package/dist/magic/global/desmos.d.ts +2 -2
- package/dist/magic/global/desmos.d.ts.map +1 -1
- package/dist/magic/global/desmos.js +3 -2
- package/dist/magic/global/desmos.js.map +1 -1
- package/dist/magic/global/viewport.d.ts +2 -2
- package/dist/magic/global/viewport.d.ts.map +1 -1
- package/dist/magic/global/viewport.js +5 -5
- package/dist/magic/global/viewport.js.map +1 -1
- package/dist/magic/incantation.d.ts +4 -4
- package/dist/magic/incantation.d.ts.map +1 -1
- package/dist/magic/incantation.js +15 -8
- package/dist/magic/incantation.js.map +1 -1
- package/dist/magic/local/colour.d.ts +3 -1
- package/dist/magic/local/colour.d.ts.map +1 -1
- package/dist/magic/local/colour.js +15 -11
- package/dist/magic/local/colour.js.map +1 -1
- package/dist/magic/local/label.d.ts.map +1 -1
- package/dist/magic/local/label.js +7 -7
- package/dist/magic/local/label.js.map +1 -1
- package/dist/magic/local/line.d.ts +2 -2
- package/dist/magic/local/line.d.ts.map +1 -1
- package/dist/magic/local/line.js +0 -1
- package/dist/magic/local/line.js.map +1 -1
- package/dist/options.d.ts +57 -23
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +2 -1
- package/dist/options.js.map +1 -1
- package/dist/parser/ast.d.ts +3 -17
- package/dist/parser/ast.d.ts.map +1 -1
- package/dist/parser/ast.js +0 -2
- package/dist/parser/ast.js.map +1 -1
- package/dist/parser/desmost-parser.d.ts +33 -22
- package/dist/parser/desmost-parser.d.ts.map +1 -1
- package/dist/parser/desmost-parser.js +114 -100
- package/dist/parser/desmost-parser.js.map +1 -1
- package/dist/parser/generic-parser.d.ts +23 -14
- package/dist/parser/generic-parser.d.ts.map +1 -1
- package/dist/parser/generic-parser.js +67 -27
- package/dist/parser/generic-parser.js.map +1 -1
- package/dist/utils.d.ts +9 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +13 -2
- package/dist/utils.js.map +1 -1
- package/package.json +5 -2
- package/src/compiler/compile.ts +7 -120
- package/src/compiler/compiler.ts +275 -0
- package/src/compiler/format.ts +19 -7
- package/src/decompiler/decompile.ts +1 -1
- package/src/decompiler/extract.ts +3 -1
- package/src/errors.ts +40 -24
- package/src/index.internal.ts +1 -1
- package/src/magic/.template.ts +2 -2
- package/src/magic/global/desmos.ts +7 -9
- package/src/magic/global/viewport.ts +11 -17
- package/src/magic/incantation.ts +21 -22
- package/src/magic/local/colour.ts +23 -13
- package/src/magic/local/label.ts +11 -17
- package/src/magic/local/line.ts +2 -2
- package/src/options.ts +81 -47
- package/src/parser/ast.ts +1 -21
- package/src/parser/desmost-parser.ts +139 -143
- package/src/parser/generic-parser.ts +82 -40
- package/src/utils.ts +25 -3
- package/dist/compiler/evaluate.d.ts +0 -18
- package/dist/compiler/evaluate.d.ts.map +0 -1
- package/dist/compiler/evaluate.js +0 -93
- package/dist/compiler/evaluate.js.map +0 -1
- package/dist/desmos.d.ts +0 -16
- package/dist/desmos.d.ts.map +0 -1
- package/dist/desmos.js +0 -19
- package/dist/desmos.js.map +0 -1
- package/src/compiler/evaluate.ts +0 -128
- package/src/desmos.ts +0 -22
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import { NO_MATCH,
|
|
1
|
+
import { NO_MATCH, DesmostError } from "../errors.js";
|
|
2
2
|
const IGNORED_CHARACTERS = new Set([
|
|
3
|
-
|
|
3
|
+
'\r',
|
|
4
4
|
]);
|
|
5
5
|
/**
|
|
6
6
|
* A stateful lazy parser, providing core (non-Desmost-specific) methods for parsing.
|
|
7
7
|
*
|
|
8
|
-
* Many methods come in `<verb>` and `try_<verb>` pairs. On parsing failure, the former throws an `
|
|
8
|
+
* Many methods come in `<verb>` and `try_<verb>` pairs. On parsing failure, the former throws an `DesmostError`, but the latter instead backtracks and only returns a `NoMatch`. The former is for expected parses, while the latter is for speculative parsing.
|
|
9
9
|
*/
|
|
10
10
|
export class GenericParser {
|
|
11
|
-
/** The source code
|
|
11
|
+
/** The source code to parse. */
|
|
12
12
|
source;
|
|
13
13
|
/** The current position in the source code the parser is pointing to. */
|
|
14
14
|
i = 0;
|
|
15
15
|
/** The number of characters in the source code. */
|
|
16
16
|
length;
|
|
17
|
+
/** Accumulated errors in the current block being parsed. */
|
|
18
|
+
errors;
|
|
17
19
|
/** Create a parser for parsing `source`. */
|
|
18
20
|
constructor(source) {
|
|
19
21
|
this.source = source;
|
|
20
22
|
this.length = source.length;
|
|
23
|
+
this.errors = [];
|
|
21
24
|
}
|
|
22
25
|
/**
|
|
23
26
|
* Is the parser currently pointing at an invalid character?
|
|
@@ -31,8 +34,17 @@ export class GenericParser {
|
|
|
31
34
|
get current() {
|
|
32
35
|
return this.source.at(this.i);
|
|
33
36
|
}
|
|
37
|
+
peek() {
|
|
38
|
+
return this.source.at(this.i + 1);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Peek the rest of the content in the current line.
|
|
42
|
+
*/
|
|
43
|
+
peek_line() {
|
|
44
|
+
return this.source.slice(this.i, this.source.indexOf("\n", this.i));
|
|
45
|
+
}
|
|
34
46
|
/**
|
|
35
|
-
* Peek a snippet of the upcoming source text.
|
|
47
|
+
* Peek a snippet of the upcoming source text for display purposes.
|
|
36
48
|
*
|
|
37
49
|
* Optionally start from the given `idx`.
|
|
38
50
|
*/
|
|
@@ -44,11 +56,11 @@ export class GenericParser {
|
|
|
44
56
|
/**
|
|
45
57
|
* Advance to the next character, skipping ignored characters.
|
|
46
58
|
*
|
|
47
|
-
* Errors if the parser is
|
|
59
|
+
* Errors if the parser is already out-of-bounds *before* advancing.
|
|
48
60
|
*/
|
|
49
|
-
advance(
|
|
61
|
+
advance(error_data) {
|
|
50
62
|
if (this.out_of_bounds()) {
|
|
51
|
-
throw new
|
|
63
|
+
throw new DesmostError.UnexpectedEnd(error_data ?? {});
|
|
52
64
|
}
|
|
53
65
|
this.#advance();
|
|
54
66
|
}
|
|
@@ -58,44 +70,58 @@ export class GenericParser {
|
|
|
58
70
|
* Fails if the parser is the out-of-bounds *before* advancing.
|
|
59
71
|
*/
|
|
60
72
|
try_advance() {
|
|
61
|
-
if (this.out_of_bounds())
|
|
73
|
+
if (this.out_of_bounds()) {
|
|
62
74
|
return NO_MATCH;
|
|
75
|
+
}
|
|
63
76
|
this.#advance();
|
|
64
77
|
}
|
|
65
78
|
#advance() {
|
|
66
79
|
this.i++;
|
|
67
80
|
// @ts-expect-error: `this.current == undefined` is a true negative
|
|
68
|
-
|
|
69
|
-
this.
|
|
81
|
+
while (IGNORED_CHARACTERS.has(this.current)) {
|
|
82
|
+
this.i++;
|
|
70
83
|
}
|
|
71
84
|
}
|
|
72
85
|
/**
|
|
73
86
|
* Consume `raw`, erroring if `raw` was not found.
|
|
74
87
|
*/
|
|
75
|
-
|
|
88
|
+
eat(raw, error_data) {
|
|
76
89
|
if (this.out_of_bounds()) {
|
|
77
|
-
throw new
|
|
90
|
+
throw new DesmostError.UnexpectedEnd({
|
|
91
|
+
msg: `While trying to consume: \`${raw}\``,
|
|
92
|
+
show: {
|
|
93
|
+
text: this.preview(this.i - 5),
|
|
94
|
+
}
|
|
95
|
+
});
|
|
78
96
|
}
|
|
79
97
|
let init = this.i;
|
|
80
98
|
let ii = 0;
|
|
81
99
|
while (this.current === raw[ii]) {
|
|
82
|
-
this.advance(
|
|
100
|
+
this.advance({
|
|
101
|
+
msg: `While trying to consume: \`${raw}\``,
|
|
102
|
+
show: {
|
|
103
|
+
text: `\`${this.preview(init)}\``,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
83
106
|
ii++;
|
|
84
107
|
if (ii === raw.length)
|
|
85
108
|
return;
|
|
86
109
|
}
|
|
87
|
-
throw new
|
|
110
|
+
throw new DesmostError.UnexpectedInput({
|
|
111
|
+
msg: `Expected: \`${raw}\`, but found: \`${this.preview(init)}\``,
|
|
112
|
+
...error_data,
|
|
113
|
+
});
|
|
88
114
|
}
|
|
89
115
|
/**
|
|
90
116
|
* Attempt to consume `raw`, backtracking if `raw` was not found.
|
|
91
117
|
*/
|
|
92
|
-
|
|
118
|
+
try_eat(raw) {
|
|
93
119
|
let init = this.i;
|
|
94
120
|
let ii = 0;
|
|
95
121
|
while (this.current === raw[ii]) {
|
|
96
122
|
let r = this.try_advance();
|
|
97
123
|
if (r === NO_MATCH)
|
|
98
|
-
|
|
124
|
+
break;
|
|
99
125
|
ii++;
|
|
100
126
|
if (ii === raw.length)
|
|
101
127
|
return;
|
|
@@ -105,14 +131,25 @@ export class GenericParser {
|
|
|
105
131
|
this.i = init;
|
|
106
132
|
return NO_MATCH;
|
|
107
133
|
}
|
|
134
|
+
try_eat_identifier() {
|
|
135
|
+
let init = this.i;
|
|
136
|
+
while (/[a-zA-Z-]/.test(this.current ?? "")) {
|
|
137
|
+
let r = this.try_advance();
|
|
138
|
+
if (r === NO_MATCH) {
|
|
139
|
+
this.i = init;
|
|
140
|
+
return NO_MATCH;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return this.source.slice(init, this.i);
|
|
144
|
+
}
|
|
108
145
|
/**
|
|
109
|
-
* Consume 0 or more space characters.
|
|
146
|
+
* Consume 0 or more space or tab characters.
|
|
110
147
|
*/
|
|
111
|
-
|
|
148
|
+
eat_whitespace() {
|
|
112
149
|
/* NOTE: Callers should be able to assume this is safe to call even when at end of input, since it should just match 0 characters */
|
|
113
150
|
if (this.out_of_bounds())
|
|
114
151
|
return;
|
|
115
|
-
while (this.current ===
|
|
152
|
+
while (this.current === ' ' || this.current === '\t') {
|
|
116
153
|
this.advance();
|
|
117
154
|
}
|
|
118
155
|
}
|
|
@@ -121,21 +158,24 @@ export class GenericParser {
|
|
|
121
158
|
*
|
|
122
159
|
* Same as `.consume_spaces()`, but allows tabs and newlines.
|
|
123
160
|
*/
|
|
124
|
-
|
|
161
|
+
eat_newlines() {
|
|
125
162
|
/* NOTE: Callers should be able to assume this is safe to call even when at end of input, since it should just match 0 characters */
|
|
126
163
|
if (this.i >= this.length)
|
|
127
164
|
return;
|
|
128
|
-
while (this.current ===
|
|
129
|
-
|| this.current ===
|
|
130
|
-
|| this.current ===
|
|
165
|
+
while (this.current === ' '
|
|
166
|
+
|| this.current === '\n'
|
|
167
|
+
|| this.current === '\t') {
|
|
131
168
|
this.advance();
|
|
132
169
|
}
|
|
133
170
|
}
|
|
134
|
-
|
|
171
|
+
eat_end_of_block(error_data) {
|
|
135
172
|
if (this.i >= this.length)
|
|
136
173
|
return;
|
|
137
|
-
this.
|
|
138
|
-
this.
|
|
174
|
+
this.eat_whitespace();
|
|
175
|
+
this.eat("\n", {
|
|
176
|
+
msg: `Expected a newline at the end of a block, but found: \`${this.preview()}\``,
|
|
177
|
+
...error_data
|
|
178
|
+
});
|
|
139
179
|
}
|
|
140
180
|
}
|
|
141
181
|
//# sourceMappingURL=generic-parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic-parser.js","sourceRoot":"","sources":["../../src/parser/generic-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"generic-parser.js","sourceRoot":"","sources":["../../src/parser/generic-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
export declare const LINE: string;
|
|
2
|
+
/**
|
|
3
|
+
* Is `expr` a Desmos LaTeX expression (as opposed to a note or table)?
|
|
4
|
+
*/
|
|
5
|
+
export declare function is_latex(expr: Desmos.ExpressionState): expr is Desmos.Expression;
|
|
2
6
|
export declare function reversing<T>(items: ArrayLike<T>): Generator<T>;
|
|
3
7
|
export declare function paired<T>(items: Iterable<T>): Array<[left: T, right: T]>;
|
|
4
8
|
export declare function pairing<T>(items: Iterable<T>): Generator<[left: T, right: T]>;
|
|
5
9
|
export declare function chars(s: string, start?: number, stop?: number): string[];
|
|
6
10
|
export declare class Range {
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
/** The lower bound of the range (inclusive). */
|
|
12
|
+
readonly start: number;
|
|
13
|
+
/** The upper bound of the range (exclusive). */
|
|
14
|
+
readonly stop: number;
|
|
9
15
|
constructor(start: number, stop: number);
|
|
16
|
+
get length(): number;
|
|
10
17
|
map<T>(callback: (n: number) => T): Generator<T>;
|
|
11
18
|
}
|
|
12
19
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,QAAiB,CAAC;AAGnC,wBAAiB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAK/D;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAGxE;AAED,wBAAiB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAkB9E;AAGD,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAGxE;AAGD,qBAAa,KAAK;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,QAAiB,CAAC;AAGnC;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,CAGhF;AAGD,wBAAiB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAK/D;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAGxE;AAED,wBAAiB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAkB9E;AAGD,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAGxE;AAGD,qBAAa,KAAK;IAEjB,gDAAgD;IAChD,SAAgB,KAAK,EAAE,MAAM,CAAC;IAE9B,gDAAgD;IAChD,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAG5B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM;IAOb,IAAI,MAAM,IAAI,MAAM,CAEnB;IAEA,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;CAMjD"}
|
package/dist/utils.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export const LINE = '—'.repeat(10);
|
|
2
|
+
/**
|
|
3
|
+
* Is `expr` a Desmos LaTeX expression (as opposed to a note or table)?
|
|
4
|
+
*/
|
|
5
|
+
export function is_latex(expr) {
|
|
6
|
+
return (expr.type === undefined || expr.type === "expression");
|
|
7
|
+
}
|
|
2
8
|
export function* reversing(items) {
|
|
3
9
|
for (let i = items.length - 1; i >= 0; i--) {
|
|
4
10
|
yield items[i];
|
|
@@ -27,11 +33,16 @@ export function chars(s, start, stop) {
|
|
|
27
33
|
return new Range(start ?? 0, stop ?? s.length).map(i => s[i]).toArray();
|
|
28
34
|
}
|
|
29
35
|
export class Range {
|
|
36
|
+
/** The lower bound of the range (inclusive). */
|
|
30
37
|
start;
|
|
38
|
+
/** The upper bound of the range (exclusive). */
|
|
31
39
|
stop;
|
|
32
40
|
constructor(start, stop) {
|
|
33
|
-
this.start = start;
|
|
34
|
-
this.stop = stop;
|
|
41
|
+
this.start = Math.min(start, stop);
|
|
42
|
+
this.stop = Math.max(start, stop);
|
|
43
|
+
}
|
|
44
|
+
get length() {
|
|
45
|
+
return this.stop - this.start;
|
|
35
46
|
}
|
|
36
47
|
*map(callback) {
|
|
37
48
|
for (let n = this.start; n < this.stop; n++) {
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAGnC,MAAM,SAAS,CAAC,CAAC,SAAS,CAAI,KAAmB;IAEhD,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,MAAM,CAAI,KAAkB;IAE3C,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,SAAS,CAAC,CAAC,OAAO,CAAI,KAAkB;IAE7C,IAAI,QAAQ,GAAG,IAAI,CAAC;IAEpB,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACvB,QAAQ,GAAG,IAAI,CAAC;YAChB,SAAS;QACV,CAAC;aACI,CAAC;YACL,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACvB,QAAQ,GAAG,IAAI,CAAC;QACjB,CAAC;IACF,CAAC;IAED,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC;IACjB,CAAC;AACF,CAAC;AAGD,MAAM,UAAU,KAAK,CAAC,CAAS,EAAE,KAAc,EAAE,IAAa;IAE7D,OAAO,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AACzE,CAAC;AAGD,MAAM,OAAO,KAAK;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAGnC;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,IAA4B;IAEpD,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;AAChE,CAAC;AAGD,MAAM,SAAS,CAAC,CAAC,SAAS,CAAI,KAAmB;IAEhD,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,MAAM,CAAI,KAAkB;IAE3C,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,SAAS,CAAC,CAAC,OAAO,CAAI,KAAkB;IAE7C,IAAI,QAAQ,GAAG,IAAI,CAAC;IAEpB,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACvB,QAAQ,GAAG,IAAI,CAAC;YAChB,SAAS;QACV,CAAC;aACI,CAAC;YACL,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACvB,QAAQ,GAAG,IAAI,CAAC;QACjB,CAAC;IACF,CAAC;IAED,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC;IACjB,CAAC;AACF,CAAC;AAGD,MAAM,UAAU,KAAK,CAAC,CAAS,EAAE,KAAc,EAAE,IAAa;IAE7D,OAAO,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AACzE,CAAC;AAGD,MAAM,OAAO,KAAK;IAEjB,gDAAgD;IAChC,KAAK,CAAS;IAE9B,gDAAgD;IAChC,IAAI,CAAS;IAE7B,YACC,KAAa,EACb,IAAY;QAGZ,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAI,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;IAC/B,CAAC;IAED,CAAC,GAAG,CAAI,QAA0B;QAEjC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;IACF,CAAC;CACD"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "desmost",
|
|
3
3
|
"author": "Sup#2.0",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.10.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
|
|
7
7
|
"description": "A tiny DSL for compiling LaTeX to Desmos",
|
|
@@ -54,7 +54,10 @@
|
|
|
54
54
|
"test": "vitest run",
|
|
55
55
|
"testw": "vitest",
|
|
56
56
|
|
|
57
|
-
"check": "npx
|
|
57
|
+
"check": "npx tsc --noEmit -p tsconfig.build.json",
|
|
58
|
+
"lint": "npx oxlint src",
|
|
59
|
+
|
|
60
|
+
"doc": "cd ../.autodoc && rake",
|
|
58
61
|
|
|
59
62
|
"prepublishOnly": "nu build.nu pre-publish"
|
|
60
63
|
},
|
package/src/compiler/compile.ts
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DesmostCompiler, type DesmostDebug } from "./compiler";
|
|
2
2
|
|
|
3
3
|
import { type DesmostOptions, fill_defaults } from "../options";
|
|
4
|
-
import { DesmostParser, Ast } from "../parser";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/** Debug diagnostics returned from `compile()`. */
|
|
8
|
-
export interface DesmostDebug
|
|
9
|
-
{
|
|
10
|
-
duration: number;
|
|
11
|
-
num_blocks: number;
|
|
12
|
-
ast: Ast[];
|
|
13
|
-
}
|
|
14
4
|
|
|
15
5
|
|
|
16
6
|
/**
|
|
@@ -55,114 +45,11 @@ export function compile(
|
|
|
55
45
|
return;
|
|
56
46
|
}
|
|
57
47
|
|
|
58
|
-
let
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
var ast: Ast[] = [];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let parser = new DesmostParser(source, opts);
|
|
67
|
-
|
|
68
|
-
let errors: string[] = [];
|
|
69
|
-
|
|
70
|
-
/* To aggregate errors at the start, we need a target to retroactively inject errors into */
|
|
71
|
-
if (opts.place_errors === "start") {
|
|
72
|
-
desmos.setExpression({ id: "deferred-start", latex: " " }); // FIXME check if ` ` needed
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/* Keep track of whether we're still evaluating leading blank expressions, which might be ignored. */
|
|
76
|
-
let seen_non_blank = false;
|
|
77
|
-
|
|
78
|
-
/** The number of pending blank expressions to add. */
|
|
79
|
-
let pending_blanks: number = 0;
|
|
80
|
-
|
|
81
|
-
/* The compiler is lazy, parsing and evaluating one block at a time (as opposed to first parsing the entire AST). We don't need the whole AST, so this saves memory. */
|
|
82
|
-
/* NOTE: It also doesn't sacrifice performance, since `.setExpressions()` internally just calls `.setExpression()` in a loop anyway. Benchmarks in the frontend produce similar times for both, so there's no performance improvement. */
|
|
83
|
-
try {
|
|
84
|
-
while (true) {
|
|
85
|
-
let r = parser.parse_next();
|
|
86
|
-
if (r === null) break;
|
|
87
|
-
|
|
88
|
-
if (opts.debug) {
|
|
89
|
-
num_blocks!++;
|
|
90
|
-
ast!.push(r);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** An error message to leave for aggregation later. */
|
|
94
|
-
let defer: string | void = undefined;
|
|
95
|
-
|
|
96
|
-
switch (r.kind) {
|
|
97
|
-
case Ast.Kind.INCANTATION_INVOCATION:
|
|
98
|
-
defer = evaluate_global_incantation(r, desmos, opts);
|
|
99
|
-
break;
|
|
100
|
-
|
|
101
|
-
case Ast.Kind.EXPRESSION:
|
|
102
|
-
// @ts-expect-error: check type-narrows
|
|
103
|
-
if (r.data.latex === " ") {
|
|
104
|
-
if (opts.ignore_all_blanks) break;
|
|
105
|
-
if (!seen_non_blank && !opts.keep_leading_blanks) break;
|
|
106
|
-
pending_blanks++;
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
flush_pending_blanks(desmos, pending_blanks);
|
|
111
|
-
pending_blanks = 0;
|
|
112
|
-
|
|
113
|
-
seen_non_blank = true;
|
|
114
|
-
defer = evaluate_expr(r, desmos, opts);
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
case Ast.Kind.INVALID_INCANTATION:
|
|
119
|
-
defer = evaluate_error(r.error, desmos, opts);
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (defer !== undefined) {
|
|
124
|
-
errors.push(defer);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
catch (e) {
|
|
129
|
-
errors.push((e as Error).message);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (opts.keep_trailing_blanks) {
|
|
133
|
-
flush_pending_blanks(desmos, pending_blanks);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (errors.length > 0) {
|
|
137
|
-
let expr: Desmos.ExpressionState = {
|
|
138
|
-
type: "text",
|
|
139
|
-
text: errors.join("\n\n"),
|
|
140
|
-
};
|
|
48
|
+
let compiler = new DesmostCompiler(
|
|
49
|
+
desmos,
|
|
50
|
+
source,
|
|
51
|
+
fill_defaults(options),
|
|
52
|
+
);
|
|
141
53
|
|
|
142
|
-
|
|
143
|
-
case "start":
|
|
144
|
-
desmos.setExpression({ ...expr, id: "deferred-start" });
|
|
145
|
-
break;
|
|
146
|
-
case "end":
|
|
147
|
-
case "inline":
|
|
148
|
-
desmos.setExpression(expr);
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (opts.debug) {
|
|
154
|
-
return {
|
|
155
|
-
duration: performance.now() - t_init!,
|
|
156
|
-
num_blocks: num_blocks!,
|
|
157
|
-
ast: ast!,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
function flush_pending_blanks(desmos: Desmos.Calculator, count: number)
|
|
164
|
-
{
|
|
165
|
-
for (let i = 0; i < count; i++) {
|
|
166
|
-
desmos.setExpression({ latex: ` ` });
|
|
167
|
-
}
|
|
54
|
+
return compiler.compile();
|
|
168
55
|
}
|