From 8f13574ee771b6e9a877e9e7b5801aaefa710f51 Mon Sep 17 00:00:00 2001 From: Mari Date: Mon, 18 Sep 2023 15:10:22 -0700 Subject: [PATCH] couple more bits of parsing --- src/grammar/grammar.ohm | 10 ++++ src/grammar/parser.ts | 114 +++++++++++++++++++++++++++++++--------- src/model/Messages.ts | 10 ++++ 3 files changed, 109 insertions(+), 25 deletions(-) diff --git a/src/grammar/grammar.ohm b/src/grammar/grammar.ohm index b7e66c8..f19ca66 100644 --- a/src/grammar/grammar.ohm +++ b/src/grammar/grammar.ohm @@ -167,6 +167,16 @@ FabulaDSL { FailReason = avoid|dodge|miss|resist|fail|block|parry FailOperation = Operands colon FailReason + allySide = caseInsensitive<"allies">|caseInsensitive<"ally"> + |caseInsensitive<"friendly">|caseInsensitive<"friends">|caseInsensitive<"friend"> + |caseInsensitive<"party">|caseInsensitive<"pcs">|caseInsensitive<"pc"> + |caseInsensitive<"heroes">|caseInsensitive<"hero"> + enemySide = caseInsensitive<"villains">|caseInsensitive<"villain"> + |caseInsensitive<"enemies">|caseInsensitive<"enemy"> + |caseInsensitive<"npcs">|caseInsensitive<"npc"> + |caseInsensitive<"opponents">|caseInsensitive<"opponent">|caseInsensitive<"opposed"> + characterSide = allySide|enemySide + printOperator = ">" PrintOperation = printOperator textToEndOfLine PrintOperationWithOperands = Operands colon printOperator textToEndOfLine diff --git a/src/grammar/parser.ts b/src/grammar/parser.ts index 3790f7b..e4f07bb 100644 --- a/src/grammar/parser.ts +++ b/src/grammar/parser.ts @@ -2,48 +2,52 @@ import grammar from "./grammar.ohm-bundle"; import { Affinity, ElementalType, + FailReason, MarkdownContext, MarkdownOutput, MeteredResource, NumberSign, - Operands, OperandsFrom, + Operands, + OperandsFrom, ParseContext, - Resource, Source, Target, + Resource, + Source, + Target, UnmeteredResource, } from "../model/Messages"; -import {Iter, IterationNode, Node, NonterminalNode, TerminalNode} from "ohm-js"; +import {IterationNode, Node, NonterminalNode, TerminalNode} from "ohm-js"; import {CharacterPrivacy, CharacterSide} from "../model/Character"; import {ClockMode, TimerDirection} from "../model/GameState"; export const parser = grammar.createSemantics() export interface ParserNode extends Node { - element: ElementalType|null - affinity: Affinity - sign: NumberSign - numberValue: number - identifier: string - resource: Resource|null - operands: Operands - blockTargets: Operands - blockSources: Operands - silenced: boolean - currentValue: number - maxValue: number + readonly element: ElementalType|null + readonly affinity: Affinity + readonly sign: NumberSign + readonly numberValue: number + readonly identifier: string + readonly resource: Resource|null + readonly operands: Operands + readonly blockTargets: Operands + readonly blockSources: Operands + readonly silenced: boolean + readonly currentValue: number + readonly maxValue: number + readonly failReason: FailReason + readonly side: CharacterSide // TODO: Implement all of the things listed below. - textValue: string - failReason: unknown // TODO: create an enum for this + readonly textValue: string // TODO: create rules for these to describe clocks/timers/items/statuses/characters and implement them - nameText: string - descriptionText: string + readonly nameText: string + readonly descriptionText: string // TODO: use for portraits, status icons, backdrops, BGM, and SFX - url: string - side: CharacterSide - privacy: CharacterPrivacy - clockMode: ClockMode - timerDirection: TimerDirection - timerDurationMs: number + readonly url: string + readonly privacy: CharacterPrivacy + readonly clockMode: ClockMode + readonly timerDirection: TimerDirection + readonly timerDurationMs: number // TODO: add backdrop and music change and sfx commands // TODO: make sure that FP and UP spent gets saved in the appropriate counters @@ -782,4 +786,64 @@ parser.addAttribute("maxValue", { _terminal(): never { throw Error(`No idea what to say ${this.ctorName} terminal node's max value is`) } +}) + +parser.addAttribute("failReason", { + avoid(): FailReason.Avoid { + return FailReason.Avoid + }, + dodge(): FailReason.Dodge { + return FailReason.Dodge + }, + miss(): FailReason.Miss { + return FailReason.Miss + }, + resist(): FailReason.Resist { + return FailReason.Resist + }, + fail(): FailReason.Fail { + return FailReason.Fail + }, + block(): FailReason.Block { + return FailReason.Block + }, + parry(): FailReason.Parry { + return FailReason.Parry + }, + FailReason(reason: NonterminalNode): FailReason { + return (reason as ParserNode).failReason + }, + FailOperation(operands: NonterminalNode, colon: NonterminalNode, reason: NonterminalNode): FailReason { + return (reason as ParserNode).failReason + }, + _iter(): never { + throw Error(`No idea what to say ${this.ctorName} iteration node's fail reason is`) + }, + _nonterminal(): never { + throw Error(`No idea what to say ${this.ctorName} nonterminal node's fail reason is`) + }, + _terminal(): never { + throw Error(`No idea what to say ${this.ctorName} terminal node's fail reason is`) + } +}) + +parser.addAttribute("side", { + characterSide(side: NonterminalNode): CharacterSide { + return (side as ParserNode).side + }, + enemySide(): CharacterSide.Enemy { + return CharacterSide.Enemy + }, + allySide(): CharacterSide.Ally { + return CharacterSide.Ally + }, + _iter(): never { + throw Error(`No idea what to say ${this.ctorName} iteration node's loyalties are`) + }, + _nonterminal(): never { + throw Error(`No idea what to say ${this.ctorName} nonterminal node's loyalties are`) + }, + _terminal(): never { + throw Error(`No idea what to say ${this.ctorName} terminal node's loyalties are`) + } }) \ No newline at end of file diff --git a/src/model/Messages.ts b/src/model/Messages.ts index c35881b..fdfead2 100644 --- a/src/model/Messages.ts +++ b/src/model/Messages.ts @@ -48,6 +48,16 @@ export enum UnmeteredResource { export type Resource = MeteredResource|UnmeteredResource +export enum FailReason { + Avoid = "avoid", + Dodge = "dodge", + Miss = "miss", + Resist = "resist", + Fail = "fail", + Block = "block", + Parry = "parry", +} + export const Target: unique symbol = Symbol("target"); export const Source: unique symbol = Symbol("source");