nv-constexpr-simple-codify 1.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/README.md +121 -0
- package/TEST/tst.js +156 -0
- package/index.d.ts +84 -0
- package/index.js +210 -0
- package/package.json +12 -0
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# nv-constexpr-simple-codify
|
|
2
|
+
|
|
3
|
+
A slow but precise object-to-code converter designed specifically for **macro compilation tools** and compile-time code generation.
|
|
4
|
+
|
|
5
|
+
Its a readable But less-suportted-type version of nv-buf-data-to-code.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## ⚠️ Important Notice
|
|
10
|
+
|
|
11
|
+
This library is **NOT optimized for performance**. It is intentionally slow because it generates executable JavaScript code rather than serialized data. Use it only when you need:
|
|
12
|
+
|
|
13
|
+
- Compile-time constant evaluation
|
|
14
|
+
- Macro expansion systems
|
|
15
|
+
- Generating code from configuration objects
|
|
16
|
+
- Static analysis tools that output executable code
|
|
17
|
+
|
|
18
|
+
Do NOT use this for runtime serialization or high-frequency operations.
|
|
19
|
+
|
|
20
|
+
## Supported Leaf Types (1:1 C++ Mapping)
|
|
21
|
+
|
|
22
|
+
Every supported leaf type has a direct 1:1 counterpart in C++. This makes the output ideal for generating C++ constexpr-compatible code.
|
|
23
|
+
|
|
24
|
+
| JavaScript Type | C++ Equivalent | Output Format | Example |
|
|
25
|
+
|-----------------|----------------|---------------|---------|
|
|
26
|
+
| `undefined` | Special NaN sentinel | `undefined` | `undefined` *(see note below)* |
|
|
27
|
+
| `null` | `std::nullptr_t` / `NULL` | `null` | `null` |
|
|
28
|
+
| `boolean` | `bool` | `true` / `false` | `true` |
|
|
29
|
+
| `string` | `std::string` / `const char*` | JSON-stringified | `"hello\nworld"` |
|
|
30
|
+
| `number` | `double` / `float` / `int` | String representation | `123.45` |
|
|
31
|
+
| `bigint` | `std::int64_t` / `std::uint64_t` | `n` suffix notation | `9007199254740993n` |
|
|
32
|
+
| `ArrayBuffer` | `std::array<uint8_t>` (raw buffer) | IIFE with byte array | `(()=>{ var ab = new ArrayBuffer(8);(new Uint8Array(ab)).set([0,32,64,96,128,160,192,224]);return(ab);})()` |
|
|
33
|
+
| `SharedArrayBuffer` | `std::shared_ptr<std::array<uint8_t>>` | IIFE with byte array | Same format as ArrayBuffer |
|
|
34
|
+
| `DataView` | `struct` with manual byte access | `new DataView(...)` | `(new DataView((new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])).buffer))` |
|
|
35
|
+
| `Uint8Array` | `std::array<uint8_t>` | `new Uint8Array([...])` | `(new Uint8Array([1,2,255]))` |
|
|
36
|
+
| `Uint8ClampedArray` | `std::array<uint8_t>` (clamped) | `new Uint8ClampedArray([...])` | `(new Uint8ClampedArray([0,128,255]))` |
|
|
37
|
+
| `Int8Array` | `std::array<int8_t>` | `new Int8Array([...])` | `(new Int8Array([-128,0,127]))` |
|
|
38
|
+
| `Uint16Array` | `std::array<uint16_t>` | `new Uint16Array([...])` | `(new Uint16Array([1,65535]))` |
|
|
39
|
+
| `Int16Array` | `std::array<int16_t>` | `new Int16Array([...])` | `(new Int16Array([-32768,32767]))` |
|
|
40
|
+
| `Uint32Array` | `std::array<uint32_t>` | `new Uint32Array([...])` | `(new Uint32Array([1,4294967295]))` |
|
|
41
|
+
| `Int32Array` | `std::array<int32_t>` | `new Int32Array([...])` | `(new Int32Array([-2147483648,2147483647]))` |
|
|
42
|
+
| `Float32Array` | `std::array<float>` | `new Float32Array([...])` | `(new Float32Array([1.5,-2.5,0]))` |
|
|
43
|
+
| `Float64Array` | `std::array<double>` | `new Float64Array([...])` | `(new Float64Array([1.7976931348623157e+308,-Infinity,NaN]))` |
|
|
44
|
+
| `BigUint64Array` | `std::array<uint64_t>` | `new BigUint64Array([...])` | `(new BigUint64Array([18446744073709551615n]))` |
|
|
45
|
+
| `BigInt64Array` | `std::array<int64_t>` | `new BigInt64Array([...])` | `(new BigInt64Array([-9223372036854775808n]))` |
|
|
46
|
+
| `Date` | `std::chrono::system_clock::time_point` | `new Date(timestamp)` | `(new Date(1705321845123))` |
|
|
47
|
+
| `RegExp` | `do NOT use std::regex` | `/pattern/flags` | `/test\/pattern/gi` |
|
|
48
|
+
|
|
49
|
+
### Special Note on `undefined`
|
|
50
|
+
|
|
51
|
+
`undefined` does not have a direct C++ equivalent. In C++ code generation scenarios, it should be replaced with a **special NaN sentinel value** (nan is a range)`) or a designated invalid marker. The codifier outputs `undefined` as-is for transparency, leaving the C++ mapping decision to the downstream compiler logic.
|
|
52
|
+
|
|
53
|
+
`RegExp` use a third-party library that supports compile-time regex (do NOT use std::regex)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
## Container Support
|
|
57
|
+
|
|
58
|
+
**Only two container types are supported:**
|
|
59
|
+
|
|
60
|
+
1. **Arrays `[]`** - Indexed collections
|
|
61
|
+
2. **Plain Objects `{}`** - String-keyed collections
|
|
62
|
+
|
|
63
|
+
Nested structures are fully supported (arrays within objects, objects within arrays, etc.).
|
|
64
|
+
|
|
65
|
+
**Unsupported containers:**
|
|
66
|
+
- `Map` - Not supported
|
|
67
|
+
- `Set` - Not supported
|
|
68
|
+
- `WeakMap` - Not supported
|
|
69
|
+
- `WeakSet` - Not supported
|
|
70
|
+
- `Array-like objects` - Not supported
|
|
71
|
+
- Custom classes/constructors - Not supported
|
|
72
|
+
|
|
73
|
+
## API
|
|
74
|
+
|
|
75
|
+
### `codify(obj, space = 0)`
|
|
76
|
+
|
|
77
|
+
Main entry point. Converts an object to a code string.
|
|
78
|
+
|
|
79
|
+
- `obj` - The object to convert (must contain only supported types)
|
|
80
|
+
- `space` - Optional indentation:
|
|
81
|
+
- `0` or `""` (empty string) - No indentation, compact output
|
|
82
|
+
- `number` - Number of spaces per level
|
|
83
|
+
- `string` - Custom indentation string
|
|
84
|
+
|
|
85
|
+
Returns: `string` - Executable JavaScript code
|
|
86
|
+
|
|
87
|
+
### Internal Functions
|
|
88
|
+
|
|
89
|
+
For advanced use cases, the following internal functions are exported:
|
|
90
|
+
|
|
91
|
+
- `_codify_leaf(o)` - Convert a single leaf value
|
|
92
|
+
- `_codify_ary(ary, depth, space, recv, is_lst, key)` - Process arrays
|
|
93
|
+
- `_codify_dict(dict, depth, space, recv, is_lst, key)` - Process objects
|
|
94
|
+
- `_codify_typed_ary(o, Cls)` - Convert TypedArrays/DataView
|
|
95
|
+
- `_codify_ab(o, ClsName)` - Convert ArrayBuffer/SharedArrayBuffer
|
|
96
|
+
|
|
97
|
+
## Use Cases
|
|
98
|
+
|
|
99
|
+
This tool is designed for:
|
|
100
|
+
|
|
101
|
+
1. **Macro Compilation Systems** - Generate code at compile time
|
|
102
|
+
2. **Static Configuration** - Convert config objects to constants
|
|
103
|
+
3. **Code Generation Tools** - Build source code from templates
|
|
104
|
+
4. **Build-time Optimizations** - Pre-compute values during build
|
|
105
|
+
5. **Domain-Specific Languages** - Implement DSL compilers
|
|
106
|
+
|
|
107
|
+
## Performance Note
|
|
108
|
+
|
|
109
|
+
This library prioritizes **code fidelity** over **execution speed**. It is significantly slower than `JSON.stringify` because:
|
|
110
|
+
|
|
111
|
+
- It generates executable code, not just data
|
|
112
|
+
- It handles many more data types
|
|
113
|
+
- It performs recursive processing with string building
|
|
114
|
+
- It's not optimized for large datasets
|
|
115
|
+
|
|
116
|
+
Do NOT use it For runtime serialization.
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
Any
|
|
120
|
+
|
|
121
|
+
|
package/TEST/tst.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
const codify = require('../index');
|
|
2
|
+
|
|
3
|
+
var code0 = codify({
|
|
4
|
+
undef: undefined,
|
|
5
|
+
nil: null,
|
|
6
|
+
boolTrue: true,
|
|
7
|
+
boolFalse: false,
|
|
8
|
+
str: "hello\"world\n\t\\test",
|
|
9
|
+
num: 12345.6789,
|
|
10
|
+
bigint: 9007199254740993n,
|
|
11
|
+
// TypedArrays
|
|
12
|
+
uint8: new Uint8Array([1, 2, 255]),
|
|
13
|
+
uint8c: new Uint8ClampedArray([0, 128, 255]),
|
|
14
|
+
int8: new Int8Array([-128, 0, 127]),
|
|
15
|
+
uint16: new Uint16Array([1, 65535]),
|
|
16
|
+
int16: new Int16Array([-32768, 32767]),
|
|
17
|
+
uint32: new Uint32Array([1, 4294967295]),
|
|
18
|
+
int32: new Int32Array([-2147483648, 2147483647]),
|
|
19
|
+
float32: new Float32Array([1.5, -2.5, 0.0]),
|
|
20
|
+
float64: new Float64Array([1.7976931348623157e+308, -Infinity, NaN]),
|
|
21
|
+
biguint64: new BigUint64Array([18446744073709551615n]),
|
|
22
|
+
bigint64: new BigInt64Array([-9223372036854775808n]),
|
|
23
|
+
|
|
24
|
+
// ArrayBuffers 和 SharedArrayBuffer
|
|
25
|
+
arrBuf: new ArrayBuffer(8),
|
|
26
|
+
//sharedArrBuf: new SharedArrayBuffer ? new SharedArrayBuffer(8) : null,
|
|
27
|
+
|
|
28
|
+
// DateView 和 Date
|
|
29
|
+
dateView: new DataView(new ArrayBuffer(16)),
|
|
30
|
+
date: new Date('2024-01-15T12:30:45.123Z'),
|
|
31
|
+
|
|
32
|
+
// RegExp
|
|
33
|
+
regex: /test\/pattern/gi,
|
|
34
|
+
}, 4);
|
|
35
|
+
console.log(code0);
|
|
36
|
+
|
|
37
|
+
var code1 = codify([
|
|
38
|
+
undefined,
|
|
39
|
+
null,
|
|
40
|
+
true,
|
|
41
|
+
false,
|
|
42
|
+
"hello\"world\n\t\\test",
|
|
43
|
+
12345.6789,
|
|
44
|
+
9007199254740993n,
|
|
45
|
+
// TypedArrays
|
|
46
|
+
new Uint8Array([1, 2, 255]),
|
|
47
|
+
new Uint8ClampedArray([0, 128, 255]),
|
|
48
|
+
new Int8Array([-128, 0, 127]),
|
|
49
|
+
new Uint16Array([1, 65535]),
|
|
50
|
+
new Int16Array([-32768, 32767]),
|
|
51
|
+
new Uint32Array([1, 4294967295]),
|
|
52
|
+
new Int32Array([-2147483648, 2147483647]),
|
|
53
|
+
new Float32Array([1.5, -2.5, 0.0]),
|
|
54
|
+
new Float64Array([1.7976931348623157e+308, -Infinity, NaN]),
|
|
55
|
+
new BigUint64Array([18446744073709551615n]),
|
|
56
|
+
new BigInt64Array([-9223372036854775808n]),
|
|
57
|
+
|
|
58
|
+
// ArrayBuffers 和 SharedArrayBuffer
|
|
59
|
+
new ArrayBuffer(8),
|
|
60
|
+
//sharedArrBuf: new SharedArrayBuffer ? new SharedArrayBuffer(8) : null,
|
|
61
|
+
|
|
62
|
+
// DateView 和 Date
|
|
63
|
+
new DataView(new ArrayBuffer(16)),
|
|
64
|
+
new Date('2024-01-15T12:30:45.123Z'),
|
|
65
|
+
|
|
66
|
+
// RegExp
|
|
67
|
+
/test\/pattern/gi,
|
|
68
|
+
], 4);
|
|
69
|
+
console.log(code1);
|
|
70
|
+
|
|
71
|
+
console.log(codify({
|
|
72
|
+
level3: 789n,
|
|
73
|
+
arr: [1n, 2n, 3n]
|
|
74
|
+
|
|
75
|
+
},2));
|
|
76
|
+
|
|
77
|
+
// ============ 构造复杂测试对象 ============
|
|
78
|
+
function createComplexTestObject() {
|
|
79
|
+
return {
|
|
80
|
+
// 基础类型
|
|
81
|
+
undef: undefined,
|
|
82
|
+
nil: null,
|
|
83
|
+
boolTrue: true,
|
|
84
|
+
boolFalse: false,
|
|
85
|
+
str: "hello\"world\n\t\\test",
|
|
86
|
+
num: 12345.6789,
|
|
87
|
+
bigint: 9007199254740993n,
|
|
88
|
+
|
|
89
|
+
// TypedArrays
|
|
90
|
+
uint8: new Uint8Array([1, 2, 255]),
|
|
91
|
+
uint8c: new Uint8ClampedArray([0, 128, 255]),
|
|
92
|
+
int8: new Int8Array([-128, 0, 127]),
|
|
93
|
+
uint16: new Uint16Array([1, 65535]),
|
|
94
|
+
int16: new Int16Array([-32768, 32767]),
|
|
95
|
+
uint32: new Uint32Array([1, 4294967295]),
|
|
96
|
+
int32: new Int32Array([-2147483648, 2147483647]),
|
|
97
|
+
float32: new Float32Array([1.5, -2.5, 0.0]),
|
|
98
|
+
float64: new Float64Array([1.7976931348623157e+308, -Infinity, NaN]),
|
|
99
|
+
biguint64: new BigUint64Array([18446744073709551615n]),
|
|
100
|
+
bigint64: new BigInt64Array([-9223372036854775808n]),
|
|
101
|
+
|
|
102
|
+
// ArrayBuffers 和 SharedArrayBuffer
|
|
103
|
+
arrBuf: new ArrayBuffer(8),
|
|
104
|
+
//sharedArrBuf: new SharedArrayBuffer ? new SharedArrayBuffer(8) : null,
|
|
105
|
+
|
|
106
|
+
// DateView 和 Date
|
|
107
|
+
dateView: new DataView(new ArrayBuffer(16)),
|
|
108
|
+
date: new Date('2024-01-15T12:30:45.123Z'),
|
|
109
|
+
|
|
110
|
+
// RegExp
|
|
111
|
+
regex: /test\/pattern/gi,
|
|
112
|
+
|
|
113
|
+
// 嵌套数组
|
|
114
|
+
nestedArr: [
|
|
115
|
+
1,
|
|
116
|
+
2n,
|
|
117
|
+
"string",
|
|
118
|
+
true,
|
|
119
|
+
[3, 4n, [5, 6n]],
|
|
120
|
+
{ nested: "object" }
|
|
121
|
+
],
|
|
122
|
+
|
|
123
|
+
// 嵌套对象
|
|
124
|
+
nestedObj: {
|
|
125
|
+
level1: {
|
|
126
|
+
level2: {
|
|
127
|
+
level3: 789n,
|
|
128
|
+
arr: [1n, 2n, 3n]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// 数组中包含对象
|
|
134
|
+
arrWithObjs: [
|
|
135
|
+
{ id: 1, val: 10n },
|
|
136
|
+
{ id: 2, val: 20n }
|
|
137
|
+
]
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ============ 填充 ArrayBuffer 数据 ============
|
|
142
|
+
function fillArrayBuffer(buf) {
|
|
143
|
+
const u8 = new Uint8Array(buf);
|
|
144
|
+
for (let i = 0; i < u8.length; i++) {
|
|
145
|
+
u8[i] = i * 32;
|
|
146
|
+
}
|
|
147
|
+
return buf;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const testObj = createComplexTestObject();
|
|
151
|
+
fillArrayBuffer(testObj.arrBuf);
|
|
152
|
+
console.dir(testObj,{depth:null});
|
|
153
|
+
|
|
154
|
+
const generatedCode = codify(testObj, 2);
|
|
155
|
+
console.log(generatedCode);
|
|
156
|
+
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codify - A slow but precise object to code converter for macro compilation tools
|
|
3
|
+
*
|
|
4
|
+
* This module converts JavaScript objects into executable code strings.
|
|
5
|
+
* It is designed for compile-time code generation, not runtime serialization.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const code = codify({ foo: 1n, bar: [1, 2, 3] }, 2);
|
|
9
|
+
* // Returns formatted code string that can be eval'd
|
|
10
|
+
*/
|
|
11
|
+
declare function codify(obj: unknown, space?: number | string): string;
|
|
12
|
+
|
|
13
|
+
declare namespace codify {
|
|
14
|
+
/**
|
|
15
|
+
* Convert a TypedArray or DataView to a code representation
|
|
16
|
+
* @param o - The typed array or DataView instance
|
|
17
|
+
* @param Cls - The constructor class (e.g., Uint8Array, Int16Array)
|
|
18
|
+
* @returns Code string representing the array contents
|
|
19
|
+
*/
|
|
20
|
+
function _codify_typed_ary(o: TypedArray | DataView, Cls: new (buffer: ArrayBuffer) => TypedArray): string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Convert an ArrayBuffer or SharedArrayBuffer to executable code
|
|
24
|
+
* @param o - The buffer instance
|
|
25
|
+
* @param ClsName - Class name as string ("ArrayBuffer" or "SharedArrayBuffer")
|
|
26
|
+
* @returns Immediately invoked function expression that recreates the buffer
|
|
27
|
+
*/
|
|
28
|
+
function _codify_ab(o: ArrayBuffer | SharedArrayBuffer, ClsName: string): string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Convert leaf nodes (non-container values) to code representation
|
|
32
|
+
* @param o - Any leaf node value
|
|
33
|
+
* @returns Code string or undefined if value needs recursive processing
|
|
34
|
+
*/
|
|
35
|
+
function _codify_leaf(o: unknown): string | undefined;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Process arrays recursively and build code string
|
|
39
|
+
* @param ary - Array to process
|
|
40
|
+
* @param depth - Current indentation depth
|
|
41
|
+
* @param space - Indentation string
|
|
42
|
+
* @param recv - Accumulated result string
|
|
43
|
+
* @param is_lst - Whether this is the last element in parent container
|
|
44
|
+
* @param key - Key name if processing as object property
|
|
45
|
+
* @returns Updated result string
|
|
46
|
+
*/
|
|
47
|
+
function _codify_ary(
|
|
48
|
+
ary: unknown[],
|
|
49
|
+
depth: number,
|
|
50
|
+
space: string,
|
|
51
|
+
recv: string,
|
|
52
|
+
is_lst: boolean,
|
|
53
|
+
key?: string | undefined
|
|
54
|
+
): string;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Process plain objects recursively and build code string
|
|
58
|
+
* @param dict - Plain object to process
|
|
59
|
+
* @param depth - Current indentation depth
|
|
60
|
+
* @param space - Indentation string
|
|
61
|
+
* @param recv - Accumulated result string
|
|
62
|
+
* @param is_lst - Whether this is the last element in parent container
|
|
63
|
+
* @param key - Key name if processing as nested property
|
|
64
|
+
* @returns Updated result string
|
|
65
|
+
*/
|
|
66
|
+
function _codify_dict(
|
|
67
|
+
dict: Record<string, unknown>,
|
|
68
|
+
depth: number,
|
|
69
|
+
space: string,
|
|
70
|
+
recv: string,
|
|
71
|
+
is_lst: boolean,
|
|
72
|
+
key?: string | undefined
|
|
73
|
+
): string;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Internal recursive codify implementation
|
|
77
|
+
* @param obj - Object to convert
|
|
78
|
+
* @param space - Indentation string
|
|
79
|
+
* @returns Generated code string
|
|
80
|
+
*/
|
|
81
|
+
function _codify(obj: unknown, space: string): string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export = codify;
|
package/index.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
const _codify_typed_ary = (o,Cls)=>{
|
|
2
|
+
var si = o.byteOffset;
|
|
3
|
+
var ei = si + o.byteLength;
|
|
4
|
+
var ta = new Cls(o.buffer);
|
|
5
|
+
var subvw = ta.subarray(si/Cls.BYTES_PER_ELEMENT,ei/Cls.BYTES_PER_ELEMENT);
|
|
6
|
+
var s ="[";
|
|
7
|
+
for(var i=0;i< subvw.length-1;++i) {
|
|
8
|
+
if(typeof(subvw[i]) === "bigint") {
|
|
9
|
+
s += subvw[i] + "n" + ","
|
|
10
|
+
} else {
|
|
11
|
+
s += subvw[i] + ","
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
if(subvw.length ===0) {
|
|
15
|
+
} else {
|
|
16
|
+
if(typeof(subvw[subvw.length-1]) === "bigint") {
|
|
17
|
+
s += subvw[subvw.length-1] + "n";
|
|
18
|
+
} else {
|
|
19
|
+
s += subvw[subvw.length-1]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
s += "]"
|
|
23
|
+
return(s)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const _codify_ab = (o,ClsName) => {
|
|
27
|
+
var u8a = new Uint8Array(o);
|
|
28
|
+
var u8a_str = JSON.stringify(Array.from(u8a));
|
|
29
|
+
var ab_str ;
|
|
30
|
+
if(o.resizable) {
|
|
31
|
+
ab_str = `new ${ClsName}(${o.byteLength},{maxByteLength:${o.maxByteLength}})`;
|
|
32
|
+
} else {
|
|
33
|
+
ab_str = `new ${ClsName}(${o.byteLength})`
|
|
34
|
+
}
|
|
35
|
+
return(`(()=>{ var ab = ${ab_str};(new Uint8Array(ab)).set(${u8a_str});return(ab);})()`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const _codify_leaf = (o)=>{
|
|
39
|
+
if(o instanceof ArrayBuffer) {
|
|
40
|
+
return (_codify_ab(o,"ArrayBuffer"));
|
|
41
|
+
} else if(o?.constructor?.name === 'SharedArrayBuffer') {
|
|
42
|
+
return (_codify_ab(o,"SharedArrayBuffer"));
|
|
43
|
+
} else if(o instanceof DataView){
|
|
44
|
+
return(`(new DataView((new Uint8Array(${_codify_typed_ary(o,Uint8Array)})).buffer))`);
|
|
45
|
+
} else if(o instanceof Uint8Array){
|
|
46
|
+
return(`(new Uint8Array(${_codify_typed_ary(o,Uint8Array)}))`);
|
|
47
|
+
} else if(o instanceof Uint8ClampedArray) {
|
|
48
|
+
return(`(new Uint8ClampedArray(${_codify_typed_ary(o,Uint8ClampedArray)}))`);
|
|
49
|
+
} else if(o instanceof Int8Array) {
|
|
50
|
+
return(`(new Int8Array(${_codify_typed_ary(o,Int8Array)}))`);
|
|
51
|
+
} else if(o instanceof Uint16Array) {
|
|
52
|
+
return(`(new Uint16Array(${_codify_typed_ary(o,Uint16Array)}))`);
|
|
53
|
+
} else if(o instanceof Int16Array) {
|
|
54
|
+
return(`(new Int16Array(${_codify_typed_ary(o,Int16Array)}))`);
|
|
55
|
+
} else if (o instanceof Uint32Array) {
|
|
56
|
+
return(`(new Uint32Array(${_codify_typed_ary(o,Uint32Array)}))`);
|
|
57
|
+
} else if (o instanceof Int32Array) {
|
|
58
|
+
return(`(new Int32Array(${_codify_typed_ary(o,Int32Array)}))`);
|
|
59
|
+
} else if(o instanceof BigUint64Array) {
|
|
60
|
+
return(`(new BigUint64Array(${_codify_typed_ary(o,BigUint64Array)}))`);
|
|
61
|
+
} else if(o instanceof BigInt64Array) {
|
|
62
|
+
return(`(new BigInt64Array(${_codify_typed_ary(o,BigInt64Array)}))`);
|
|
63
|
+
} else if(o instanceof Float32Array) {
|
|
64
|
+
return(`(new Float32Array(${_codify_typed_ary(o,Float32Array)}))`);
|
|
65
|
+
} else if(o instanceof Float64Array) {
|
|
66
|
+
return(`(new Float64Array(${_codify_typed_ary(o,Float64Array)}))`);
|
|
67
|
+
} else if(o instanceof Date) {
|
|
68
|
+
var mts = o.getTime();
|
|
69
|
+
return(`(new Date(${String(mts)}))`);
|
|
70
|
+
} else if(o instanceof RegExp) {
|
|
71
|
+
var source = o.source;
|
|
72
|
+
var flags = o.flags;
|
|
73
|
+
return `/${source}/${flags}`
|
|
74
|
+
} else if(o === undefined){
|
|
75
|
+
return "undefined"
|
|
76
|
+
} else if(o === null) {
|
|
77
|
+
return "null";
|
|
78
|
+
} else {
|
|
79
|
+
var tnm = typeof(o);
|
|
80
|
+
if(tnm === "string") {
|
|
81
|
+
return JSON.stringify(o)
|
|
82
|
+
} else if(tnm === "number") {
|
|
83
|
+
return String(o)
|
|
84
|
+
} else if(tnm === "boolean") {
|
|
85
|
+
return o?"true":"false"
|
|
86
|
+
} else if(tnm === "bigint"){
|
|
87
|
+
return String(o) + "n";
|
|
88
|
+
} else {
|
|
89
|
+
return undefined
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
function _codify_ary(ary,depth,space,recv,is_lst,key) {
|
|
96
|
+
var indent_str = space.repeat(depth);
|
|
97
|
+
var nl = space===""? "":"\n";
|
|
98
|
+
key = key===undefined?"":(JSON.stringify(key) + " : ");
|
|
99
|
+
if(ary.length === 0) {
|
|
100
|
+
recv += indent_str + key + "[]" + (is_lst?"":",") + nl;
|
|
101
|
+
} else {
|
|
102
|
+
recv += indent_str + key+"[" + nl;
|
|
103
|
+
for(var i=0; i<ary.length-1;++i) {
|
|
104
|
+
var v = ary[i];
|
|
105
|
+
if(Array.isArray(v)) {
|
|
106
|
+
recv = _codify_ary(v,depth+1,space,recv,false,undefined)
|
|
107
|
+
} else {
|
|
108
|
+
var cv = _codify_leaf(v);
|
|
109
|
+
if(cv===undefined) {
|
|
110
|
+
recv = _codify_dict(v,depth+1,space,recv,false,undefined)
|
|
111
|
+
} else {
|
|
112
|
+
var child_indent_str = space.repeat(depth+1);
|
|
113
|
+
recv += child_indent_str + cv + "," + nl;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
////
|
|
118
|
+
{
|
|
119
|
+
var v = ary[ary.length-1];
|
|
120
|
+
if(Array.isArray(v)) {
|
|
121
|
+
recv = _codify_ary(v,depth+1,space,recv,true,undefined)
|
|
122
|
+
} else {
|
|
123
|
+
var cv = _codify_leaf(v);
|
|
124
|
+
if(cv===undefined) {
|
|
125
|
+
recv = _codify_dict(v,depth+1,space,recv,true,undefined)
|
|
126
|
+
} else {
|
|
127
|
+
var child_indent_str = space.repeat(depth+1);
|
|
128
|
+
recv += child_indent_str + cv + nl;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
recv += indent_str + "]" + (is_lst?"":",") + nl;
|
|
133
|
+
}
|
|
134
|
+
return recv;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function _codify_dict(dict,depth,space,recv,is_lst,key) {
|
|
138
|
+
var indent_str = space.repeat(depth);
|
|
139
|
+
var nl = space===""? "":"\n";
|
|
140
|
+
key = key===undefined?"":(JSON.stringify(key) + " : ");
|
|
141
|
+
var ks = Object.keys(dict);
|
|
142
|
+
if(ks.length === 0) {
|
|
143
|
+
recv += indent_str + key + "{}" + (is_lst?"":",") + nl;
|
|
144
|
+
} else {
|
|
145
|
+
recv += indent_str + key+"{" + nl;
|
|
146
|
+
for(var i=0;i<ks.length-1;++i) {
|
|
147
|
+
var v = dict[ks[i]];
|
|
148
|
+
if(Array.isArray(v)) {
|
|
149
|
+
recv = _codify_ary(v,depth+1,space,recv,false,ks[i])
|
|
150
|
+
} else {
|
|
151
|
+
var cv = _codify_leaf(v);
|
|
152
|
+
if(cv === undefined) {
|
|
153
|
+
recv = _codify_dict(v,depth+1,space,recv,false,ks[i])
|
|
154
|
+
} else {
|
|
155
|
+
var child_indent_str = space.repeat(depth+1);
|
|
156
|
+
recv += child_indent_str + JSON.stringify(ks[i]) + " : " + cv + "," + nl;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
////
|
|
161
|
+
{
|
|
162
|
+
var k = ks[ks.length-1];
|
|
163
|
+
var v = dict[k];
|
|
164
|
+
if(Array.isArray(v)) {
|
|
165
|
+
recv = _codify_ary(v,depth+1,space,recv,true,k)
|
|
166
|
+
} else {
|
|
167
|
+
var cv = _codify_leaf(v);
|
|
168
|
+
if(cv === undefined) {
|
|
169
|
+
recv = _codify_dict(v,depth+1,space,recv,true,k)
|
|
170
|
+
} else {
|
|
171
|
+
var child_indent_str = space.repeat(depth+1);
|
|
172
|
+
recv += child_indent_str + JSON.stringify(ks[ks.length-1]) + " : " + cv + nl;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
var end = indent_str + "}" + (is_lst?"":",") + nl;
|
|
177
|
+
recv += end;
|
|
178
|
+
}
|
|
179
|
+
return recv;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function _codify(obj,space) {
|
|
183
|
+
if(Array.isArray(obj)) {
|
|
184
|
+
return _codify_ary(obj,0,space,"",true,undefined);
|
|
185
|
+
} else {
|
|
186
|
+
var cv = _codify_leaf(obj);
|
|
187
|
+
if(cv === undefined) {
|
|
188
|
+
return _codify_dict(obj,0,space,"",true,undefined);
|
|
189
|
+
} else {
|
|
190
|
+
return _codify_leaf(obj)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function codify (obj,space=0){
|
|
196
|
+
if(typeof(space)==="number") {space = " ".repeat(space)} else {space = String(space)}
|
|
197
|
+
return _codify(obj,space);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
module.exports = codify;
|
|
203
|
+
module.exports._codify_typed_ary = _codify_typed_ary;
|
|
204
|
+
module.exports._codify_ab = _codify_ab;
|
|
205
|
+
module.exports._codify_leaf = _codify_leaf;
|
|
206
|
+
module.exports._codify_ary = _codify_ary;
|
|
207
|
+
module.exports._codify_dict = _codify_dict;
|
|
208
|
+
module.exports._codify = _codify;
|
|
209
|
+
|
|
210
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nv-constexpr-simple-codify",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"author": "",
|
|
9
|
+
"license": "ISC",
|
|
10
|
+
"description": "A slow but precise object-to-code converter designed specifically for **macro compilation tools** and compile-time code generation.",
|
|
11
|
+
"types": "./index.d.ts"
|
|
12
|
+
}
|