Add zip command

This commit is contained in:
2026-03-03 09:15:21 -06:00
parent 6e1e44adb4
commit d296646d4f
3 changed files with 44 additions and 0 deletions

View File

@@ -45,6 +45,7 @@ import {Drop} from "./drop.js";
import {Sort} from "./sort.js"; import {Sort} from "./sort.js";
import {Set} from "./set.js"; import {Set} from "./set.js";
import {Assign} from "./assign.js"; import {Assign} from "./assign.js";
import {Zip} from "./zip.js";
export type Commands = Command<CommandData>[] export type Commands = Command<CommandData>[]
export const commands: Commands = [ export const commands: Commands = [
@@ -94,4 +95,5 @@ export const commands: Commands = [
new Upper, new Upper,
new Word, new Word,
new Words, new Words,
new Zip,
] ]

38
src/vm/commands/zip.ts Normal file
View File

@@ -0,0 +1,38 @@
import {Command, ParseContext, StrDestructured, StrTerm} from "./command.js";
import {Awaitable} from "../../util/types.js";
import {LexInput} from "../lexer.js";
import {StrVM} from "../vm.js";
export type ZipData = {
with: StrTerm,
}
export class Zip extends Command<ZipData> {
attemptParse(context: ParseContext): Awaitable<ZipData> {
return {
with: context.popTerm(),
}
}
getDisplayName(): string {
return 'zip'
}
isParseCandidate(token: LexInput): boolean {
return this.isKeyword(token, 'zip')
}
execute(vm: StrVM, data: ZipData): Awaitable<StrVM> {
return vm.replaceContextMatchingTerm(ctx => ({
destructured: lhs => {
const rhs = ctx.resolveDestructured(data.with)
const zipped: StrDestructured['value'] = []
for ( let i = 0; i < Math.max(lhs.length, rhs.length); i += 1 ) {
if ( lhs[i] ) zipped.push(lhs[i])
if ( rhs[i] ) zipped.push(rhs[i])
}
return zipped
},
}))
}
}

View File

@@ -266,6 +266,10 @@ export class ExecutionContext {
return unwrapString(this.resolveRequired(term)) return unwrapString(this.resolveRequired(term))
} }
resolveDestructured(term: StrTerm) {
return unwrapDestructured(this.resolveRequired(term))
}
resolveInt(term: StrTerm): number { resolveInt(term: StrTerm): number {
return unwrapInt(this.resolveRequired(term)) return unwrapInt(this.resolveRequired(term))
} }