mirror of
https://github.com/IvarK/AntimatterDimensionsSourceCode.git
synced 2024-11-12 23:23:20 +00:00
Untangle the automator
This commit is contained in:
parent
897364950d
commit
740d807373
@ -1,4 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { blockifyTextAutomator } from "@/core/automator";
|
||||||
import ModalWrapper from "@/components/modals/ModalWrapper";
|
import ModalWrapper from "@/components/modals/ModalWrapper";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -124,7 +125,7 @@ export default {
|
|||||||
if (this.isBlock) {
|
if (this.isBlock) {
|
||||||
const newTemplateBlock = {
|
const newTemplateBlock = {
|
||||||
name: `Template: ${this.name}`,
|
name: `Template: ${this.name}`,
|
||||||
blocks: AutomatorGrammar.blockifyTextAutomator(this.templateScript.script).blocks
|
blocks: blockifyTextAutomator(this.templateScript.script).blocks
|
||||||
};
|
};
|
||||||
AutomatorData.blockTemplates.push(newTemplateBlock);
|
AutomatorData.blockTemplates.push(newTemplateBlock);
|
||||||
GameUI.notify.info("Custom template block created");
|
GameUI.notify.info("Custom template block created");
|
||||||
@ -227,4 +228,4 @@ export default {
|
|||||||
.o-load-preset-button-margin {
|
.o-load-preset-button-margin {
|
||||||
margin-right: 0.3rem;
|
margin-right: 0.3rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { AutomatorBackend } from "@/core/globals";
|
import { hasCompilationErrors } from "@/core/automator";
|
||||||
|
|
||||||
import ModalWrapperChoice from "@/components/modals/ModalWrapperChoice";
|
import ModalWrapperChoice from "@/components/modals/ModalWrapperChoice";
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ export default {
|
|||||||
this.importedPresets = parsed.presets;
|
this.importedPresets = parsed.presets;
|
||||||
this.importedConstants = parsed.constants;
|
this.importedConstants = parsed.constants;
|
||||||
this.lineCount = this.scriptContent.split("\n").length;
|
this.lineCount = this.scriptContent.split("\n").length;
|
||||||
this.hasErrors = AutomatorGrammar.compile(this.scriptContent).errors.length !== 0;
|
this.hasErrors = hasCompilationErrors(this.scriptContent);
|
||||||
this.isValid = true;
|
this.isValid = true;
|
||||||
},
|
},
|
||||||
importSave() {
|
importSave() {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import draggable from "vuedraggable";
|
import draggable from "vuedraggable";
|
||||||
|
|
||||||
import AutomatorBlockSingleRow from "./AutomatorBlockSingleRow";
|
import AutomatorBlockSingleRow from "./AutomatorBlockSingleRow";
|
||||||
|
import { blockifyTextAutomator } from "@/core/automator";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AutomatorBlockEditor",
|
name: "AutomatorBlockEditor",
|
||||||
@ -104,13 +105,13 @@ export const BlockAutomator = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateEditor(scriptText) {
|
updateEditor(scriptText) {
|
||||||
const lines = AutomatorGrammar.blockifyTextAutomator(scriptText).blocks;
|
const lines = blockifyTextAutomator(scriptText).blocks;
|
||||||
this.lines = lines;
|
this.lines = lines;
|
||||||
return lines;
|
return lines;
|
||||||
},
|
},
|
||||||
|
|
||||||
hasUnparsableCommands(text) {
|
hasUnparsableCommands(text) {
|
||||||
const blockified = AutomatorGrammar.blockifyTextAutomator(text);
|
const blockified = blockifyTextAutomator(text);
|
||||||
return blockified.validatedBlocks !== blockified.visitedBlocks;
|
return blockified.validatedBlocks !== blockified.visitedBlocks;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { validateLine } from "@/core/automator";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AutomatorBlockSingleInput",
|
name: "AutomatorBlockSingleInput",
|
||||||
props: {
|
props: {
|
||||||
@ -194,10 +196,10 @@ export default {
|
|||||||
const clone = Object.assign({}, this.b);
|
const clone = Object.assign({}, this.b);
|
||||||
clone.nest = [];
|
clone.nest = [];
|
||||||
lines = BlockAutomator.parseLines([clone]);
|
lines = BlockAutomator.parseLines([clone]);
|
||||||
validator = AutomatorGrammar.validateLine(lines.join("\n"));
|
validator = validateLine(lines.join("\n"));
|
||||||
} else {
|
} else {
|
||||||
lines = BlockAutomator.parseLines([this.b]);
|
lines = BlockAutomator.parseLines([this.b]);
|
||||||
validator = AutomatorGrammar.validateLine(lines[0]);
|
validator = validateLine(lines[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Yes, the odd structure of this check is intentional. Something odd happens within parseLines under certain
|
// Yes, the odd structure of this check is intentional. Something odd happens within parseLines under certain
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { forbiddenConstantPatterns } from "@/core/automator";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AutomatorDefineSingleEntry",
|
name: "AutomatorDefineSingleEntry",
|
||||||
props: {
|
props: {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { AUTOMATOR_TYPE } from "@/core/automator/automator-backend";
|
||||||
import AutomatorBlocks from "./AutomatorBlocks";
|
import AutomatorBlocks from "./AutomatorBlocks";
|
||||||
import AutomatorButton from "./AutomatorButton";
|
import AutomatorButton from "./AutomatorButton";
|
||||||
import AutomatorDataTransferPage from "./AutomatorDataTransferPage";
|
import AutomatorDataTransferPage from "./AutomatorDataTransferPage";
|
||||||
@ -121,8 +122,8 @@ export default {
|
|||||||
created() {
|
created() {
|
||||||
this.on$(GAME_EVENT.GAME_LOAD, () => this.onGameLoad());
|
this.on$(GAME_EVENT.GAME_LOAD, () => this.onGameLoad());
|
||||||
this.on$(GAME_EVENT.AUTOMATOR_SAVE_CHANGED, () => this.onGameLoad());
|
this.on$(GAME_EVENT.AUTOMATOR_SAVE_CHANGED, () => this.onGameLoad());
|
||||||
this.updateCurrentScriptID();
|
this.on$(GAME_EVENT.AUTOMATOR_TYPE_CHANGED, () => this.openMatchingAutomatorTypeDocs());
|
||||||
this.updateScriptList();
|
this.onGameLoad();
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
this.fullScreen = false;
|
this.fullScreen = false;
|
||||||
@ -154,6 +155,7 @@ export default {
|
|||||||
onGameLoad() {
|
onGameLoad() {
|
||||||
this.updateCurrentScriptID();
|
this.updateCurrentScriptID();
|
||||||
this.updateScriptList();
|
this.updateScriptList();
|
||||||
|
this.fixAutomatorTypeDocs();
|
||||||
},
|
},
|
||||||
updateScriptList() {
|
updateScriptList() {
|
||||||
this.scripts = Object.values(player.reality.automator.scripts).map(script => ({
|
this.scripts = Object.values(player.reality.automator.scripts).map(script => ({
|
||||||
@ -185,6 +187,21 @@ export default {
|
|||||||
if (!this.isBlock && AutomatorTextUI.editor) AutomatorTextUI.editor.performLint();
|
if (!this.isBlock && AutomatorTextUI.editor) AutomatorTextUI.editor.performLint();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
fixAutomatorTypeDocs() {
|
||||||
|
const automator = player.reality.automator;
|
||||||
|
if (automator.currentInfoPane === AutomatorPanels.COMMANDS && automator.type === AUTOMATOR_TYPE.BLOCK) {
|
||||||
|
this.openMatchingAutomatorTypeDocs();
|
||||||
|
}
|
||||||
|
if (automator.currentInfoPane === AutomatorPanels.BLOCKS && automator.type === AUTOMATOR_TYPE.TEXT) {
|
||||||
|
this.openMatchingAutomatorTypeDocs();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openMatchingAutomatorTypeDocs() {
|
||||||
|
const automator = player.reality.automator;
|
||||||
|
automator.currentInfoPane = automator.type === AUTOMATOR_TYPE.BLOCK
|
||||||
|
? AutomatorPanels.BLOCKS
|
||||||
|
: AutomatorPanels.COMMANDS;
|
||||||
|
},
|
||||||
rename() {
|
rename() {
|
||||||
this.editingName = true;
|
this.editingName = true;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { blockifyTextAutomator } from "@/core/automator";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AutomatorModeSwitch",
|
name: "AutomatorModeSwitch",
|
||||||
data() {
|
data() {
|
||||||
@ -68,7 +70,7 @@ export default {
|
|||||||
(BlockAutomator.hasUnparsableCommands(currScript) || AutomatorData.currentErrors().length !== 0);
|
(BlockAutomator.hasUnparsableCommands(currScript) || AutomatorData.currentErrors().length !== 0);
|
||||||
|
|
||||||
if (player.options.confirmations.switchAutomatorMode && (hasTextErrors || AutomatorBackend.isRunning)) {
|
if (player.options.confirmations.switchAutomatorMode && (hasTextErrors || AutomatorBackend.isRunning)) {
|
||||||
const blockified = AutomatorGrammar.blockifyTextAutomator(currScript);
|
const blockified = blockifyTextAutomator(currScript);
|
||||||
|
|
||||||
// We explicitly pass in 0 for lostBlocks if converting from block to text since nothing is ever lost in that
|
// We explicitly pass in 0 for lostBlocks if converting from block to text since nothing is ever lost in that
|
||||||
// conversion direction
|
// conversion direction
|
||||||
|
@ -1,21 +1,4 @@
|
|||||||
import { AutomatorPanels } from "@/components/tabs/automator/AutomatorDocs";
|
import { compile } from "./compiler";
|
||||||
|
|
||||||
/** @abstract */
|
|
||||||
class AutomatorCommandInterface {
|
|
||||||
constructor(id) {
|
|
||||||
AutomatorCommandInterface.all[id] = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @abstract */
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
run(command) { throw new NotImplementedError(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
AutomatorCommandInterface.all = [];
|
|
||||||
|
|
||||||
export function AutomatorCommand(id) {
|
|
||||||
return AutomatorCommandInterface.all[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AUTOMATOR_COMMAND_STATUS = Object.freeze({
|
export const AUTOMATOR_COMMAND_STATUS = Object.freeze({
|
||||||
NEXT_INSTRUCTION: 0,
|
NEXT_INSTRUCTION: 0,
|
||||||
@ -150,7 +133,7 @@ export class AutomatorScript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compile() {
|
compile() {
|
||||||
this._compiled = AutomatorGrammar.compile(this.text).compiled;
|
this._compiled = compile(this.text).compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static create(name, content = "") {
|
static create(name, content = "") {
|
||||||
@ -215,7 +198,7 @@ export const AutomatorData = {
|
|||||||
},
|
},
|
||||||
recalculateErrors() {
|
recalculateErrors() {
|
||||||
const toCheck = this.currentScriptText();
|
const toCheck = this.currentScriptText();
|
||||||
this.cachedErrors = AutomatorGrammar.compile(toCheck).errors;
|
this.cachedErrors = compile(toCheck).errors;
|
||||||
this.cachedErrors.sort((a, b) => a.startLine - b.startLine);
|
this.cachedErrors.sort((a, b) => a.startLine - b.startLine);
|
||||||
},
|
},
|
||||||
currentErrors() {
|
currentErrors() {
|
||||||
@ -1012,18 +995,15 @@ export const AutomatorBackend = {
|
|||||||
// This saves the script after converting it.
|
// This saves the script after converting it.
|
||||||
BlockAutomator.parseTextFromBlocks();
|
BlockAutomator.parseTextFromBlocks();
|
||||||
player.reality.automator.type = AUTOMATOR_TYPE.TEXT;
|
player.reality.automator.type = AUTOMATOR_TYPE.TEXT;
|
||||||
if (player.reality.automator.currentInfoPane === AutomatorPanels.BLOCKS) {
|
|
||||||
player.reality.automator.currentInfoPane = AutomatorPanels.COMMANDS;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const toConvert = AutomatorTextUI.editor.getDoc().getValue();
|
const toConvert = AutomatorTextUI.editor.getDoc().getValue();
|
||||||
// Needs to be called to update the lines prop in the BlockAutomator object
|
// Needs to be called to update the lines prop in the BlockAutomator object
|
||||||
BlockAutomator.updateEditor(toConvert);
|
BlockAutomator.updateEditor(toConvert);
|
||||||
AutomatorBackend.saveScript(scriptID, toConvert);
|
AutomatorBackend.saveScript(scriptID, toConvert);
|
||||||
player.reality.automator.type = AUTOMATOR_TYPE.BLOCK;
|
player.reality.automator.type = AUTOMATOR_TYPE.BLOCK;
|
||||||
player.reality.automator.currentInfoPane = AutomatorPanels.BLOCKS;
|
|
||||||
}
|
}
|
||||||
AutomatorHighlighter.clearAllHighlightedLines();
|
AutomatorHighlighter.clearAllHighlightedLines();
|
||||||
|
EventHub.ui.dispatch(GAME_EVENT.AUTOMATOR_TYPE_CHANGED);
|
||||||
},
|
},
|
||||||
|
|
||||||
clearEditor() {
|
clearEditor() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { AutomatorGrammar } from "./parser";
|
import { lexer, tokenIds } from "./lexer";
|
||||||
import { AutomatorLexer } from "./lexer";
|
import { compile } from "./compiler";
|
||||||
|
import { parser } from "./parser";
|
||||||
|
|
||||||
function walkSuggestion(suggestion, prefix, output) {
|
function walkSuggestion(suggestion, prefix, output) {
|
||||||
const hasAutocomplete = suggestion.$autocomplete &&
|
const hasAutocomplete = suggestion.$autocomplete &&
|
||||||
@ -8,14 +8,14 @@ function walkSuggestion(suggestion, prefix, output) {
|
|||||||
const isUnlocked = suggestion.$unlocked ? suggestion.$unlocked() : true;
|
const isUnlocked = suggestion.$unlocked ? suggestion.$unlocked() : true;
|
||||||
if (hasAutocomplete && isUnlocked) output.add(suggestion.$autocomplete);
|
if (hasAutocomplete && isUnlocked) output.add(suggestion.$autocomplete);
|
||||||
for (const s of suggestion.categoryMatches) {
|
for (const s of suggestion.categoryMatches) {
|
||||||
walkSuggestion(AutomatorLexer.tokenIds[s], prefix, output);
|
walkSuggestion(tokenIds[s], prefix, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
CodeMirror.registerHelper("lint", "automato", (contents, _, editor) => {
|
CodeMirror.registerHelper("lint", "automato", (contents, _, editor) => {
|
||||||
const doc = editor.getDoc();
|
const doc = editor.getDoc();
|
||||||
const errors = AutomatorGrammar.compile(contents, true).errors;
|
const errors = compile(contents, true).errors;
|
||||||
return errors.map(e => ({
|
return errors.map(e => ({
|
||||||
message: e.info,
|
message: e.info,
|
||||||
severity: "error",
|
severity: "error",
|
||||||
@ -32,9 +32,9 @@ CodeMirror.registerHelper("hint", "anyword", editor => {
|
|||||||
while (start && /\w/u.test(line.charAt(start - 1)))--start;
|
while (start && /\w/u.test(line.charAt(start - 1)))--start;
|
||||||
const lineStart = line.slice(0, start);
|
const lineStart = line.slice(0, start);
|
||||||
const currentPrefix = line.slice(start, end);
|
const currentPrefix = line.slice(start, end);
|
||||||
const lineLex = AutomatorLexer.lexer.tokenize(lineStart);
|
const lineLex = lexer.tokenize(lineStart);
|
||||||
if (lineLex.errors.length > 0) return undefined;
|
if (lineLex.errors.length > 0) return undefined;
|
||||||
const rawSuggestions = AutomatorGrammar.parser.computeContentAssist("command", lineLex.tokens);
|
const rawSuggestions = parser.computeContentAssist("command", lineLex.tokens);
|
||||||
const suggestions = new Set();
|
const suggestions = new Set();
|
||||||
for (const s of rawSuggestions) {
|
for (const s of rawSuggestions) {
|
||||||
if (s.ruleStack[1] === "badCommand") continue;
|
if (s.ruleStack[1] === "badCommand") continue;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { AutomatorLexer } from "./lexer";
|
import { standardizeAutomatorValues, tokenMap as T } from "./lexer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: the $ shorthand for the parser object is required by Chevrotain. Don't mess with it.
|
* Note: the $ shorthand for the parser object is required by Chevrotain. Don't mess with it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const T = AutomatorLexer.tokenMap;
|
|
||||||
const presetSplitter = /name[ \t]+(.+$)/ui;
|
const presetSplitter = /name[ \t]+(.+$)/ui;
|
||||||
const idSplitter = /id[ \t]+(\d)/ui;
|
const idSplitter = /id[ \t]+(\d)/ui;
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
|
import { lexer, tokenMap as T } from "./lexer";
|
||||||
import { AutomatorCommands } from "./automator-commands";
|
import { AutomatorCommands } from "./automator-commands";
|
||||||
import { AutomatorGrammar } from "./parser";
|
import { parser } from "./parser";
|
||||||
import { AutomatorLexer } from "./lexer";
|
|
||||||
|
|
||||||
const parser = AutomatorGrammar.parser;
|
|
||||||
const BaseVisitor = parser.getBaseCstVisitorConstructorWithDefaults();
|
const BaseVisitor = parser.getBaseCstVisitorConstructorWithDefaults();
|
||||||
|
|
||||||
class Validator extends BaseVisitor {
|
class Validator extends BaseVisitor {
|
||||||
@ -20,7 +19,7 @@ class Validator extends BaseVisitor {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const lexResult = AutomatorLexer.lexer.tokenize(rawText);
|
const lexResult = lexer.tokenize(rawText);
|
||||||
const tokens = lexResult.tokens;
|
const tokens = lexResult.tokens;
|
||||||
parser.input = tokens;
|
parser.input = tokens;
|
||||||
this.parseResult = parser.script();
|
this.parseResult = parser.script();
|
||||||
@ -362,7 +361,6 @@ class Validator extends BaseVisitor {
|
|||||||
this.addError(ctx, "Missing comparison operator (<, >, <=, >=)", "Insert the appropriate comparison operator");
|
this.addError(ctx, "Missing comparison operator (<, >, <=, >=)", "Insert the appropriate comparison operator");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const T = AutomatorLexer.tokenMap;
|
|
||||||
if (ctx.ComparisonOperator[0].tokenType === T.OpEQ || ctx.ComparisonOperator[0].tokenType === T.EqualSign) {
|
if (ctx.ComparisonOperator[0].tokenType === T.OpEQ || ctx.ComparisonOperator[0].tokenType === T.EqualSign) {
|
||||||
this.addError(ctx, "Please use an inequality comparison (>, <, >=, <=)",
|
this.addError(ctx, "Please use an inequality comparison (>, <, >=, <=)",
|
||||||
"Comparisons cannot be done with equality, only with inequality operators");
|
"Comparisons cannot be done with equality, only with inequality operators");
|
||||||
@ -529,7 +527,7 @@ class Blockifier extends BaseVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function compile(input, validateOnly = false) {
|
export function compile(input, validateOnly = false) {
|
||||||
// The lexer and codemirror choke on the last line of the script, so we pad it with an invisible newline
|
// The lexer and codemirror choke on the last line of the script, so we pad it with an invisible newline
|
||||||
const script = `${input}\n `;
|
const script = `${input}\n `;
|
||||||
const validator = new Validator(script);
|
const validator = new Validator(script);
|
||||||
@ -542,9 +540,12 @@ function compile(input, validateOnly = false) {
|
|||||||
compiled,
|
compiled,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
AutomatorGrammar.compile = compile;
|
|
||||||
|
|
||||||
function blockifyTextAutomator(input) {
|
export function hasCompilationErrors(input) {
|
||||||
|
return compile(input, true).errors.length !== 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function blockifyTextAutomator(input) {
|
||||||
const validator = new Validator(input);
|
const validator = new Validator(input);
|
||||||
const blockifier = new Blockifier();
|
const blockifier = new Blockifier();
|
||||||
const blocks = blockifier.visit(validator.parseResult);
|
const blocks = blockifier.visit(validator.parseResult);
|
||||||
@ -584,11 +585,8 @@ function blockifyTextAutomator(input) {
|
|||||||
|
|
||||||
return { blocks, validatedBlocks, visitedBlocks };
|
return { blocks, validatedBlocks, visitedBlocks };
|
||||||
}
|
}
|
||||||
AutomatorGrammar.blockifyTextAutomator = blockifyTextAutomator;
|
|
||||||
|
|
||||||
function validateLine(input) {
|
export function validateLine(input) {
|
||||||
const validator = new Validator(input);
|
const validator = new Validator(input);
|
||||||
return validator;
|
return validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutomatorGrammar.validateLine = validateLine;
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
import "./compiler";
|
|
||||||
import "./automator-codemirror";
|
import "./automator-codemirror";
|
||||||
|
|
||||||
export { AutomatorGrammar } from "./parser";
|
export {
|
||||||
export { forbiddenConstantPatterns, standardizeAutomatorValues } from "./lexer";
|
forbiddenConstantPatterns
|
||||||
|
} from "./lexer";
|
||||||
|
|
||||||
|
export {
|
||||||
|
blockifyTextAutomator,
|
||||||
|
hasCompilationErrors,
|
||||||
|
validateLine
|
||||||
|
} from "./compiler";
|
||||||
|
|
||||||
|
export * from "./automator-backend";
|
||||||
|
export * from "./automator-points";
|
||||||
|
@ -342,7 +342,7 @@ const Pipe = createToken({ name: "Pipe", pattern: /\|/, label: "|" });
|
|||||||
const Dash = createToken({ name: "Dash", pattern: /-/, label: "-" });
|
const Dash = createToken({ name: "Dash", pattern: /-/, label: "-" });
|
||||||
|
|
||||||
// The order here is the order the lexer looks for tokens in.
|
// The order here is the order the lexer looks for tokens in.
|
||||||
const automatorTokens = [
|
export const automatorTokens = [
|
||||||
HSpace, StringLiteral, StringLiteralSingleQuote, Comment, EOL,
|
HSpace, StringLiteral, StringLiteralSingleQuote, Comment, EOL,
|
||||||
ComparisonOperator, ...tokenLists.ComparisonOperator,
|
ComparisonOperator, ...tokenLists.ComparisonOperator,
|
||||||
LCurly, RCurly, Comma, EqualSign, Pipe, Dash,
|
LCurly, RCurly, Comma, EqualSign, Pipe, Dash,
|
||||||
@ -362,19 +362,19 @@ RCurly.LABEL = "'}'";
|
|||||||
NumberLiteral.LABEL = "Number";
|
NumberLiteral.LABEL = "Number";
|
||||||
Comma.LABEL = "❟";
|
Comma.LABEL = "❟";
|
||||||
|
|
||||||
const lexer = new Lexer(automatorTokens, {
|
export const lexer = new Lexer(automatorTokens, {
|
||||||
positionTracking: "full",
|
positionTracking: "full",
|
||||||
ensureOptimizations: true
|
ensureOptimizations: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// The lexer uses an ID system that's separate from indices into the token array
|
// The lexer uses an ID system that's separate from indices into the token array
|
||||||
const tokenIds = [];
|
export const tokenIds = [];
|
||||||
for (const token of lexer.lexerDefinition) {
|
for (const token of lexer.lexerDefinition) {
|
||||||
tokenIds[token.tokenTypeIdx] = token;
|
tokenIds[token.tokenTypeIdx] = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use this while building up the grammar
|
// We use this while building up the grammar
|
||||||
const tokenMap = automatorTokens.mapToObject(e => e.name, e => e);
|
export const tokenMap = automatorTokens.mapToObject(e => e.name, e => e);
|
||||||
|
|
||||||
const automatorCurrencyNames = tokenLists.AutomatorCurrency.map(i => i.$autocomplete.toUpperCase());
|
const automatorCurrencyNames = tokenLists.AutomatorCurrency.map(i => i.$autocomplete.toUpperCase());
|
||||||
|
|
||||||
@ -405,12 +405,3 @@ export const forbiddenConstantPatterns = lexer.lexerDefinition
|
|||||||
.filter(p => !ignoredPatterns.includes(p.name))
|
.filter(p => !ignoredPatterns.includes(p.name))
|
||||||
.map(p => p.PATTERN.source)
|
.map(p => p.PATTERN.source)
|
||||||
.flatMap(p => ((p.includes("(") || p.includes(")")) ? p : p.split("[ \\t]+")));
|
.flatMap(p => ((p.includes("(") || p.includes(")")) ? p : p.split("[ \\t]+")));
|
||||||
|
|
||||||
export const AutomatorLexer = {
|
|
||||||
lexer,
|
|
||||||
tokens: automatorTokens,
|
|
||||||
tokenIds,
|
|
||||||
tokenMap,
|
|
||||||
standardizeAutomatorValues,
|
|
||||||
forbiddenConstantPatterns,
|
|
||||||
};
|
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
import { EOF, Parser } from "chevrotain";
|
import { EOF, Parser } from "chevrotain";
|
||||||
|
|
||||||
|
import { automatorTokens, tokenMap as T } from "./lexer";
|
||||||
import { AutomatorCommands } from "./automator-commands";
|
import { AutomatorCommands } from "./automator-commands";
|
||||||
import { AutomatorLexer } from "./lexer";
|
|
||||||
|
|
||||||
const T = AutomatorLexer.tokenMap;
|
|
||||||
|
|
||||||
// ----------------- parser -----------------
|
// ----------------- parser -----------------
|
||||||
class AutomatorParser extends Parser {
|
class AutomatorParser extends Parser {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(AutomatorLexer.tokens, {
|
super(automatorTokens, {
|
||||||
recoveryEnabled: true,
|
recoveryEnabled: true,
|
||||||
outputCst: true,
|
outputCst: true,
|
||||||
nodeLocationTracking: "full",
|
nodeLocationTracking: "full",
|
||||||
@ -130,10 +128,4 @@ class AutomatorParser extends Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parser = new AutomatorParser();
|
export const parser = new AutomatorParser();
|
||||||
|
|
||||||
export const AutomatorGrammar = {
|
|
||||||
parser,
|
|
||||||
// This field is filled in by automator-validate.js
|
|
||||||
validate: null,
|
|
||||||
};
|
|
||||||
|
@ -100,6 +100,7 @@ window.GAME_EVENT = {
|
|||||||
OFFLINE_CURRENCY_GAINED: "OFFLINE_CURRENCY_GAINED",
|
OFFLINE_CURRENCY_GAINED: "OFFLINE_CURRENCY_GAINED",
|
||||||
SAVE_CONVERTED_FROM_PREVIOUS_VERSION: "SAVE_CONVERTED_FROM_PREVIOUS_VERSION",
|
SAVE_CONVERTED_FROM_PREVIOUS_VERSION: "SAVE_CONVERTED_FROM_PREVIOUS_VERSION",
|
||||||
REALITY_FIRST_UNLOCKED: "REALITY_FIRST_UNLOCKED",
|
REALITY_FIRST_UNLOCKED: "REALITY_FIRST_UNLOCKED",
|
||||||
|
AUTOMATOR_TYPE_CHANGED: "AUTOMATOR_TYPE_CHANGED",
|
||||||
AUTOMATOR_SAVE_CHANGED: "AUTOMATOR_SAVE_CHANGED",
|
AUTOMATOR_SAVE_CHANGED: "AUTOMATOR_SAVE_CHANGED",
|
||||||
AUTOMATOR_CONSTANT_CHANGED: "AUTOMATOR_CONSTANT_CHANGED",
|
AUTOMATOR_CONSTANT_CHANGED: "AUTOMATOR_CONSTANT_CHANGED",
|
||||||
PELLE_STRIKE_UNLOCKED: "PELLE_STRIKE_UNLOCKED",
|
PELLE_STRIKE_UNLOCKED: "PELLE_STRIKE_UNLOCKED",
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
export * from "./glyph-effects";
|
export * from "./glyph-effects";
|
||||||
export * from "./player";
|
export * from "./player";
|
||||||
|
|
||||||
export * from "./automator/automator-backend";
|
|
||||||
export * from "./performance-stats";
|
export * from "./performance-stats";
|
||||||
export * from "./currency";
|
export * from "./currency";
|
||||||
export * from "./cache";
|
export * from "./cache";
|
||||||
@ -38,7 +37,6 @@ export * from "./celestials/pelle/game-end";
|
|||||||
export * from "./celestials/celestials";
|
export * from "./celestials/celestials";
|
||||||
|
|
||||||
export * from "./automator";
|
export * from "./automator";
|
||||||
export * from "./automator/automator-points";
|
|
||||||
|
|
||||||
export * from "./player-progress";
|
export * from "./player-progress";
|
||||||
export * from "./modal";
|
export * from "./modal";
|
||||||
|
Loading…
Reference in New Issue
Block a user