ARRAY_PUSH

This commit is contained in:
Chris Wanstrath 2025-10-05 15:32:49 -07:00
parent 9a748beacb
commit 6f6ddcea89
4 changed files with 50 additions and 6 deletions

View File

@ -381,6 +381,12 @@ Index is coerced to number and floored.
**Stack**: [array, index, value] → [] **Stack**: [array, index, value] → []
**Errors**: Throws if not array or index out of bounds **Errors**: Throws if not array or index out of bounds
#### ARRAY_PUSH
**Operand**: None
**Effect**: Append value to end of array (mutates array, grows by 1)
**Stack**: [array, value] → []
**Errors**: Throws if not array
#### ARRAY_LEN #### ARRAY_LEN
**Operand**: None **Operand**: None
**Effect**: Get array length **Effect**: Get array length

View File

@ -48,6 +48,7 @@ export enum OpCode {
MAKE_ARRAY, MAKE_ARRAY,
ARRAY_GET, ARRAY_GET,
ARRAY_SET, ARRAY_SET,
ARRAY_PUSH,
ARRAY_LEN, ARRAY_LEN,
// dicts // dicts

View File

@ -212,6 +212,16 @@ export class VM {
setArray.value[setIdx] = setValue setArray.value[setIdx] = setValue
break break
case OpCode.ARRAY_PUSH:
const pushValue = this.stack.pop()!
const pushArray = this.stack.pop()!
if (pushArray.type !== 'array')
throw new Error('ARRAY_PUSH: not an array')
pushArray.value.push(pushValue)
break
case OpCode.ARRAY_LEN: case OpCode.ARRAY_LEN:
const lenArray = this.stack.pop()! const lenArray = this.stack.pop()!
if (lenArray.type !== 'array') if (lenArray.type !== 'array')

View File

@ -418,6 +418,33 @@ test("ARRAY_SET - sets element", async () => {
expect(await run(toBytecode(str))).toEqual({ type: 'number', value: 99 }) expect(await run(toBytecode(str))).toEqual({ type: 'number', value: 99 })
}) })
test("ARRAY_PUSH - appends to array", async () => {
const str = `
PUSH 10
PUSH 20
MAKE_ARRAY 2
DUP
PUSH 30
ARRAY_PUSH
ARRAY_LEN
`
expect(await run(toBytecode(str))).toEqual({ type: 'number', value: 3 })
})
test("ARRAY_PUSH - mutates original array", async () => {
const str = `
PUSH 10
PUSH 20
MAKE_ARRAY 2
DUP
PUSH 30
ARRAY_PUSH
PUSH 2
ARRAY_GET
`
expect(await run(toBytecode(str))).toEqual({ type: 'number', value: 30 })
})
test("ARRAY_LEN - gets length", async () => { test("ARRAY_LEN - gets length", async () => {
const str = ` const str = `
PUSH 10 PUSH 10