Compare commits

...

4 Commits

Author SHA1 Message Date
92ce43b508 dict.set 2025-10-29 13:12:40 -07:00
c51030b3bd sure 2025-10-29 12:50:56 -07:00
e95c0d6728 use bun's equal check 2025-10-29 12:50:09 -07:00
c3453fdc5c how did that get in there... 2025-10-29 12:45:27 -07:00
5 changed files with 22 additions and 47 deletions

8
ha.sh
View File

@ -1,8 +0,0 @@
bob = [ name= Bob age= 44 ]
mike = [
name= Mike
age= 46
]
echo bob
echo (mike | at name)

View File

@ -1,9 +1,16 @@
import { type Value, toString, toValue } from 'reefvm'
export const dict = {
keys: (dict: Record<string, any>) => Object.keys(dict),
values: (dict: Record<string, any>) => Object.values(dict),
entries: (dict: Record<string, any>) => Object.entries(dict).map(([k, v]) => ({ key: k, value: v })),
'has?': (dict: Record<string, any>, key: string) => key in dict,
get: (dict: Record<string, any>, key: string, defaultValue: any = null) => dict[key] ?? defaultValue,
set: (dict: Value, key: Value, value: Value) => {
const map = dict.value as Map<string, Value>
map.set(toString(key), value)
return dict
},
merge: (...dicts: Record<string, any>[]) => Object.assign({}, ...dicts),
'empty?': (dict: Record<string, any>) => Object.keys(dict).length === 0,
map: async (dict: Record<string, any>, cb: Function) => {
@ -22,3 +29,7 @@ export const dict = {
},
'from-entries': (entries: [string, any][]) => Object.fromEntries(entries),
}
// raw functions deal directly in Value types, meaning we can modify collection
// careful - the MUST return a Value!
; (dict.set as any).raw = true

View File

@ -471,6 +471,12 @@ describe('dict operations', () => {
await expect(`dict.get [a=1] 'b' 99`).toEvaluateTo(99, globals)
})
test('dict.set sets value', async () => {
await expect(`map = [a=1]; dict.set map 'b' 99; map.b`).toEvaluateTo(99, globals)
await expect(`map = [a=1]; dict.set map 'a' 100; map.a`).toEvaluateTo(100, globals)
})
test('dict.empty? checks if dict is empty', async () => {
await expect(`dict.empty? [=]`).toEvaluateTo(true, globals)
await expect(`dict.empty? [a=1]`).toEvaluateTo(false, globals)

View File

@ -108,16 +108,10 @@ expect.extend({
if (expected instanceof RegExp) expected = String(expected)
if (value instanceof RegExp) value = String(value)
if (isEqual(value, expected)) {
return { pass: true }
} else {
return {
message: () =>
`Expected evaluation to be ${JSON.stringify(expected)}, but got ${JSON.stringify(
value
)}`,
pass: false,
}
expect(value).toEqual(expected)
return {
message: () => `Expected evaluation to be ${expected}, but got ${value}`,
pass: true,
}
} catch (error) {
return {
@ -167,29 +161,3 @@ const trimWhitespace = (str: string): string => {
})
.join('\n')
}
function isEqual(a: any, b: any): boolean {
if (a === null && b === null) return true
switch (typeof a) {
case 'string':
case 'number':
case 'boolean':
case 'undefined':
return a === b
default:
return JSON.stringify(sortKeys(a)) === JSON.stringify(sortKeys(b))
}
}
function sortKeys(o: any): any {
if (Array.isArray(o)) return o.map(sortKeys)
if (o && typeof o === 'object' && o.constructor === Object)
return Object.keys(o)
.sort()
.reduce((r, k) => {
r[k] = sortKeys(o[k])
return r
}, {} as any)
return o
}

View File

@ -1,5 +1,4 @@
import { Tree, TreeCursor } from '@lezer/common'
import { assertNever } from '#utils/utils'
import { type Value, fromValue } from 'reefvm'
export const treeToString = (tree: Tree, input: string): string => {
@ -35,6 +34,5 @@ export const treeToString = (tree: Tree, input: string): string => {
}
export const VMResultToValue = (result: Value): unknown => {
if (result.type === 'function') return Function
else return fromValue(result)
return result.type === 'function' ? Function : fromValue(result)
}