desmost 0.8.0 → 0.8.2
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/compiler/compile.d.ts +25 -1
- package/dist/compiler/compile.d.ts.map +1 -1
- package/dist/compiler/compile.js +32 -2
- package/dist/compiler/compile.js.map +1 -1
- package/dist/compiler/evaluate.d.ts +11 -0
- package/dist/compiler/evaluate.d.ts.map +1 -1
- package/dist/compiler/evaluate.js +14 -0
- package/dist/compiler/evaluate.js.map +1 -1
- package/dist/compiler/format.d.ts +11 -0
- package/dist/compiler/format.d.ts.map +1 -1
- package/dist/compiler/format.js +14 -1
- package/dist/compiler/format.js.map +1 -1
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/index.js.map +1 -1
- package/dist/compiler/options.d.ts +79 -0
- package/dist/compiler/options.d.ts.map +1 -1
- package/dist/compiler/options.js +18 -11
- package/dist/compiler/options.js.map +1 -1
- package/dist/decompiler/decompile.d.ts +11 -0
- package/dist/decompiler/decompile.d.ts.map +1 -1
- package/dist/decompiler/decompile.js +11 -0
- package/dist/decompiler/decompile.js.map +1 -1
- package/dist/decompiler/emit.d.ts +6 -0
- package/dist/decompiler/emit.d.ts.map +1 -1
- package/dist/decompiler/emit.js +9 -0
- package/dist/decompiler/emit.js.map +1 -1
- package/dist/decompiler/extract.d.ts +9 -0
- package/dist/decompiler/extract.d.ts.map +1 -1
- package/dist/decompiler/extract.js +11 -1
- package/dist/decompiler/extract.js.map +1 -1
- package/dist/decompiler/format.js +6 -3
- package/dist/decompiler/format.js.map +1 -1
- package/dist/desmos.d.ts +3 -0
- package/dist/desmos.d.ts.map +1 -1
- package/dist/desmos.js +3 -0
- package/dist/desmos.js.map +1 -1
- package/dist/errors.d.ts +18 -4
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +13 -1
- 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/index.internal.js +1 -1
- package/dist/index.internal.js.map +1 -1
- package/dist/magic/expr/latex.js +1 -0
- package/dist/magic/expr/latex.js.map +1 -1
- package/dist/magic/expr/text.js +1 -0
- package/dist/magic/expr/text.js.map +1 -1
- package/dist/magic/global/desmos.d.ts +3 -1
- package/dist/magic/global/desmos.d.ts.map +1 -1
- package/dist/magic/global/desmos.js.map +1 -1
- package/dist/magic/incantation.d.ts +44 -0
- package/dist/magic/incantation.d.ts.map +1 -1
- package/dist/magic/incantation.js +38 -0
- package/dist/magic/incantation.js.map +1 -1
- package/dist/magic/index.d.ts +7 -0
- package/dist/magic/index.d.ts.map +1 -1
- package/dist/magic/index.js +7 -0
- package/dist/magic/index.js.map +1 -1
- package/dist/magic/local/anim.js +1 -0
- package/dist/magic/local/anim.js.map +1 -1
- package/dist/magic/local/label.js +1 -0
- package/dist/magic/local/label.js.map +1 -1
- package/dist/magic/local/slider.js +1 -0
- package/dist/magic/local/slider.js.map +1 -1
- package/dist/parser/ast.d.ts +9 -0
- package/dist/parser/ast.d.ts.map +1 -1
- package/dist/parser/ast.js +1 -0
- package/dist/parser/ast.js.map +1 -1
- package/dist/parser/desmost-parser.d.ts +101 -1
- package/dist/parser/desmost-parser.d.ts.map +1 -1
- package/dist/parser/desmost-parser.js +128 -1
- package/dist/parser/desmost-parser.js.map +1 -1
- package/dist/parser/generic-parser.d.ts +47 -0
- package/dist/parser/generic-parser.d.ts.map +1 -1
- package/dist/parser/generic-parser.js +50 -0
- package/dist/parser/generic-parser.js.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js.map +1 -1
- package/package.json +5 -2
- package/src/compiler/format.ts +6 -1
- package/src/compiler/index.ts +0 -7
- package/src/compiler/options.ts +18 -15
- package/src/compiler/readme.md +5 -0
- package/src/decompiler/readme.md +34 -0
- package/src/errors.ts +7 -7
- package/src/index.internal.ts +1 -1
- package/src/magic/global/desmos.ts +4 -1
- package/src/magic/readme.md +5 -0
- package/src/parser/ast.ts +3 -3
- package/src/parser/index.ts +0 -4
- package/src/parser/readme.md +21 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic-parser.js","sourceRoot":"","sources":["../../src/parser/generic-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAIzD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;IAClC,IAAI;CACJ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"generic-parser.js","sourceRoot":"","sources":["../../src/parser/generic-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC"}
|
package/dist/parser/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "desmost",
|
|
3
3
|
"author": "Sup#2.0",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
|
|
7
7
|
"description": "A tiny DSL for compiling LaTeX to Desmos",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
|
|
21
21
|
"type": "module",
|
|
22
|
+
"sideEffects": false,
|
|
22
23
|
"files": [
|
|
23
24
|
"./src/",
|
|
24
25
|
"./dist/",
|
|
@@ -51,7 +52,9 @@
|
|
|
51
52
|
|
|
52
53
|
"check": "npx oxlint src",
|
|
53
54
|
|
|
54
|
-
"
|
|
55
|
+
"doc": "cd ../.autodoc && rake",
|
|
56
|
+
|
|
57
|
+
"prepublishOnly": "npm run test && npm run doc && npm run buildx"
|
|
55
58
|
},
|
|
56
59
|
|
|
57
60
|
"dependencies":
|
package/src/compiler/format.ts
CHANGED
|
@@ -41,7 +41,12 @@ export function prettify_latex(latex: string): string
|
|
|
41
41
|
latex = latex.replaceAll(/(:|,)(?!\\ ) */g, "$1\\ ");
|
|
42
42
|
|
|
43
43
|
latex = latex.replaceAll(
|
|
44
|
-
/(?<=[^\w]|^)\\?(mean|median|count|total|repeat|join|sort|shuffle|unique|mod|ceil|floor|round|sign) ?(?=\(|\\left\()/g,
|
|
44
|
+
/(?<=[^\w]|^)\\?(length|mean|median|count|total|repeat|join|sort|shuffle|unique|mod|ceil|floor|round|sign) ?(?=\(|\\left\()/g,
|
|
45
|
+
"\\operatorname{$1}"
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
latex = latex.replaceAll(
|
|
49
|
+
/\s(and|or)\s/g,
|
|
45
50
|
"\\operatorname{$1}"
|
|
46
51
|
);
|
|
47
52
|
|
package/src/compiler/index.ts
CHANGED
package/src/compiler/options.ts
CHANGED
|
@@ -85,24 +85,27 @@ export interface DesmostOptions
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
|
|
88
|
+
export const DEFAULT_OPTIONS =
|
|
89
|
+
{
|
|
90
|
+
errors: "surface",
|
|
91
|
+
place_errors: "inline",
|
|
92
|
+
error_prefix: "[DESMOST ERROR]\n",
|
|
93
|
+
prettify: true,
|
|
94
|
+
ignore_comments: false,
|
|
95
|
+
ignore_all_blanks: false,
|
|
96
|
+
keep_leading_blanks: false,
|
|
97
|
+
keep_trailing_blanks: false,
|
|
98
|
+
debug: false,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
|
|
88
102
|
/**
|
|
89
103
|
* Fill in `options` with Desmost's defaults to produce a complete `DesmostOptions` config.
|
|
90
104
|
*/
|
|
91
105
|
export function fill_defaults(options: Partial<DesmostOptions> | undefined): Required<DesmostOptions>
|
|
92
106
|
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
out.error_prefix ??= "[DESMOST ERROR]\n";
|
|
98
|
-
|
|
99
|
-
out.prettify ??= true;
|
|
100
|
-
|
|
101
|
-
out.ignore_comments ??= false;
|
|
102
|
-
out.ignore_all_blanks ??= false;
|
|
103
|
-
out.keep_leading_blanks ??= false;
|
|
104
|
-
out.keep_trailing_blanks ??= false;
|
|
105
|
-
out.debug ??= false;
|
|
106
|
-
|
|
107
|
-
return out as Required<DesmostOptions>;
|
|
107
|
+
return {
|
|
108
|
+
...DEFAULT_OPTIONS,
|
|
109
|
+
...options,
|
|
110
|
+
} as Required<DesmostOptions>;
|
|
108
111
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Decompiler
|
|
2
|
+
|
|
3
|
+
This module implements the Desmos -> Desmost decompiler.
|
|
4
|
+
|
|
5
|
+
This decompiles a `Desmos.Calculator` instance into the *minimal* raw Desmost source code that could *completely* reproduce the calculator state. Decompilation happens through several lowering stages:
|
|
6
|
+
|
|
7
|
+
```hs
|
|
8
|
+
Desmos.Calculator -> object[] -> Ast[] -> string
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The first 2 stages are closely intertwined, so they're merged into one `desmos_to_ast()` function.
|
|
12
|
+
|
|
13
|
+
Technically it'd be more performant to directly emit instead of constructing the intermediate AST, but doing it this way means:
|
|
14
|
+
|
|
15
|
+
- We can access the AST for debug information (in Playground)
|
|
16
|
+
- We can diff the AST instead of the source when doing incremenetal decompilation in future
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## Extracting the AST
|
|
20
|
+
`Desmos.Calculator -> object[] -> Ast[]`
|
|
21
|
+
|
|
22
|
+
We need to not only extract the expressions in the editor with `.getExpressions()`, but also other global calculator state like `.graphpaperBounds`.
|
|
23
|
+
|
|
24
|
+
We then transform those raw objects into `Ast` nodes.
|
|
25
|
+
|
|
26
|
+
The main challenge here is removing unnecessary noise - we need to pick up on fields that *wouldn't* be covered by defaults and include them as incantations, but ignore everything else to avoid producing humongous `/desmos{ p, q, r, s, t }` slop.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## Emitting the Source
|
|
30
|
+
`Ast[] -> string`
|
|
31
|
+
|
|
32
|
+
The main concern here is ensuring the emitted source code looks like something the user would write, which means nice formatting, line breaks, spaces, indentatino, etc.
|
|
33
|
+
|
|
34
|
+
Once we try implementing incremental decompilation, this will be the hardest part because we need to reconcile changes with the user's existing source code, respecting where their formatting deviates from the autogenerated output (currently their entire source code may be shuffled around when decompiling, which is terrible UX).
|
package/src/errors.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/** The parser failed to parse something (usually during speculative parsing), which only results in internal backtracking. */
|
|
2
|
+
export const NO_MATCH = Symbol("no-match");
|
|
3
|
+
|
|
4
|
+
/** The compiler encountered a non-fatal recoverable failure (usually during speculative parsing), which only results in internal backtracking. */
|
|
5
|
+
export type NoMatch = typeof NO_MATCH & { readonly __brand?: unique symbol };
|
|
6
|
+
|
|
7
|
+
|
|
1
8
|
/**
|
|
2
9
|
* The compiler encountered a fatal unrecoverable error, which will reach the end user.
|
|
3
10
|
*
|
|
@@ -28,12 +35,5 @@ export namespace UnrecoverableError
|
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
|
|
31
|
-
/** The parser failed to parse something (usually during speculative parsing), which only results in internal backtracking. */
|
|
32
|
-
export const NO_MATCH = Symbol("no-match");
|
|
33
|
-
|
|
34
|
-
/** The compiler encountered a non-fatal recoverable failure (usually during speculative parsing), which only results in internal backtracking. */
|
|
35
|
-
export type NoMatch = typeof NO_MATCH & { readonly __brand?: unique symbol };
|
|
36
|
-
|
|
37
|
-
|
|
38
38
|
/** Indicates that a function may throw an `UnrecoverableError`. */
|
|
39
39
|
export type Unrecoverable<Result> = Result | Result & { readonly __brand?: unique symbol };
|
package/src/index.internal.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Incantation, ArgIncantation, type GLOBAL } from "../incantation";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
type DesmosSettings = Desmos.GraphConfiguration & Desmos.GraphSettings
|
|
5
|
+
|
|
6
|
+
|
|
4
7
|
export class DesmosIncantation extends ArgIncantation<GLOBAL>
|
|
5
8
|
{
|
|
6
9
|
override readonly description
|
|
@@ -12,7 +15,7 @@ export class DesmosIncantation extends ArgIncantation<GLOBAL>
|
|
|
12
15
|
|
|
13
16
|
override apply(
|
|
14
17
|
target: Desmos.Calculator,
|
|
15
|
-
data?:
|
|
18
|
+
data?: DesmosSettings,
|
|
16
19
|
): void
|
|
17
20
|
{
|
|
18
21
|
if (data != undefined) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Incantations
|
|
2
|
+
|
|
3
|
+
This module implements how incantations are represented, and the individual logic for every incantation in Desmost.
|
|
4
|
+
|
|
5
|
+
Each incantation is defined in its own file as a class deriving from `ArgIncantation` or `Incantation`. They can then implement whatever logic they require for `apply()` and `evaluate_arg()`.
|
package/src/parser/ast.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Incantation, ArgIncantation } from "../magic";
|
|
|
4
4
|
|
|
5
5
|
export namespace Ast
|
|
6
6
|
{
|
|
7
|
-
/** What kind of
|
|
7
|
+
/** What kind of AST node this is. */
|
|
8
8
|
export enum Kind
|
|
9
9
|
{
|
|
10
10
|
EXPRESSION = "Expression",
|
|
@@ -41,7 +41,7 @@ export namespace Ast
|
|
|
41
41
|
/**
|
|
42
42
|
* An invalid invantation invocation that raised an error when parsed.
|
|
43
43
|
*
|
|
44
|
-
* This will be propogated to the user as an extra Desmos text expression (unless they have `errors:
|
|
44
|
+
* This will be propogated to the user as an extra Desmos text expression (unless they have `errors: "suppress"` configured).
|
|
45
45
|
*/
|
|
46
46
|
export interface InvalidInvocation
|
|
47
47
|
{
|
|
@@ -52,7 +52,7 @@ export namespace Ast
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/** An abstract object produced by
|
|
55
|
+
/** An abstract object produced by the parser. */
|
|
56
56
|
export type Ast =
|
|
57
57
|
| Ast.Expression
|
|
58
58
|
| Ast.IncantationInvocation
|
package/src/parser/index.ts
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Parser
|
|
2
|
+
|
|
3
|
+
This module implements the Desmost -> AST parser.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Structure
|
|
7
|
+
|
|
8
|
+
The parser is split into `DesmostParser` and `GenericParser`.
|
|
9
|
+
|
|
10
|
+
`GenericParser` implements the skeleton common to any parser, while `DesmostParser` implements Desmost-specific logic. (Think of `GenericParser` as the library, while `DesmostParser` is the application).
|
|
11
|
+
|
|
12
|
+
The parser is stateful, tracking its current position in the source text with its `.i` field.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Backtracking
|
|
16
|
+
|
|
17
|
+
The parser often backtracks. For instance, if the source code is `/unknown`, the parser will first check if it's a global incantation with `try_parse_global_incantation()`, scanning through `/desmos`, `/viewport`, etc. Since none match, it backtracks and returns `NO_MATCH`.
|
|
18
|
+
|
|
19
|
+
It then tries `try_parse_local_incantation()`, again backtracking because none match. Finally, it falls back to `parse_line()`, producing a LaTeX expression `/unknown`.
|
|
20
|
+
|
|
21
|
+
Methods that may backtrack start with `try_` and may return `NoMatch`.
|