import { describe } from 'bun:test' import { expect, test } from 'bun:test' describe('number literals', () => { test('binary literals', () => { expect('0b110').toEvaluateTo(6) expect('0b1010').toEvaluateTo(10) expect('0b11111111').toEvaluateTo(255) expect('0b0').toEvaluateTo(0) expect('0b1').toEvaluateTo(1) }) test('hex literals', () => { expect('0xdeadbeef').toEvaluateTo(0xdeadbeef) expect('0xdeadbeef').toEvaluateTo(3735928559) expect('0xFF').toEvaluateTo(255) expect('0xff').toEvaluateTo(255) expect('0x10').toEvaluateTo(16) expect('0x0').toEvaluateTo(0) expect('0xABCDEF').toEvaluateTo(0xabcdef) }) test('decimal literals still work', () => { expect('42').toEvaluateTo(42) expect('3.14').toEvaluateTo(3.14) expect('0').toEvaluateTo(0) expect('999999').toEvaluateTo(999999) }) test('negative hex and binary', () => { expect('-0xFF').toEvaluateTo(-255) expect('-0b1010').toEvaluateTo(-10) }) test('positive prefix', () => { expect('+0xFF').toEvaluateTo(255) expect('+0b110').toEvaluateTo(6) expect('+42').toEvaluateTo(42) }) }) 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']) }) test('empty arrays', () => { expect('[]').toEvaluateTo([]) }) test('mixed types', () => { expect("[1 'two' three true null]").toEvaluateTo([1, 'two', 'three', true, null]) }) test('semicolons as separators', () => { expect('[1; 2; 3]').toEvaluateTo([1, 2, 3]) }) test('expressions in arrays', () => { expect('[(1 + 2) (3 * 4)]').toEvaluateTo([3, 12]) }) test('mixed separators - spaces and newlines', () => { expect(`[1 2 3 4]`).toEvaluateTo([1, 2, 3, 4]) }) test('mixed separators - spaces and semicolons', () => { expect('[1 2; 3 4]').toEvaluateTo([1, 2, 3, 4]) }) test('empty lines within arrays', () => { expect(`[1 2]`).toEvaluateTo([1, 2]) }) test('comments within arrays', () => { expect(`[1 2 ]`).toEvaluateTo([1, 2]) }) test('complex nested multiline', () => { expect(`[ [1 2] [3 4] [5 6] ]`).toEvaluateTo([ [1, 2], [3, 4], [5, 6], ]) }) test('boolean and null literals', () => { expect('[true false null]').toEvaluateTo([true, false, null]) }) test('regex literals', () => { expect('[//[0-9]+//]').toEvaluateTo([/[0-9]+/]) }) test('trailing newlines', () => { expect(`[ 1 2 ]`).toEvaluateTo([1, 2]) }) }) describe('dict literals', () => { test('work with numbers', () => { expect('[a=1 b=2 c=3]').toEvaluateTo({ a: 1, b: 2, c: 3 }) }) test('work with strings', () => { expect("[a='one' b='two' c='three']").toEvaluateTo({ a: 'one', b: 'two', c: 'three' }) }) test('work with identifiers', () => { expect('[a=one b=two c=three]').toEvaluateTo({ a: 'one', b: 'two', c: 'three' }) }) test('can be nested', () => { expect('[a=one b=[two [c=three]]]').toEvaluateTo({ a: 'one', b: ['two', { c: 'three' }] }) }) test('can span multiple lines', () => { expect(`[ a=1 b=2 c=3 ]`).toEvaluateTo({ a: 1, b: 2, c: 3 }) }) test('empty dict', () => { expect('[=]').toEvaluateTo({}) expect('[ = ]').toEvaluateTo({}) }) test('mixed types', () => { expect("[a=1 b='two' c=three d=true e=null]").toEvaluateTo({ a: 1, b: 'two', c: 'three', d: true, e: null, }) }) test('semicolons as separators', () => { expect('[a=1; b=2; c=3]').toEvaluateTo({ a: 1, b: 2, c: 3 }) }) test('expressions in dicts', () => { expect('[a=(1 + 2) b=(3 * 4)]').toEvaluateTo({ a: 3, b: 12 }) }) test('empty lines within dicts', () => { expect(`[a=1 b=2 c=3]`).toEvaluateTo({ a: 1, b: 2, c: 3 }) }) }) describe('curly strings', () => { test('work on one line', () => { expect('{ one two three }').toEvaluateTo(" one two three ") }) test('work on multiple lines', () => { expect(`{ one two three }`).toEvaluateTo("\n one\n two\n three\n ") }) test('can contain other curlies', () => { expect(`{ { one } two { three } }`).toEvaluateTo("\n { one }\n two\n { three }\n ") }) test('interpolates variables', () => { expect(`name = Bob; { Hello $name! }`).toEvaluateTo(` Hello Bob! `) }) test("doesn't interpolate escaped variables ", () => { expect(`name = Bob; { Hello \\$name }`).toEvaluateTo(` Hello $name `) expect(`a = 1; b = 2; { sum is \\$(a + b)! }`).toEvaluateTo(` sum is $(a + b)! `) }) test('interpolates expressions', () => { expect(`a = 1; b = 2; { sum is $(a + b)! }`).toEvaluateTo(` sum is 3! `) expect(`a = 1; b = 2; { sum is { $(a + b) }! }`).toEvaluateTo(` sum is { 3 }! `) expect(`a = 1; b = 2; { sum is $(a + (b * b))! }`).toEvaluateTo(` sum is 5! `) expect(`{ This is $({twisted}). }`).toEvaluateTo(` This is twisted. `) expect(`{ This is $({{twisted}}). }`).toEvaluateTo(` This is {twisted}. `) }) test('interpolation edge cases', () => { expect(`{[a=1 b=2 c={wild}]}`).toEvaluateTo(`[a=1 b=2 c={wild}]`) expect(`a = 1;b = 2;c = 3;{$a $b $c}`).toEvaluateTo(`1 2 3`) expect(`a = 1;b = 2;c = 3;{$a$b$c}`).toEvaluateTo(`123`) }) }) describe('double quoted strings', () => { test("work", () => { expect(`"hello world"`).toEvaluateTo('hello world') }) test("don't interpolate", () => { expect(`"hello $world"`).toEvaluateTo('hello $world') expect(`"hello $(1 + 2)"`).toEvaluateTo('hello $(1 + 2)') }) test("equal regular strings", () => { expect(`"hello world" == 'hello world'`).toEvaluateTo(true) }) test("can contain newlines", () => { expect(` "hello world"`).toEvaluateTo('hello\n world') }) })