From c437958406c9153f508096ee600b04a4f3e691a3 Mon Sep 17 00:00:00 2001 From: garrettmills Date: Tue, 11 Nov 2025 20:50:28 -0600 Subject: [PATCH] Start lipsum command --- src/vm/commands/command.ts | 25 +++++++++++++++++++++---- src/vm/commands/lipsum.ts | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/vm/commands/lipsum.ts diff --git a/src/vm/commands/command.ts b/src/vm/commands/command.ts index 3eeab78..91ce675 100644 --- a/src/vm/commands/command.ts +++ b/src/vm/commands/command.ts @@ -1,10 +1,15 @@ import {LexInput} from '../lexer.js' -import {ExpectedEndOfInputError, InvalidVariableNameError, UnexpectedEndOfInputError} from "../parse.js"; +import { + ExpectedEndOfInputError, + InvalidVariableNameError, + IsNotKeywordError, + UnexpectedEndOfInputError +} from "../parse.js"; export type StrLVal = { term: 'variable', name: string } export type StrTerm = - { term: 'string', value: string } + { term: 'string', value: string, literal?: true } | StrLVal export class ParseContext { @@ -25,7 +30,7 @@ export class ParseContext { popTerm(): StrTerm { if ( !this.inputs.length ) { - throw new UnexpectedEndOfInputError('Unexpected end of input. Expected term.'); + throw new UnexpectedEndOfInputError('Unexpected end of input. Expected term.') } const input = this.inputs.shift()! @@ -40,7 +45,19 @@ export class ParseContext { } // Otherwise, parse it as a string literal: - return { term: 'string', value: input.value } + return { term: 'string', value: input.value, literal: input.literal } + } + + popKeywordInSet(options: T) { + if ( !this.inputs.length ) { + throw new UnexpectedEndOfInputError('Unexpected end of input. Expected one of: ' + options.join(', ')) + } + + const input = this.inputs.shift()! + + if ( input.literal || !options.includes(input.value) ) { + throw new IsNotKeywordError('Unexpected term: ' + input.value + ' (expected one of: ' + options.join(', ') + ')') + } } popLVal(): StrLVal { diff --git a/src/vm/commands/lipsum.ts b/src/vm/commands/lipsum.ts new file mode 100644 index 0000000..ec0456b --- /dev/null +++ b/src/vm/commands/lipsum.ts @@ -0,0 +1,18 @@ +import {Command, ParseContext, StrTerm} from './command.js' +import {LexInput} from '../lexer.js' + +export class Lipsum extends Command<{ length: StrTerm }> { + attemptParse(context: ParseContext): { length: StrTerm } { + return { + length: context.popTerm(), + } + } + + getDisplayName(): string { + return 'lipsum' + } + + isParseCandidate(token: LexInput): boolean { + return this.isKeyword(token, 'lipsum') + } +}