fix typing and generation-based matching
This commit is contained in:
parent
6d92cb4deb
commit
70141b162f
67
calc.js
67
calc.js
@ -1,12 +1,13 @@
|
|||||||
import calc, {
|
import {
|
||||||
calculate,
|
calculate,
|
||||||
Generations,
|
|
||||||
Field,
|
Field,
|
||||||
|
Generations,
|
||||||
Move,
|
Move,
|
||||||
Pokemon,
|
Pokemon,
|
||||||
|
Result,
|
||||||
} from "@ajhyndman/smogon-calc";
|
} from "@ajhyndman/smogon-calc";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import chev, { Lexer } from "chevrotain";
|
import { createToken, Lexer } from "chevrotain";
|
||||||
|
|
||||||
const gen = Generations.get(9);
|
const gen = Generations.get(9);
|
||||||
|
|
||||||
@ -16,65 +17,61 @@ const gen = Generations.get(9);
|
|||||||
* @returns {Lexer}
|
* @returns {Lexer}
|
||||||
*/
|
*/
|
||||||
function buildLexer() {
|
function buildLexer() {
|
||||||
const Boost = chev.createToken({ name: "Boost", pattern: /[+-]\d+/ });
|
const Boost = createToken({ name: "Boost", pattern: /[+-]\d+/ });
|
||||||
const EV = chev.createToken({ name: "EV", pattern: /\d+[+-]?/ });
|
const EV = createToken({ name: "EV", pattern: /\d+[+-]?/ });
|
||||||
const Stat = chev.createToken({
|
const Stat = createToken({
|
||||||
name: "Stat",
|
name: "Stat",
|
||||||
pattern: /HP|Atk|Def|SpA|SpD|Spe/,
|
pattern: /HP|Atk|Def|SpA|SpD|Spe/,
|
||||||
});
|
});
|
||||||
|
|
||||||
const Item = chev.createToken({
|
const Item = createToken({
|
||||||
name: "Item",
|
name: "Item",
|
||||||
pattern: new RegExp(calc.ITEMS.flatMap((gen) => gen).join("|")),
|
pattern: new RegExp([...gen.items].map((i) => i.name).join("|")),
|
||||||
});
|
});
|
||||||
const Ability = chev.createToken({
|
const Ability = createToken({
|
||||||
name: "Ability",
|
name: "Ability",
|
||||||
pattern: new RegExp(calc.ABILITIES.flatMap((gen) => gen).join("|")),
|
pattern: new RegExp([...gen.abilities].map((a) => a.name).join("|")),
|
||||||
});
|
});
|
||||||
|
|
||||||
const Pokemon = chev.createToken({
|
const Pokemon = createToken({
|
||||||
name: "Pokemon",
|
name: "Pokemon",
|
||||||
pattern: new RegExp(
|
pattern: new RegExp([...gen.species].map((s) => s.name).join("|")),
|
||||||
calc.SPECIES.flatMap((gen) => Object.keys(gen)).join("|")
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
const Move = chev.createToken({
|
const Move = createToken({
|
||||||
name: "Move",
|
name: "Move",
|
||||||
pattern: new RegExp(
|
pattern: new RegExp([...gen.moves].map((m) => m.name).join("|")),
|
||||||
calc.MOVES.flatMap((gen) => Object.keys(gen)).join("|")
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const whitespace = chev.createToken({
|
const whitespace = createToken({
|
||||||
name: "Whitespace",
|
name: "Whitespace",
|
||||||
pattern: /\s+/,
|
pattern: /\s+/,
|
||||||
group: Lexer.SKIPPED,
|
group: Lexer.SKIPPED,
|
||||||
});
|
});
|
||||||
const div = chev.createToken({
|
const div = createToken({
|
||||||
name: "div",
|
name: "div",
|
||||||
pattern: "/",
|
pattern: "/",
|
||||||
group: Lexer.SKIPPED,
|
group: Lexer.SKIPPED,
|
||||||
});
|
});
|
||||||
const vs = chev.createToken({
|
const vs = createToken({
|
||||||
name: "vs",
|
name: "vs",
|
||||||
pattern: /vs\.?/,
|
pattern: /vs\.?/,
|
||||||
});
|
});
|
||||||
|
|
||||||
const terrainEnter = chev.createToken({
|
const terrainEnter = createToken({
|
||||||
name: "terrainEnter",
|
name: "terrainEnter",
|
||||||
pattern: "in",
|
pattern: "in",
|
||||||
push_mode: "terrain_mode",
|
push_mode: "terrain_mode",
|
||||||
});
|
});
|
||||||
const Weather = chev.createToken({
|
const Weather = createToken({
|
||||||
name: "Weather",
|
name: "Weather",
|
||||||
pattern: /Sun|Rain|Sand|Snow/,
|
pattern: /Sun|Rain|Sand|Snow/,
|
||||||
});
|
});
|
||||||
const Terrain = chev.createToken({
|
const Terrain = createToken({
|
||||||
name: "Terrain",
|
name: "Terrain",
|
||||||
pattern: /(Electric|Grassy|Misty|Psychic) Terrain/,
|
pattern: /(Electric|Grassy|Misty|Psychic) Terrain/,
|
||||||
});
|
});
|
||||||
|
|
||||||
const screenEnter = chev.createToken({
|
const screenEnter = createToken({
|
||||||
name: "screenEnter",
|
name: "screenEnter",
|
||||||
pattern: "through",
|
pattern: "through",
|
||||||
push_mode: "screen_mode",
|
push_mode: "screen_mode",
|
||||||
@ -117,7 +114,7 @@ function* iterate(arr) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} type token type
|
* @param {string} type token type
|
||||||
* @param {chev.IToken} token token
|
* @param {import("chevrotain").IToken} token token
|
||||||
* @return {string} matched token
|
* @return {string} matched token
|
||||||
*/
|
*/
|
||||||
function unwrapToken(type, token) {
|
function unwrapToken(type, token) {
|
||||||
@ -155,7 +152,7 @@ const NEG_NATURES = {
|
|||||||
* through Light Screen
|
* through Light Screen
|
||||||
*
|
*
|
||||||
* @param {string} line textual line
|
* @param {string} line textual line
|
||||||
* @return {calc.Result} calculation result
|
* @return {Result} calculation result
|
||||||
*/
|
*/
|
||||||
function parseAndCalculate(line) {
|
function parseAndCalculate(line) {
|
||||||
const lexer = buildLexer();
|
const lexer = buildLexer();
|
||||||
@ -169,14 +166,14 @@ function parseAndCalculate(line) {
|
|||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
var defender;
|
var defender;
|
||||||
|
|
||||||
/** @type {calc.State.Pokemon} */
|
/** @type {import("@ajhyndman/smogon-calc").State.Pokemon} */
|
||||||
var attackerOpts = {};
|
var attackerOpts = {};
|
||||||
/** @type {calc.State.Pokemon} */
|
/** @type {import("@ajhyndman/smogon-calc").State.Pokemon} */
|
||||||
var defenderOpts = {};
|
var defenderOpts = {};
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
var move;
|
var move;
|
||||||
/** @type {calc.State.Field} */
|
/** @type {import("@ajhyndman/smogon-calc").State.Field} */
|
||||||
var field = {};
|
var field = {};
|
||||||
|
|
||||||
// Tokenising state.
|
// Tokenising state.
|
||||||
@ -216,7 +213,7 @@ function parseAndCalculate(line) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "Stat":
|
case "Stat":
|
||||||
throw Error("Impossibel state: bare Stat");
|
throw Error("Impossible state: bare Stat");
|
||||||
case "Item":
|
case "Item":
|
||||||
opts().item = unwrapToken("Item", item);
|
opts().item = unwrapToken("Item", item);
|
||||||
break;
|
break;
|
||||||
@ -269,9 +266,11 @@ function parseAndCalculate(line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pre-checking before the calculator throws unreadable errors.
|
// Pre-checking before the calculator throws unreadable errors.
|
||||||
if (!gen.species.get(attacker)) throw Error(`No species ${attacker}`);
|
if (!gen.species.get(attacker.toLowerCase()))
|
||||||
if (!gen.species.get(defender)) throw Error(`No species ${attacker}`);
|
throw Error(`No species named ${attacker}`);
|
||||||
if (!gen.moves.get(move)) throw Error(`No move ${move}`);
|
if (!gen.species.get(defender.toLowerCase()))
|
||||||
|
throw Error(`No species named ${defender}`);
|
||||||
|
if (!gen.moves.get(move.toLowerCase())) throw Error(`No move named ${move}`);
|
||||||
|
|
||||||
return calculate(
|
return calculate(
|
||||||
gen,
|
gen,
|
||||||
|
Loading…
Reference in New Issue
Block a user