Skip to content

Commit fc10367

Browse files
authored
refactor: rework the existing code with the new syntax parser (#246)
* refactor: some many changes * fix: fixing all the tests and regex * refactor: cleaning unused code
1 parent 9e5a9fc commit fc10367

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+9668
-2935
lines changed

src/graph/mermaid.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,11 @@ flowchart ${this.options.direction}`;
106106

107107
case NodeType.FunctionCall:
108108
const funcName = node.names.join(".");
109-
return createNodeInfo(`{{"${node.namespace}.${funcName}()${position}"}}`, `${node.namespace}.${funcName}()`);
109+
return createNodeInfo(`{{"${node.scope}.${funcName}()${position}"}}`, `${node.scope}.${funcName}()`);
110110

111111
case NodeType.ResourceReference:
112112
const resName = node.names.join(".");
113-
return createNodeInfo(`[/"${node.namespace}.${resName}${position}"/]`, `${node.namespace}.${resName}`);
113+
return createNodeInfo(`[/"${node.scope}.${resName}${position}"/]`, `${node.scope}.${resName}`);
114114

115115
default:
116116
return {

src/main.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
export * from "./data";
22
export * as Molang from "./molang";
3-
export * from "./types/defined";

src/molang/cache.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { OffsetWord } from "bc-minecraft-bedrock-types/lib/types";
2+
import { ExpressionNode, parseMolang } from "./syntax";
3+
4+
export class MolangSyntaxCache {
5+
private _data: Map<string, ExpressionNode[]>;
6+
7+
constructor() {
8+
this._data = new Map();
9+
}
10+
11+
build(code: OffsetWord): ExpressionNode[] | undefined {
12+
const exp = this._data.get(code.text);
13+
if (exp === undefined) {
14+
const r = parseMolang(code);
15+
this._data.set(code.text, r);
16+
return r;
17+
}
18+
19+
return exp;
20+
}
21+
22+
clear() {
23+
this._data.clear();
24+
}
25+
26+
entries() {
27+
return this._data.entries();
28+
}
29+
30+
syntaxes() {
31+
return this._data.keys();
32+
}
33+
34+
expressions() {
35+
return this._data.values();
36+
}
37+
}

src/molang/functions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ const molangRegexp =
2121
* @param data The string to check
2222
* @returns The type of molang
2323
*/
24-
export function IsMolangType(data: string): MolangType {
24+
export function isMolangType(data: string): MolangType {
2525
if (commandRegex.test(data)) return MolangType.command;
2626
if (eventRegex.test(data)) return MolangType.event;
2727
if (molangRegexp.test(data)) return MolangType.molang;
2828

2929
return MolangType.unknown;
3030
}
3131

32+
export function isMolang(data: string) {
33+
return molangRegexp.test(data);
34+
}
35+
3236
/**
3337
* Already assumes that the given data is of type MolangType.event
3438
* @param data The text to parse

src/molang/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
/* Auto generated */
2-
export * as Types from "./types/index";
32
export * from "./functions";
43
export * from "./molang-set";
5-
export * from "./regexp";
64
export * from "./syntax";
7-
export * from "./traverse";
5+
export * from "./traverse";

src/molang/molang-set.ts

Lines changed: 57 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,157 +1,79 @@
1-
import { DefinedUsing } from "../types/defined/defined-using";
2-
import { Using } from "../types/defined";
3-
import { Context, Queries, Temps, Variables, Geometries, Textures, Materials } from "./types";
4-
5-
/** Can either be a MolangSet or a MolangSet[] */
6-
export type MolangSetOptional = MolangSet | MolangFullSet;
1+
import { OffsetWord } from "bc-minecraft-bedrock-types/lib/types";
2+
import { MolangSyntaxCache } from "./cache";
3+
import { isMolang, isValidMolang } from "./functions";
4+
import { ExpressionNode, FunctionCallNode, NodeType, ResourceReferenceNode, VariableNode, walk } from "./syntax";
75

86
/** The interface for the molang set */
9-
export interface MolangSet {
10-
/** The set of contexts variables used*/
11-
contexts: Using<string>;
12-
/** The set of queries used */
13-
queries: Using<string>;
14-
/** The set of variables defined and used*/
15-
variables: DefinedUsing<string>;
16-
/** The set of temps variables defined and used*/
17-
temps: DefinedUsing<string>;
18-
}
7+
export class MolangSet {
8+
public cache = new MolangSyntaxCache();
9+
public assigned = new Set<ResourceReferenceNode | VariableNode>();
10+
public functions = new Set<FunctionCallNode>();
11+
public using = new Set<ResourceReferenceNode | VariableNode>();
1912

20-
/** The interface for the molang with the full set of data */
21-
export interface MolangFullSet extends MolangSet {
22-
/** The set of geometries used */
23-
geometries: DefinedUsing<string>;
24-
/** The set of materials used */
25-
materials: DefinedUsing<string>;
26-
/** The set of textures used */
27-
textures: DefinedUsing<string>;
28-
}
13+
constructor() {}
2914

30-
/** The namespace for the molang set */
31-
export namespace MolangSet {
3215
/**
33-
* Creates a new MolangSet
34-
* @returns A new MolangSet
16+
* adds the data from the molang code if it is valid molang
17+
* @param molang
3518
*/
36-
export function create(): MolangSet {
37-
return {
38-
queries: Using.create<string>(),
39-
variables: DefinedUsing.create<string>(),
40-
temps: DefinedUsing.create<string>(),
41-
contexts: Using.create<string>(),
42-
};
19+
addIf(molang: OffsetWord) {
20+
if (isValidMolang(molang.text)) this.add(molang);
4321
}
4422

4523
/**
46-
* Harvests molang data from the given object
47-
* @param object The object to harvest from
48-
* @returns The molang data
24+
*
25+
* @param molang
26+
* @returns
4927
*/
50-
export function harvest(object: any): MolangSet {
51-
const out = create();
52-
53-
Queries.getUsing(object, out.queries.using);
54-
Context.getUsing(object, out.contexts.using);
55-
56-
Variables.getUsing(object, out.variables.using);
57-
Variables.getDefined(object, out.variables.defined);
58-
59-
Temps.getUsing(object, out.temps.using);
60-
Temps.getDefined(object, out.temps.defined);
61-
62-
return out;
28+
add(molang: OffsetWord) {
29+
const exp = this.cache.build(molang);
30+
if (exp === undefined) return;
31+
exp.forEach((e) => walk(e, this.walkFn.bind(this)));
6332
}
64-
}
6533

66-
/** The namespace for the full molang set */
67-
export namespace MolangFullSet {
68-
/**
69-
* Creates a new MolangFullSet
70-
* @returns A new MolangFullSet
71-
*/
72-
export function create(): MolangFullSet {
73-
return {
74-
queries: Using.create<string>(),
75-
variables: DefinedUsing.create<string>(),
76-
temps: DefinedUsing.create<string>(),
77-
contexts: Using.create<string>(),
78-
geometries: DefinedUsing.empty(),
79-
materials: DefinedUsing.empty(),
80-
textures: DefinedUsing.empty(),
81-
};
82-
}
83-
84-
/**
85-
* Add the necessary properties to the given data set to the full MolangFullSet
86-
* @param data The data to add to
87-
*/
88-
export function upgrade(data: MolangSet): MolangFullSet {
89-
const out = data as MolangFullSet;
90-
91-
if (!DefinedUsing.is<string>(out.geometries)) out.geometries = DefinedUsing.empty();
92-
if (!DefinedUsing.is<string>(out.materials)) out.materials = DefinedUsing.empty();
93-
if (!DefinedUsing.is<string>(out.textures)) out.textures = DefinedUsing.empty();
94-
95-
return out;
96-
}
97-
98-
/**
99-
* Harvests molang data from the given object
100-
* @param object The object to harvest from
101-
*/
102-
export function harvest(object: object | string): MolangFullSet {
103-
const out = create();
104-
105-
Queries.getUsing(object, out.queries.using);
106-
Context.getUsing(object, out.contexts.using);
107-
108-
Variables.getUsing(object, out.variables.using);
109-
Variables.getDefined(object, out.variables.defined);
110-
111-
Temps.getUsing(object, out.temps.using);
112-
Temps.getDefined(object, out.temps.defined);
113-
114-
Textures.getUsing(object, out.textures.using);
115-
Geometries.getUsing(object, out.geometries.using);
116-
Materials.getUsing(object, out.materials.using);
117-
118-
return out;
34+
private walkFn(node: ExpressionNode): void {
35+
switch (node.type) {
36+
case NodeType.Assignment:
37+
this.checkAssigned(node.left);
38+
break;
39+
case NodeType.FunctionCall:
40+
this.functions.add(node);
41+
break;
42+
case NodeType.ResourceReference:
43+
case NodeType.Variable:
44+
if (this.assigned.has(node)) break;
45+
this.using.add(node);
46+
break;
47+
}
11948
}
12049

121-
/**
122-
* Merges the given MolangFullSet into the given MolangFullSet
123-
* @param value
124-
*/
125-
export function isEither(value: MolangSetOptional): value is MolangFullSet {
126-
const temp = value as MolangFullSet;
127-
128-
if (
129-
typeof temp.geometries === "object" &&
130-
typeof temp.materials === "object" &&
131-
typeof temp.textures === "object"
132-
) {
133-
return true;
50+
private checkAssigned(node: ExpressionNode): void {
51+
switch (node.type) {
52+
case NodeType.ResourceReference:
53+
case NodeType.Variable:
54+
this.assigned.add(node);
55+
break;
13456
}
135-
136-
return false;
13757
}
13858

139-
export function fromScript(script: { variables?: Record<string, string> }, addTo: MolangSet): void {
140-
if (script.variables) {
141-
const keys = Object.getOwnPropertyNames(script.variables);
59+
harvest(object: Record<string, any> | string, originalText: string) {
60+
if (typeof object === "string") {
61+
if (isMolang(object)) {
62+
this.add(OffsetWord.create(object, originalText.indexOf(object)));
63+
return;
64+
}
65+
}
14266

143-
for (let I = 0; I < keys.length; I++) {
144-
const key = keys[I];
145-
if (typeof key !== "string") {
146-
continue;
147-
}
148-
const index = key.indexOf(".");
149-
if (index < 0) {
150-
continue;
67+
for (const [, value] of Object.entries(object)) {
68+
if (typeof value === "string") {
69+
if (isMolang(value)) {
70+
this.add(OffsetWord.create(value, originalText.indexOf(value)));
15171
}
152-
const id = key.substring(index + 1);
153-
if (id && id.length > 0) {
154-
addTo.variables.defined.push(id);
72+
} else if (typeof value === "object") {
73+
if (Array.isArray(value)) {
74+
value.forEach((v) => this.harvest(v, originalText));
75+
} else {
76+
this.harvest(value, originalText);
15577
}
15678
}
15779
}

src/molang/regexp.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

0 commit comments

Comments
 (0)