ARRAY_PUSH
This commit is contained in:
parent
9a748beacb
commit
6f6ddcea89
18
SPEC.md
18
SPEC.md
|
|
@ -376,15 +376,21 @@ Items are popped in reverse order (item1 is array[0]).
|
||||||
Index is coerced to number and floored.
|
Index is coerced to number and floored.
|
||||||
|
|
||||||
#### ARRAY_SET
|
#### ARRAY_SET
|
||||||
**Operand**: None
|
**Operand**: None
|
||||||
**Effect**: Set array element at index (mutates array)
|
**Effect**: Set array element at index (mutates array)
|
||||||
**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
|
||||||
**Stack**: [array] → [length]
|
**Stack**: [array] → [length]
|
||||||
**Errors**: Throws if not array
|
**Errors**: Throws if not array
|
||||||
|
|
||||||
### Dictionary Operations
|
### Dictionary Operations
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
10
src/vm.ts
10
src/vm.ts
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user