add var? and var
This commit is contained in:
parent
d93ce85178
commit
f9b0aa2db5
|
|
@ -1,7 +1,7 @@
|
||||||
// The prelude creates all the builtin Shrimp functions.
|
// The prelude creates all the builtin Shrimp functions.
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type Value, toValue,
|
type Value, type VM, toValue,
|
||||||
extractParamInfo, isWrapped, getOriginalFunction,
|
extractParamInfo, isWrapped, getOriginalFunction,
|
||||||
} from 'reefvm'
|
} from 'reefvm'
|
||||||
|
|
||||||
|
|
@ -34,13 +34,11 @@ export const globals = {
|
||||||
const val = toValue(v)
|
const val = toValue(v)
|
||||||
return `#<${val.type}: ${formatValue(val)}>`
|
return `#<${val.type}: ${formatValue(val)}>`
|
||||||
},
|
},
|
||||||
length: (v: any) => {
|
var: function (this: VM, v: any) {
|
||||||
const value = toValue(v)
|
return typeof v === 'string' ? this.scope.get(v) : v
|
||||||
switch (value.type) {
|
},
|
||||||
case 'string': case 'array': return value.value.length
|
'var?': function (this: VM, v: string) {
|
||||||
case 'dict': return value.value.size
|
return typeof v !== 'string' || this.scope.has(v)
|
||||||
default: throw new Error(`length: expected string, array, or dict, got ${value.type}`)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// type predicates
|
// type predicates
|
||||||
|
|
@ -65,6 +63,14 @@ export const globals = {
|
||||||
identity: (v: any) => v,
|
identity: (v: any) => v,
|
||||||
|
|
||||||
// collections
|
// collections
|
||||||
|
length: (v: any) => {
|
||||||
|
const value = toValue(v)
|
||||||
|
switch (value.type) {
|
||||||
|
case 'string': case 'array': return value.value.length
|
||||||
|
case 'dict': return value.value.size
|
||||||
|
default: throw new Error(`length: expected string, array, or dict, got ${value.type}`)
|
||||||
|
}
|
||||||
|
},
|
||||||
at: (collection: any, index: number | string) => {
|
at: (collection: any, index: number | string) => {
|
||||||
const value = toValue(collection)
|
const value = toValue(collection)
|
||||||
if (value.type === 'string' || value.type === 'array') {
|
if (value.type === 'string' || value.type === 'array') {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,25 @@
|
||||||
import { expect, describe, test } from 'bun:test'
|
import { expect, describe, test } from 'bun:test'
|
||||||
import { globals, colors } from '#prelude'
|
import { globals } from '#prelude'
|
||||||
|
|
||||||
|
describe('var and var?', () => {
|
||||||
|
test('var? checks if a variable exists', async () => {
|
||||||
|
await expect(`var? 'nada'`).toEvaluateTo(false, globals)
|
||||||
|
await expect(`var? 'info'`).toEvaluateTo(false, globals)
|
||||||
|
await expect(`abc = abc; var? 'abc'`).toEvaluateTo(true, globals)
|
||||||
|
await expect(`var? 'var?'`).toEvaluateTo(true, globals)
|
||||||
|
|
||||||
|
await expect(`var? 'dict'`).toEvaluateTo(true, globals)
|
||||||
|
await expect(`var? dict`).toEvaluateTo(true, globals)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('var returns a value or null', async () => {
|
||||||
|
await expect(`var 'nada'`).toEvaluateTo(null, globals)
|
||||||
|
await expect(`var nada`).toEvaluateTo(null, globals)
|
||||||
|
await expect(`var 'info'`).toEvaluateTo(null, globals)
|
||||||
|
await expect(`abc = my-string; var 'abc'`).toEvaluateTo('my-string', globals)
|
||||||
|
await expect(`abc = my-string; var abc`).toEvaluateTo(null, globals)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('type predicates', () => {
|
describe('type predicates', () => {
|
||||||
test('string? checks for string type', async () => {
|
test('string? checks for string type', async () => {
|
||||||
|
|
@ -38,7 +58,6 @@ describe('type predicates', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
describe('introspection', () => {
|
describe('introspection', () => {
|
||||||
test('type returns proper types', async () => {
|
test('type returns proper types', async () => {
|
||||||
await expect(`type 'hello'`).toEvaluateTo('string', globals)
|
await expect(`type 'hello'`).toEvaluateTo('string', globals)
|
||||||
|
|
@ -50,18 +69,6 @@ describe('introspection', () => {
|
||||||
await expect(`type [a=1 b=2]`).toEvaluateTo('dict', globals)
|
await expect(`type [a=1 b=2]`).toEvaluateTo('dict', globals)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('length', async () => {
|
|
||||||
await expect(`length 'hello'`).toEvaluateTo(5, globals)
|
|
||||||
await expect(`length [1 2 3]`).toEvaluateTo(3, globals)
|
|
||||||
await expect(`length [a=1 b=2]`).toEvaluateTo(2, globals)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('length throws on invalid types', async () => {
|
|
||||||
await expect(`try: length 42 catch e: 'error' end`).toEvaluateTo('error', globals)
|
|
||||||
await expect(`try: length true catch e: 'error' end`).toEvaluateTo('error', globals)
|
|
||||||
await expect(`try: length null catch e: 'error' end`).toEvaluateTo('error', globals)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('inspect formats values', async () => {
|
test('inspect formats values', async () => {
|
||||||
await expect(`inspect 'hello'`).toEvaluateTo("\u001b[32m'hello\u001b[32m'\u001b[0m", globals)
|
await expect(`inspect 'hello'`).toEvaluateTo("\u001b[32m'hello\u001b[32m'\u001b[0m", globals)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,18 @@ describe('utilities', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('collections', () => {
|
describe('collections', () => {
|
||||||
|
test('length', async () => {
|
||||||
|
await expect(`length 'hello'`).toEvaluateTo(5, globals)
|
||||||
|
await expect(`length [1 2 3]`).toEvaluateTo(3, globals)
|
||||||
|
await expect(`length [a=1 b=2]`).toEvaluateTo(2, globals)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('length throws on invalid types', async () => {
|
||||||
|
await expect(`try: length 42 catch e: 'error' end`).toEvaluateTo('error', globals)
|
||||||
|
await expect(`try: length true catch e: 'error' end`).toEvaluateTo('error', globals)
|
||||||
|
await expect(`try: length null catch e: 'error' end`).toEvaluateTo('error', globals)
|
||||||
|
})
|
||||||
|
|
||||||
test('literal array creates array from arguments', async () => {
|
test('literal array creates array from arguments', async () => {
|
||||||
await expect(`[ 1 2 3 ]`).toEvaluateTo([1, 2, 3], globals)
|
await expect(`[ 1 2 3 ]`).toEvaluateTo([1, 2, 3], globals)
|
||||||
await expect(`['a' 'b']`).toEvaluateTo(['a', 'b'], globals)
|
await expect(`['a' 'b']`).toEvaluateTo(['a', 'b'], globals)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user