Compare commits
4 Commits
1a3f1c6c43
...
92ce43b508
| Author | SHA1 | Date | |
|---|---|---|---|
| 92ce43b508 | |||
| c51030b3bd | |||
| e95c0d6728 | |||
| c3453fdc5c |
8
ha.sh
8
ha.sh
|
|
@ -1,8 +0,0 @@
|
||||||
bob = [ name= Bob age= 44 ]
|
|
||||||
mike = [
|
|
||||||
name= Mike
|
|
||||||
age= 46
|
|
||||||
]
|
|
||||||
|
|
||||||
echo bob
|
|
||||||
echo (mike | at name)
|
|
||||||
|
|
@ -1,9 +1,16 @@
|
||||||
|
import { type Value, toString, toValue } from 'reefvm'
|
||||||
|
|
||||||
export const dict = {
|
export const dict = {
|
||||||
keys: (dict: Record<string, any>) => Object.keys(dict),
|
keys: (dict: Record<string, any>) => Object.keys(dict),
|
||||||
values: (dict: Record<string, any>) => Object.values(dict),
|
values: (dict: Record<string, any>) => Object.values(dict),
|
||||||
entries: (dict: Record<string, any>) => Object.entries(dict).map(([k, v]) => ({ key: k, value: v })),
|
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,
|
'has?': (dict: Record<string, any>, key: string) => key in dict,
|
||||||
get: (dict: Record<string, any>, key: string, defaultValue: any = null) => dict[key] ?? defaultValue,
|
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),
|
merge: (...dicts: Record<string, any>[]) => Object.assign({}, ...dicts),
|
||||||
'empty?': (dict: Record<string, any>) => Object.keys(dict).length === 0,
|
'empty?': (dict: Record<string, any>) => Object.keys(dict).length === 0,
|
||||||
map: async (dict: Record<string, any>, cb: Function) => {
|
map: async (dict: Record<string, any>, cb: Function) => {
|
||||||
|
|
@ -22,3 +29,7 @@ export const dict = {
|
||||||
},
|
},
|
||||||
'from-entries': (entries: [string, any][]) => Object.fromEntries(entries),
|
'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
|
||||||
|
|
|
||||||
|
|
@ -471,6 +471,12 @@ describe('dict operations', () => {
|
||||||
await expect(`dict.get [a=1] 'b' 99`).toEvaluateTo(99, globals)
|
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 () => {
|
test('dict.empty? checks if dict is empty', async () => {
|
||||||
await expect(`dict.empty? [=]`).toEvaluateTo(true, globals)
|
await expect(`dict.empty? [=]`).toEvaluateTo(true, globals)
|
||||||
await expect(`dict.empty? [a=1]`).toEvaluateTo(false, globals)
|
await expect(`dict.empty? [a=1]`).toEvaluateTo(false, globals)
|
||||||
|
|
|
||||||
|
|
@ -108,16 +108,10 @@ 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 (isEqual(value, expected)) {
|
expect(value).toEqual(expected)
|
||||||
return { pass: true }
|
return {
|
||||||
} else {
|
message: () => `Expected evaluation to be ${expected}, but got ${value}`,
|
||||||
return {
|
pass: true,
|
||||||
message: () =>
|
|
||||||
`Expected evaluation to be ${JSON.stringify(expected)}, but got ${JSON.stringify(
|
|
||||||
value
|
|
||||||
)}`,
|
|
||||||
pass: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
|
|
@ -167,29 +161,3 @@ const trimWhitespace = (str: string): string => {
|
||||||
})
|
})
|
||||||
.join('\n')
|
.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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { Tree, TreeCursor } from '@lezer/common'
|
import { Tree, TreeCursor } from '@lezer/common'
|
||||||
import { assertNever } from '#utils/utils'
|
|
||||||
import { type Value, fromValue } from 'reefvm'
|
import { type Value, fromValue } from 'reefvm'
|
||||||
|
|
||||||
export const treeToString = (tree: Tree, input: string): string => {
|
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 => {
|
export const VMResultToValue = (result: Value): unknown => {
|
||||||
if (result.type === 'function') return Function
|
return result.type === 'function' ? Function : fromValue(result)
|
||||||
else return fromValue(result)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user