porffor 0.0.0-828ee15 → 0.0.0-b5da8c4
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 +44 -11
- package/c +0 -0
- package/c.exe +0 -0
- package/compiler/2c.js +255 -0
- package/compiler/builtins.js +0 -1
- package/compiler/codeGen.js +330 -76
- package/compiler/decompile.js +3 -3
- package/compiler/encoding.js +4 -2
- package/compiler/index.js +53 -2
- package/compiler/opt.js +35 -5
- package/compiler/parse.js +2 -1
- package/compiler/prototype.js +4 -5
- package/compiler/sections.js +28 -2
- package/compiler/wrap.js +12 -1
- package/cool.exe +0 -0
- package/g +0 -0
- package/g.exe +0 -0
- package/hi.c +37 -0
- package/out +0 -0
- package/package.json +1 -1
- package/r.js +1 -0
- package/rhemyn/README.md +37 -0
- package/rhemyn/compile.js +214 -0
- package/rhemyn/parse.js +319 -0
- package/rhemyn/test/parse.js +59 -0
- package/runner/index.js +52 -33
- package/runner/repl.js +6 -11
- package/runner/transform.js +5 -26
- package/runner/version.js +10 -0
- package/t.js +31 -0
- package/tmp.c +37 -0
package/rhemyn/parse.js
ADDED
@@ -0,0 +1,319 @@
|
|
1
|
+
const State = {
|
2
|
+
none: 0,
|
3
|
+
insideSet: 1
|
4
|
+
};
|
5
|
+
|
6
|
+
const Quantifiers = {
|
7
|
+
'*': [ 0 ], // 0 -
|
8
|
+
'+': [ 1 ], // 1 -
|
9
|
+
'?': [ 0, 1 ], // 0 - 1
|
10
|
+
};
|
11
|
+
const QuantifierKeys = Object.keys(Quantifiers);
|
12
|
+
|
13
|
+
const getArg = (name, def) => {
|
14
|
+
const arg = (typeof process !== 'undefined' ? process.argv : Deno.args).find(x => x.startsWith(`-${name}=`));
|
15
|
+
if (arg) return arg.split('=')[0];
|
16
|
+
|
17
|
+
return def;
|
18
|
+
};
|
19
|
+
|
20
|
+
// full is spec-compliant but slower. not needed most of the time. (evil)
|
21
|
+
const DotChars = () => ({
|
22
|
+
full: [ '\n', '\r', '\u2028', '\u2029' ],
|
23
|
+
simple: [ '\n', '\r' ],
|
24
|
+
fast: [ '\n' ]
|
25
|
+
})[getArg('regex-dot', 'fast')];
|
26
|
+
|
27
|
+
const WordChars = () => ({
|
28
|
+
full: [ [ 'a', 'z' ], [ 'A', 'Z' ], [ '0', '9' ], '_' ],
|
29
|
+
fast: [ [ '_', 'z' ], [ 'A', 'Z' ], [ '0', '9' ] ] // skip individual _ with _-z BUT it also matches '`'
|
30
|
+
})[getArg('regex-word', 'full')];
|
31
|
+
|
32
|
+
const WhitespaceChars = () => ({
|
33
|
+
full: [ ' ', '\t', '\n', '\r', '\u2028', '\u2029' ],
|
34
|
+
simple: [ ' ', '\t', '\n', '\r' ]
|
35
|
+
})[getArg('regex-ws', 'simple')];
|
36
|
+
|
37
|
+
const Metachars = {
|
38
|
+
unescaped: {
|
39
|
+
'.': [ DotChars(), true ], // dot
|
40
|
+
},
|
41
|
+
escaped: {
|
42
|
+
d: [ [ [ '0', '9' ] ], false ], // digit
|
43
|
+
D: [ [ [ '0', '9' ] ], true ], // not digit
|
44
|
+
w: [ WordChars(), false ], // word
|
45
|
+
W: [ WordChars(), true ], // not word
|
46
|
+
s: [ WhitespaceChars(), false ], // whitespace
|
47
|
+
S: [ WhitespaceChars(), true ], // not whitespace
|
48
|
+
}
|
49
|
+
};
|
50
|
+
|
51
|
+
const EscapeSequences = {
|
52
|
+
f: '\f',
|
53
|
+
n: '\n',
|
54
|
+
r: '\r',
|
55
|
+
t: '\t',
|
56
|
+
v: '\v',
|
57
|
+
'0': '\0'
|
58
|
+
};
|
59
|
+
|
60
|
+
const HexDigit = /[0-9a-fA-F]/;
|
61
|
+
|
62
|
+
export default str => {
|
63
|
+
const out = {
|
64
|
+
type: 'Expression',
|
65
|
+
body: []
|
66
|
+
};
|
67
|
+
let node = out, parents = [];
|
68
|
+
|
69
|
+
let state = State.none, setIndex = 0, escape = false;
|
70
|
+
for (let i = 0; i < str.length; i++) {
|
71
|
+
const c = str[i];
|
72
|
+
|
73
|
+
const charNode = char => ({
|
74
|
+
type: 'Character',
|
75
|
+
char
|
76
|
+
});
|
77
|
+
|
78
|
+
const rangeNode = (from, to) => ({
|
79
|
+
type: 'Range',
|
80
|
+
from,
|
81
|
+
to
|
82
|
+
});
|
83
|
+
|
84
|
+
const addChar = (char = c) => {
|
85
|
+
node.body.push(charNode(char));
|
86
|
+
};
|
87
|
+
|
88
|
+
const addSet = (matches, negated = false) => {
|
89
|
+
let body = matches.map(x => x[1] ? rangeNode(x[0], x[1]) : charNode(x));
|
90
|
+
if (state === State.insideSet) {
|
91
|
+
// if negated, mark each node as negated for merge
|
92
|
+
if (negated) body = body.map(x => {
|
93
|
+
x.negated = true;
|
94
|
+
return x;
|
95
|
+
});
|
96
|
+
|
97
|
+
// already in set, merge bodies
|
98
|
+
node.body.push(...body);
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
|
102
|
+
node.body.push({
|
103
|
+
type: 'Set',
|
104
|
+
body,
|
105
|
+
negated
|
106
|
+
});
|
107
|
+
};
|
108
|
+
|
109
|
+
const addMetachar = meta => {
|
110
|
+
const [ matches, negated = false ] = meta;
|
111
|
+
return addSet(matches, negated);
|
112
|
+
};
|
113
|
+
|
114
|
+
// get next char and consume it
|
115
|
+
const seek = (allowEscaped = true) => {
|
116
|
+
const cNext = str[++i];
|
117
|
+
|
118
|
+
if (cNext === '\\') return !allowEscaped ? undefined : [ str[++i], true ];
|
119
|
+
return !allowEscaped ? cNext : [ cNext, false ];
|
120
|
+
};
|
121
|
+
|
122
|
+
// get next char without consuming
|
123
|
+
const peek = (allowEscaped = true, offset = 0) => {
|
124
|
+
const cNext = str[i + 1 + offset];
|
125
|
+
|
126
|
+
if (cNext === '\\') return !allowEscaped ? undefined : [ str[i + 2 + offset], true ];
|
127
|
+
return !allowEscaped ? cNext : [ cNext, false ];
|
128
|
+
};
|
129
|
+
|
130
|
+
if (escape) {
|
131
|
+
escape = false;
|
132
|
+
if (EscapeSequences[c]) {
|
133
|
+
addChar(EscapeSequences[c]);
|
134
|
+
continue;
|
135
|
+
}
|
136
|
+
|
137
|
+
if (Metachars.escaped[c]) {
|
138
|
+
addMetachar(Metachars.escaped[c]);
|
139
|
+
continue;
|
140
|
+
}
|
141
|
+
|
142
|
+
if (c === 'c') {
|
143
|
+
// \c (not [A-Za-z] ...) = literal \c... (WHY)
|
144
|
+
const next = peek(false);
|
145
|
+
if (next == null || /[^a-zA-Z]/.test(next)) {
|
146
|
+
addChar('\\');
|
147
|
+
addChar('c');
|
148
|
+
continue;
|
149
|
+
}
|
150
|
+
|
151
|
+
// \c[A-Za-z]
|
152
|
+
const code = seek(false).charCodeAt(0);
|
153
|
+
addChar(String.fromCharCode(code % 32));
|
154
|
+
continue;
|
155
|
+
}
|
156
|
+
|
157
|
+
if (c === 'x') {
|
158
|
+
// \x = x
|
159
|
+
// \xH = xH
|
160
|
+
// \x[0-9a-zA-Z][0-9a-zA-Z] = \xAB
|
161
|
+
const next1 = peek(false);
|
162
|
+
const next2 = peek(false, 1);
|
163
|
+
|
164
|
+
// missing a char or invalid hex digit
|
165
|
+
if (next1 == null || next2 == null || !HexDigit.test(next1) || !HexDigit.test(next2)) {
|
166
|
+
addChar('x');
|
167
|
+
continue;
|
168
|
+
}
|
169
|
+
|
170
|
+
const code = parseInt(seek(false) + seek(false), 16);
|
171
|
+
addChar(String.fromCodePoint(code));
|
172
|
+
continue;
|
173
|
+
}
|
174
|
+
|
175
|
+
if (c === 'u') {
|
176
|
+
// '\u' = u
|
177
|
+
// '\uHHH' = uHHH
|
178
|
+
// '\uABCD' = \uABCD
|
179
|
+
const next1 = peek(false);
|
180
|
+
const next2 = peek(false, 1);
|
181
|
+
const next3 = peek(false, 2);
|
182
|
+
const next4 = peek(false, 3);
|
183
|
+
|
184
|
+
// missing a char or invalid hex digit
|
185
|
+
if (next1 == null || next2 == null || next3 == null || next4 == null || !HexDigit.test(next1) || !HexDigit.test(next2) || !HexDigit.test(next3) || !HexDigit.test(next4)) {
|
186
|
+
addChar('u');
|
187
|
+
continue;
|
188
|
+
}
|
189
|
+
|
190
|
+
const code = parseInt(seek(false) + seek(false) + seek(false) + seek(false), 16);
|
191
|
+
addChar(String.fromCodePoint(code));
|
192
|
+
continue;
|
193
|
+
}
|
194
|
+
|
195
|
+
addChar();
|
196
|
+
continue;
|
197
|
+
}
|
198
|
+
|
199
|
+
if (c === '\\') {
|
200
|
+
escape = true;
|
201
|
+
continue;
|
202
|
+
}
|
203
|
+
|
204
|
+
switch (state) {
|
205
|
+
case State.none:
|
206
|
+
if (c === '[') {
|
207
|
+
parents.push(node);
|
208
|
+
node = {
|
209
|
+
type: 'Set',
|
210
|
+
body: [],
|
211
|
+
negated: false
|
212
|
+
};
|
213
|
+
|
214
|
+
parents.at(-1).body.push(node);
|
215
|
+
|
216
|
+
state = State.insideSet;
|
217
|
+
setIndex = 0;
|
218
|
+
continue;
|
219
|
+
}
|
220
|
+
|
221
|
+
if (c === '(') {
|
222
|
+
parents.push(node);
|
223
|
+
node = {
|
224
|
+
type: 'Group',
|
225
|
+
body: []
|
226
|
+
};
|
227
|
+
|
228
|
+
parents.at(-1).body.push(node);
|
229
|
+
continue;
|
230
|
+
}
|
231
|
+
|
232
|
+
if (c === ')') {
|
233
|
+
if (node.type !== 'Group') throw new SyntaxError('Unmatched closing parenthesis');
|
234
|
+
|
235
|
+
node = parents.pop();
|
236
|
+
continue;
|
237
|
+
}
|
238
|
+
|
239
|
+
if (QuantifierKeys.includes(c)) {
|
240
|
+
node.body.at(-1).quantifier = Quantifiers[c];
|
241
|
+
|
242
|
+
// lazy modifier
|
243
|
+
if (peek(false) === '?') node.body.at(-1).lazy = true;
|
244
|
+
|
245
|
+
continue;
|
246
|
+
}
|
247
|
+
|
248
|
+
if (Metachars.unescaped[c]) {
|
249
|
+
addMetachar(Metachars.unescaped[c]);
|
250
|
+
continue;
|
251
|
+
}
|
252
|
+
|
253
|
+
addChar();
|
254
|
+
break;
|
255
|
+
|
256
|
+
case State.insideSet:
|
257
|
+
setIndex++;
|
258
|
+
if (setIndex === 1) {
|
259
|
+
// first char in set
|
260
|
+
if (c === '^') {
|
261
|
+
node.negated = true;
|
262
|
+
continue;
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
if (c === ']') {
|
267
|
+
state = State.none;
|
268
|
+
node = parents.pop();
|
269
|
+
|
270
|
+
continue;
|
271
|
+
}
|
272
|
+
|
273
|
+
// range
|
274
|
+
if (c === '-') {
|
275
|
+
// start of set (or not char), just literal -
|
276
|
+
if (node.body.at(-1)?.char == null) {
|
277
|
+
addChar(); // add -
|
278
|
+
continue;
|
279
|
+
}
|
280
|
+
|
281
|
+
const from = node.body.pop().char;
|
282
|
+
const [ to, escaped ] = seek();
|
283
|
+
|
284
|
+
// end of set, just literal -
|
285
|
+
if (to == null || (!escaped && to === ']')) {
|
286
|
+
addChar(from); // add from char back
|
287
|
+
i--; // rollback seek
|
288
|
+
|
289
|
+
addChar(); // add -
|
290
|
+
continue;
|
291
|
+
}
|
292
|
+
|
293
|
+
// next char was escaped and a metachar, just literal -
|
294
|
+
if (escaped && Metachars.escaped[to] != null) {
|
295
|
+
i -= 2; // rollback seek
|
296
|
+
|
297
|
+
addChar(); // add -
|
298
|
+
continue;
|
299
|
+
}
|
300
|
+
|
301
|
+
if (to < from) throw new SyntaxError('Range out of order');
|
302
|
+
|
303
|
+
node.body.push(rangeNode(from, to));
|
304
|
+
continue;
|
305
|
+
}
|
306
|
+
|
307
|
+
addChar();
|
308
|
+
break;
|
309
|
+
}
|
310
|
+
}
|
311
|
+
|
312
|
+
// still in a group by the end
|
313
|
+
if (node.type !== 'Expression') throw new SyntaxError('Unmatched opening parenthesis');
|
314
|
+
|
315
|
+
// still in a set by the end
|
316
|
+
if (state === State.insideSet) throw new SyntaxError('Unmatched opening square bracket');
|
317
|
+
|
318
|
+
return out;
|
319
|
+
};
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import util from 'node:util';
|
2
|
+
|
3
|
+
import parse from '../parse.js';
|
4
|
+
|
5
|
+
const tests = {
|
6
|
+
'a': {},
|
7
|
+
'a(b)': {},
|
8
|
+
'a(b(c))': {},
|
9
|
+
'ab': {},
|
10
|
+
'[ab]': {},
|
11
|
+
'[a-z]': {},
|
12
|
+
'a*': {},
|
13
|
+
'a+': {},
|
14
|
+
'a?': {},
|
15
|
+
'a(b)+': {},
|
16
|
+
'[^a]': {},
|
17
|
+
'[a^]': {},
|
18
|
+
'[^ab]': {},
|
19
|
+
'.': {},
|
20
|
+
|
21
|
+
// not range
|
22
|
+
'[-]': {},
|
23
|
+
'[0-]': {},
|
24
|
+
'[-0]': {},
|
25
|
+
'[\\s-\\S]': {},
|
26
|
+
'[\\s-.]': {},
|
27
|
+
|
28
|
+
'[\\S]': {},
|
29
|
+
|
30
|
+
'\\c': {},
|
31
|
+
'\\c0': {},
|
32
|
+
'\\cJ': {},
|
33
|
+
|
34
|
+
'\\x': {},
|
35
|
+
'\\x0': {},
|
36
|
+
'\\x0g': {},
|
37
|
+
'\\x0a': {},
|
38
|
+
|
39
|
+
'\\u': {},
|
40
|
+
'\\u0': {},
|
41
|
+
'\\u000': {},
|
42
|
+
'\\u000g': {},
|
43
|
+
'\\u000a': {},
|
44
|
+
|
45
|
+
/*
|
46
|
+
// email regexes
|
47
|
+
'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$': {},
|
48
|
+
|
49
|
+
// input type=email from HTML spec
|
50
|
+
// https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)
|
51
|
+
// simpler form
|
52
|
+
'^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$': {},
|
53
|
+
// full/complex form
|
54
|
+
'^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$': {}*/
|
55
|
+
};
|
56
|
+
|
57
|
+
for (const str in tests) {
|
58
|
+
console.log(str, util.inspect(parse(str), false, null, true));
|
59
|
+
}
|
package/runner/index.js
CHANGED
@@ -1,34 +1,53 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
3
|
-
import compile from '../compiler/wrap.js';
|
4
|
-
import fs from 'node:fs';
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
//
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
const
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
import compile from '../compiler/wrap.js';
|
4
|
+
import fs from 'node:fs';
|
5
|
+
|
6
|
+
if (process.argv.includes('-compile-hints')) {
|
7
|
+
const v8 = await import('node:v8');
|
8
|
+
v8.setFlagsFromString(`--experimental-wasm-compilation-hints`);
|
9
|
+
|
10
|
+
// see also these flags:
|
11
|
+
// --experimental-wasm-branch-hinting
|
12
|
+
// --experimental-wasm-extended-const
|
13
|
+
// --experimental-wasm-inlining (?)
|
14
|
+
// --experimental-wasm-js-inlining (?)
|
15
|
+
// --experimental-wasm-return-call (on by default)
|
16
|
+
}
|
17
|
+
|
18
|
+
const file = process.argv.slice(2).find(x => x[0] !== '-');
|
19
|
+
if (!file) {
|
20
|
+
if (process.argv.includes('-v')) {
|
21
|
+
// just print version
|
22
|
+
console.log((await import('./version.js')).default);
|
23
|
+
process.exit(0);
|
24
|
+
}
|
25
|
+
|
26
|
+
// run repl if no file given
|
27
|
+
await import('./repl.js');
|
28
|
+
|
29
|
+
// do nothing for the rest of this file
|
30
|
+
await new Promise(() => {});
|
31
|
+
}
|
32
|
+
|
33
|
+
const source = fs.readFileSync(file, 'utf8');
|
34
|
+
|
35
|
+
let cache = '';
|
36
|
+
const print = str => {
|
37
|
+
cache += str;
|
38
|
+
|
39
|
+
if (str === '\n') {
|
40
|
+
process.stdout.write(cache);
|
41
|
+
cache = '';
|
42
|
+
}
|
43
|
+
};
|
44
|
+
|
45
|
+
try {
|
46
|
+
const { exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
|
47
|
+
|
48
|
+
exports.main();
|
49
|
+
if (cache) process.stdout.write(cache);
|
50
|
+
} catch (e) {
|
51
|
+
if (cache) process.stdout.write(cache);
|
52
|
+
console.error(`${e.constructor.name}: ${e.message}`);
|
34
53
|
}
|
package/runner/repl.js
CHANGED
@@ -1,14 +1,7 @@
|
|
1
1
|
import compile from '../compiler/wrap.js';
|
2
|
+
import rev from './version.js';
|
2
3
|
|
3
4
|
import repl from 'node:repl';
|
4
|
-
import fs from 'node:fs';
|
5
|
-
|
6
|
-
let rev = 'unknown';
|
7
|
-
try {
|
8
|
-
rev = fs.readFileSync(new URL('../.git/refs/heads/main', import.meta.url), 'utf8').trim().slice(0, 7);
|
9
|
-
} catch {
|
10
|
-
rev = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version.split('-')[1];
|
11
|
-
}
|
12
5
|
|
13
6
|
// process.argv.push('-O0'); // disable opts
|
14
7
|
|
@@ -48,13 +41,15 @@ const memoryToString = mem => {
|
|
48
41
|
return out;
|
49
42
|
};
|
50
43
|
|
44
|
+
const alwaysPrev = process.argv.includes('-prev');
|
45
|
+
|
51
46
|
let prev = '';
|
52
47
|
const run = async (source, _context, _filename, callback, run = true) => {
|
53
48
|
let toRun = prev + source.trim();
|
54
|
-
|
49
|
+
if (alwaysPrev) prev = toRun + ';\n';
|
55
50
|
|
56
51
|
const { exports, wasm, pages } = await compile(toRun, []);
|
57
|
-
fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
52
|
+
// fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
58
53
|
|
59
54
|
if (run && exports.$) {
|
60
55
|
lastMemory = exports.$;
|
@@ -64,7 +59,7 @@ const run = async (source, _context, _filename, callback, run = true) => {
|
|
64
59
|
const ret = run ? exports.main() : undefined;
|
65
60
|
callback(null, ret);
|
66
61
|
|
67
|
-
if (source.includes(' = ') || source.includes('let ') || source.includes('var ') || source.includes('const ') || source.includes('function ')) prev = toRun + ';\n';
|
62
|
+
if (!alwaysPrev && (source.includes(' = ') || source.includes('let ') || source.includes('var ') || source.includes('const ') || source.includes('function '))) prev = toRun + ';\n';
|
68
63
|
// prev = toRun + ';\n';
|
69
64
|
};
|
70
65
|
|
package/runner/transform.js
CHANGED
@@ -5,32 +5,11 @@ const file = process.argv.slice(2).find(x => x[0] !== '-');
|
|
5
5
|
|
6
6
|
const source = fs.readFileSync(file, 'utf8');
|
7
7
|
|
8
|
-
const underline = x => `\u001b[4m\u001b[1m${x}\u001b[0m`;
|
9
|
-
const bold = x => `\u001b[1m${x}\u001b[0m`;
|
10
|
-
|
11
|
-
let cache = '';
|
12
|
-
const print = str => {
|
13
|
-
cache += str;
|
14
|
-
|
15
|
-
if (str === '\n') {
|
16
|
-
process.stdout.write(cache);
|
17
|
-
cache = '';
|
18
|
-
}
|
19
|
-
};
|
20
|
-
|
21
8
|
const { wasm } = await compile(source);
|
22
9
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
console.log(`\n\n${underline('output')}`);
|
27
|
-
const t2 = performance.now();
|
28
|
-
|
29
|
-
exports.main();
|
30
|
-
print('\n');
|
31
|
-
|
32
|
-
if (!raw) console.log(bold(`\n\nexecuted in ${(performance.now() - t2).toFixed(2)}ms`));
|
33
|
-
}
|
10
|
+
// const out = `(async () => { const print = str => process.stdout.write(str); (await WebAssembly.instantiate(Uint8Array.from([${wasm.toString()}]), {'': { p: i => print(i.toString()), c: i => print(String.fromCharCode(i))}})).instance.exports.m()})()`;
|
11
|
+
// const out = `new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([${wasm.toString()}])),{'':{p:i=>process.stdout.write(i.toString())}}).exports.m()`;
|
12
|
+
const out = `const a=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([${wasm.toString()}])));const b=a.exports.m();console.log(Array.from(new Uint16Array(a.exports.$.buffer,b+4,new Int32Array(a.exports.$.buffer,b,1))).map(x=>String.fromCharCode(x)).join(''))`;
|
34
13
|
|
35
|
-
|
36
|
-
|
14
|
+
console.log(out);
|
15
|
+
eval(out);
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import fs from 'node:fs';
|
2
|
+
|
3
|
+
let rev = 'unknown';
|
4
|
+
try {
|
5
|
+
rev = fs.readFileSync(new URL('../.git/refs/heads/main', import.meta.url), 'utf8').trim().slice(0, 7);
|
6
|
+
} catch {
|
7
|
+
rev = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version.split('-')[1].slice(0, 7);
|
8
|
+
}
|
9
|
+
|
10
|
+
export default rev;
|
package/t.js
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
let assert = Object();
|
2
|
+
|
3
|
+
assert._isSameValue = function (a, b) {
|
4
|
+
if (a === b) {
|
5
|
+
// Handle +/-0 vs. -/+0
|
6
|
+
return a !== 0 || 1 / a === 1 / b;
|
7
|
+
}
|
8
|
+
|
9
|
+
// Handle NaN vs. NaN
|
10
|
+
return a !== a && b !== b;
|
11
|
+
|
12
|
+
// return a === b;
|
13
|
+
};
|
14
|
+
|
15
|
+
assert.sameValue = function (actual, expected) {
|
16
|
+
/* try {
|
17
|
+
if (assert._isSameValue(actual, expected)) {
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
} catch (error) {
|
21
|
+
throw new Test262Error('_isSameValue operation threw');
|
22
|
+
} */
|
23
|
+
|
24
|
+
if (assert._isSameValue(actual, expected)) {
|
25
|
+
return;
|
26
|
+
}
|
27
|
+
|
28
|
+
throw new Test262Error('assert.sameValue failed');
|
29
|
+
};
|
30
|
+
|
31
|
+
assert.sameValue("lego".charAt(), "l");
|
package/tmp.c
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
|
3
|
+
double inline f64_f(double x, double y) {
|
4
|
+
return x - (int)(x / y) * y;
|
5
|
+
}
|
6
|
+
|
7
|
+
double isPrime(double number) {
|
8
|
+
double i;
|
9
|
+
|
10
|
+
if (number < 2e+0) {
|
11
|
+
return 0e+0;
|
12
|
+
}
|
13
|
+
i = 2e+0;
|
14
|
+
while (i < number) {
|
15
|
+
if (f64_f(number, i) == 0e+0) {
|
16
|
+
return 0e+0;
|
17
|
+
}
|
18
|
+
i = i + 1e+0;
|
19
|
+
}
|
20
|
+
return 1e+0;
|
21
|
+
}
|
22
|
+
|
23
|
+
int main() {
|
24
|
+
double sum;
|
25
|
+
double counter;
|
26
|
+
|
27
|
+
sum = 0e+0;
|
28
|
+
counter = 0e+0;
|
29
|
+
while (counter <= 1e+5) {
|
30
|
+
if (isPrime(counter) == 1e+0) {
|
31
|
+
sum = sum + counter;
|
32
|
+
}
|
33
|
+
counter = counter + 1e+0;
|
34
|
+
}
|
35
|
+
printf("%f\n", sum);
|
36
|
+
}
|
37
|
+
|