compile array literals

This commit is contained in:
Chris Wanstrath 2025-10-28 16:47:33 -07:00
parent 7da4c14962
commit 339c09eb8c
3 changed files with 49 additions and 6 deletions

View File

@ -468,6 +468,13 @@ export class Compiler {
return instructions return instructions
} }
case terms.Array: {
const children = getAllChildren(node)
const instructions: ProgramItem[] = children.map((x) => this.#compileNode(x, input)).flat()
instructions.push(['MAKE_ARRAY', children.length])
return instructions
}
default: default:
throw new CompilerError( throw new CompilerError(
`Compiler doesn't know how to handle a "${node.type.name}" node.`, `Compiler doesn't know how to handle a "${node.type.name}" node.`,

View File

@ -0,0 +1,36 @@
import { describe } from 'bun:test'
import { expect, test } from 'bun:test'
describe('array literals', () => {
test('work with numbers', () => {
expect('[1 2 3]').toEvaluateTo([1, 2, 3])
})
test('work with strings', () => {
expect("['one' 'two' 'three']").toEvaluateTo(['one', 'two', 'three'])
})
test('work with identifiers', () => {
expect('[one two three]').toEvaluateTo(['one', 'two', 'three'])
})
test('can be nested', () => {
expect('[one [two [three]]]').toEvaluateTo(['one', ['two', ['three']]])
})
test('can span multiple lines', () => {
expect(`[
1
2
3
]`).toEvaluateTo([1, 2, 3])
})
test('can span multiple w/o calling functions', () => {
expect(`[
one
two
three
]`).toEvaluateTo(['one', 'two', 'three'])
})
})

View File

@ -93,11 +93,7 @@ expect.extend({
} }
}, },
async toEvaluateTo( async toEvaluateTo(received: unknown, expected: unknown, globals: Record<string, any> = {}) {
received: unknown,
expected: unknown,
globals: Record<string, any> = {}
) {
assert(typeof received === 'string', 'toEvaluateTo can only be used with string values') assert(typeof received === 'string', 'toEvaluateTo can only be used with string values')
try { try {
@ -109,7 +105,7 @@ expect.extend({
if (expected instanceof RegExp) expected = String(expected) if (expected instanceof RegExp) expected = String(expected)
if (value instanceof RegExp) value = String(value) if (value instanceof RegExp) value = String(value)
if (value === expected) { if (isEqual(value, expected)) {
return { pass: true } return { pass: true }
} else { } else {
return { return {
@ -165,3 +161,7 @@ const trimWhitespace = (str: string): string => {
}) })
.join('\n') .join('\n')
} }
function isEqual(a: any, b: any): boolean {
return typeof a === 'object' ? JSON.stringify(a) === JSON.stringify(b) : a === b
}