fix typing and generation-based matching
This commit is contained in:
		
							
								
								
									
										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, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user