simplex-lang 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/utils.ts ADDED
@@ -0,0 +1,119 @@
1
+ /* eslint-disable @typescript-eslint/unbound-method */
2
+ import { UnexpectedTypeError } from './errors.js'
3
+
4
+ /**
5
+ * Converts instances of Number, String and Boolean to primitives
6
+ */
7
+ export function unbox(value: unknown) {
8
+ if (typeof value !== 'object') return value
9
+
10
+ if (
11
+ value instanceof Number ||
12
+ value instanceof String ||
13
+ value instanceof Boolean
14
+ ) {
15
+ return value.valueOf()
16
+ }
17
+
18
+ return value
19
+ }
20
+
21
+ export function num(val: unknown): number {
22
+ val = unbox(val)
23
+
24
+ if (typeof val !== 'number' || Number.isFinite(val) === false) {
25
+ throw new UnexpectedTypeError('number', prettyType(val))
26
+ }
27
+
28
+ return val
29
+ }
30
+
31
+ export function toStr(val: unknown): string {
32
+ val = unbox(val)
33
+
34
+ const type = typeof val
35
+
36
+ if (type === 'string') return val as string
37
+ if (type === 'number' || type === 'boolean' || type === 'bigint') {
38
+ return String(val)
39
+ }
40
+
41
+ throw new UnexpectedTypeError('string', prettyType(val))
42
+ }
43
+
44
+ export function relComp(val: unknown): number | string | bigint {
45
+ val = unbox(val)
46
+
47
+ const type = typeof val
48
+
49
+ if (type !== 'number' && type !== 'string' && type !== 'bigint') {
50
+ throw new UnexpectedTypeError('number or string', prettyType(val))
51
+ }
52
+
53
+ return val as number | string | bigint
54
+ }
55
+
56
+ export function bool(val: unknown): boolean {
57
+ return Boolean(unbox(val))
58
+ }
59
+
60
+ export function ensureFunction(val: unknown): Function {
61
+ if (typeof val === 'function') return val
62
+ throw new UnexpectedTypeError('function', prettyType(val))
63
+ }
64
+
65
+ var objToStrProto = Object.prototype.toString
66
+
67
+ export function isObj(val: unknown): val is object {
68
+ return objToStrProto.call(val) === '[object Object]'
69
+ }
70
+
71
+ export function isSimple(
72
+ val: unknown
73
+ ): val is number | string | boolean | bigint | null | undefined {
74
+ val = unbox(val)
75
+
76
+ const type = typeof val
77
+
78
+ if (
79
+ type === 'string' ||
80
+ type === 'number' ||
81
+ type === 'boolean' ||
82
+ type === 'bigint'
83
+ ) {
84
+ return true
85
+ }
86
+
87
+ if (val == null) return true
88
+
89
+ return false
90
+ }
91
+
92
+ /**
93
+ * Returns the type of a value in a neat, user-readable way
94
+ */
95
+ export function prettyType(val: unknown) {
96
+ val = unbox(val)
97
+
98
+ if (val === undefined) return 'undefined'
99
+ if (val === null) return 'null'
100
+ if (val === true) return 'true'
101
+ if (val === false) return 'false'
102
+
103
+ const type = typeof val
104
+
105
+ if (type === 'number') {
106
+ if (Number.isFinite(val)) return 'number'
107
+ else if (val === Number.NEGATIVE_INFINITY) return '-infinity'
108
+ else if (val === Number.POSITIVE_INFINITY) return 'infinity'
109
+ else return 'NaN'
110
+ }
111
+
112
+ if (type === 'string') return 'string'
113
+
114
+ if (type !== 'object' && type !== 'function') return 'unknown type' // TODO Get more detailed type info
115
+
116
+ if (Array.isArray(val)) return 'array'
117
+
118
+ return 'object'
119
+ }