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