diff --git a/src/compiler/compiler.ts b/src/compiler/compiler.ts index b7e6274..d05f2ce 100644 --- a/src/compiler/compiler.ts +++ b/src/compiler/compiler.ts @@ -468,6 +468,13 @@ export class Compiler { 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: throw new CompilerError( `Compiler doesn't know how to handle a "${node.type.name}" node.`, diff --git a/src/compiler/tests/literals.test.ts b/src/compiler/tests/literals.test.ts new file mode 100644 index 0000000..4be5579 --- /dev/null +++ b/src/compiler/tests/literals.test.ts @@ -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']) + }) +}) diff --git a/src/testSetup.ts b/src/testSetup.ts index 8e1f4b8..89203e1 100644 --- a/src/testSetup.ts +++ b/src/testSetup.ts @@ -93,11 +93,7 @@ expect.extend({ } }, - async toEvaluateTo( - received: unknown, - expected: unknown, - globals: Record = {} - ) { + async toEvaluateTo(received: unknown, expected: unknown, globals: Record = {}) { assert(typeof received === 'string', 'toEvaluateTo can only be used with string values') try { @@ -109,7 +105,7 @@ expect.extend({ if (expected instanceof RegExp) expected = String(expected) if (value instanceof RegExp) value = String(value) - if (value === expected) { + if (isEqual(value, expected)) { return { pass: true } } else { return { @@ -165,3 +161,7 @@ const trimWhitespace = (str: string): string => { }) .join('\n') } + +function isEqual(a: any, b: any): boolean { + return typeof a === 'object' ? JSON.stringify(a) === JSON.stringify(b) : a === b +}