Add regexes
This commit is contained in:
parent
0844e99d2d
commit
f3759c2259
125
src/value.ts
125
src/value.ts
|
|
@ -1,22 +1,23 @@
|
|||
import { Scope } from "./scope"
|
||||
import { Scope } from './scope'
|
||||
|
||||
export type Value =
|
||||
| { type: 'null', value: null }
|
||||
| { type: 'boolean', value: boolean }
|
||||
| { type: 'number', value: number }
|
||||
| { type: 'string', value: string }
|
||||
| { type: 'array', value: Value[] }
|
||||
| { type: 'dict', value: Dict }
|
||||
| { type: 'null'; value: null }
|
||||
| { type: 'boolean'; value: boolean }
|
||||
| { type: 'number'; value: number }
|
||||
| { type: 'string'; value: string }
|
||||
| { type: 'array'; value: Value[] }
|
||||
| { type: 'dict'; value: Dict }
|
||||
| { type: 'regex'; value: RegExp }
|
||||
| {
|
||||
type: 'function',
|
||||
params: string[],
|
||||
defaults: Record<string, number>, // indices into constants
|
||||
body: number,
|
||||
parentScope: Scope,
|
||||
variadic: boolean,
|
||||
named: boolean,
|
||||
value: '<function>'
|
||||
}
|
||||
type: 'function'
|
||||
params: string[]
|
||||
defaults: Record<string, number> // indices into constants
|
||||
body: number
|
||||
parentScope: Scope
|
||||
variadic: boolean
|
||||
named: boolean
|
||||
value: '<function>'
|
||||
}
|
||||
|
||||
export type Dict = Map<string, Value>
|
||||
|
||||
|
|
@ -30,14 +31,13 @@ export type FunctionDef = {
|
|||
}
|
||||
|
||||
export function toValue(v: any): Value /* throws */ {
|
||||
if (v === null || v === undefined)
|
||||
return { type: 'null', value: null }
|
||||
if (v === null || v === undefined) return { type: 'null', value: null }
|
||||
|
||||
if (v && typeof v === 'object' && 'type' in v && 'value' in v)
|
||||
return v as Value
|
||||
if (v && typeof v === 'object' && 'type' in v && 'value' in v) return v as Value
|
||||
|
||||
if (Array.isArray(v))
|
||||
return { type: 'array', value: v.map(toValue) }
|
||||
if (Array.isArray(v)) return { type: 'array', value: v.map(toValue) }
|
||||
|
||||
if (v instanceof RegExp) return { type: 'regex', value: v }
|
||||
|
||||
switch (typeof v) {
|
||||
case 'boolean':
|
||||
|
|
@ -51,8 +51,7 @@ export function toValue(v: any): Value /* throws */ {
|
|||
case 'object':
|
||||
const dict: Dict = new Map()
|
||||
|
||||
for (const key of Object.keys(v))
|
||||
dict.set(key, toValue(v[key]))
|
||||
for (const key of Object.keys(v)) dict.set(key, toValue(v[key]))
|
||||
|
||||
return { type: 'dict', value: dict }
|
||||
default:
|
||||
|
|
@ -62,13 +61,16 @@ export function toValue(v: any): Value /* throws */ {
|
|||
|
||||
export function toNumber(v: Value): number {
|
||||
switch (v.type) {
|
||||
case 'number': return v.value
|
||||
case 'boolean': return v.value ? 1 : 0
|
||||
case 'number':
|
||||
return v.value
|
||||
case 'boolean':
|
||||
return v.value ? 1 : 0
|
||||
case 'string': {
|
||||
const parsed = parseFloat(v.value)
|
||||
return isNaN(parsed) ? 0 : parsed
|
||||
}
|
||||
default: return 0
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,17 +87,26 @@ export function isTrue(v: Value): boolean {
|
|||
|
||||
export function toString(v: Value): string {
|
||||
switch (v.type) {
|
||||
case 'string': return v.value
|
||||
case 'number': return String(v.value)
|
||||
case 'boolean': return String(v.value)
|
||||
case 'null': return 'null'
|
||||
case 'function': return '<function>'
|
||||
case 'array': return `[${v.value.map(toString).join(', ')}]`
|
||||
case 'string':
|
||||
return v.value
|
||||
case 'number':
|
||||
return String(v.value)
|
||||
case 'boolean':
|
||||
return String(v.value)
|
||||
case 'null':
|
||||
return 'null'
|
||||
case 'function':
|
||||
return '<function>'
|
||||
case 'array':
|
||||
return `[${v.value.map(toString).join(', ')}]`
|
||||
case 'dict': {
|
||||
const pairs = Array.from(v.value.entries())
|
||||
.map(([k, v]) => `${k}: ${toString(v)}`)
|
||||
const pairs = Array.from(v.value.entries()).map(([k, v]) => `${k}: ${toString(v)}`)
|
||||
return `{${pairs.join(', ')}}`
|
||||
}
|
||||
case 'regex':
|
||||
return String(v.value)
|
||||
default:
|
||||
return String(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,10 +114,14 @@ export function isEqual(a: Value, b: Value): boolean {
|
|||
if (a.type !== b.type) return false
|
||||
|
||||
switch (a.type) {
|
||||
case 'null': return true
|
||||
case 'boolean': return a.value === (b as typeof a).value
|
||||
case 'number': return a.value === (b as typeof a).value
|
||||
case 'string': return a.value === (b as typeof a).value
|
||||
case 'null':
|
||||
return true
|
||||
case 'boolean':
|
||||
return a.value === b.value
|
||||
case 'number':
|
||||
return a.value === b.value
|
||||
case 'string':
|
||||
return a.value === b.value
|
||||
case 'array': {
|
||||
const bArr = b as typeof a
|
||||
if (a.value.length !== bArr.value.length) return false
|
||||
|
|
@ -121,19 +136,35 @@ export function isEqual(a: Value, b: Value): boolean {
|
|||
}
|
||||
return true
|
||||
}
|
||||
case 'function': return false // functions never equal
|
||||
case 'regex': {
|
||||
if (!(b instanceof RegExp)) return false
|
||||
return String(a.value) === String(b.value)
|
||||
}
|
||||
case 'function':
|
||||
return false // functions never equal
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function fromValue(v: Value): any {
|
||||
switch (v.type) {
|
||||
case 'null': return null
|
||||
case 'boolean': return v.value
|
||||
case 'number': return v.value
|
||||
case 'string': return v.value
|
||||
case 'array': return v.value.map(fromValue)
|
||||
case 'dict': return Object.fromEntries(v.value.entries().map(([k, v]) => [k, fromValue(v)]))
|
||||
case 'function': return '<function>'
|
||||
case 'null':
|
||||
return null
|
||||
case 'boolean':
|
||||
return v.value
|
||||
case 'number':
|
||||
return v.value
|
||||
case 'string':
|
||||
return v.value
|
||||
case 'array':
|
||||
return v.value.map(fromValue)
|
||||
case 'dict':
|
||||
return Object.fromEntries(v.value.entries().map(([k, v]) => [k, fromValue(v)]))
|
||||
case 'regex':
|
||||
return v.value
|
||||
case 'function':
|
||||
return '<function>'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user