porffor 0.1.1 → 0.2.0-c6c8c81
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 +184 -204
- package/compiler/2c.js +377 -0
- package/compiler/builtins/base64.js +91 -91
- package/compiler/builtins.js +19 -13
- package/compiler/codeGen.js +1313 -418
- package/compiler/decompile.js +35 -9
- package/compiler/embedding.js +9 -5
- package/compiler/encoding.js +8 -2
- package/compiler/index.js +55 -17
- package/compiler/log.js +15 -0
- package/compiler/opt.js +357 -258
- package/compiler/parse.js +24 -1
- package/compiler/prototype.js +263 -56
- package/compiler/sections.js +51 -8
- package/compiler/wasmSpec.js +3 -0
- package/compiler/wrap.js +20 -6
- package/package.json +6 -1
- package/porf.cmd +1 -1
- package/rhemyn/README.md +37 -0
- package/rhemyn/compile.js +214 -0
- package/rhemyn/parse.js +321 -0
- package/rhemyn/test/parse.js +59 -0
- package/runner/index.js +54 -31
- package/runner/info.js +37 -2
- package/runner/profile.js +1 -2
- package/runner/repl.js +13 -11
- package/runner/results.json +1 -0
- package/runner/transform.js +15 -36
- package/runner/version.js +10 -0
- package/CNAME +0 -1
- package/index.html +0 -1264
- package/logo.png +0 -0
- package/sw.js +0 -26
@@ -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,32 +1,55 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
await import('
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
+
process.stdout.write(str);
|
45
|
+
};
|
46
|
+
|
47
|
+
try {
|
48
|
+
const { exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
|
49
|
+
|
50
|
+
if (!process.argv.includes('-no-run')) exports.main();
|
51
|
+
if (cache) process.stdout.write(cache);
|
52
|
+
} catch (e) {
|
53
|
+
if (cache) process.stdout.write(cache);
|
54
|
+
console.error(process.argv.includes('-i') ? e : `${e.constructor.name}: ${e.message}`);
|
32
55
|
}
|
package/runner/info.js
CHANGED
@@ -36,7 +36,7 @@ const print = str => {
|
|
36
36
|
};
|
37
37
|
|
38
38
|
const t0 = performance.now();
|
39
|
-
const { wasm, exports } = await compile(source, raw ? [ 'module' ] : [ 'module', 'info' ], {}, print);
|
39
|
+
const { wasm, exports, pages } = await compile(source, raw ? [ 'module' ] : [ 'module', 'info' ], {}, print);
|
40
40
|
|
41
41
|
if (!raw && typeof Deno === 'undefined') fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
42
42
|
|
@@ -51,4 +51,39 @@ if (!process.argv.includes('-no-run')) {
|
|
51
51
|
}
|
52
52
|
|
53
53
|
if (!raw) console.log(bold(`wasm binary is ${wasm.byteLength} bytes`));
|
54
|
-
if (!raw) console.log(`total: ${(performance.now() - t0).toFixed(2)}ms`);
|
54
|
+
if (!raw) console.log(`total: ${(performance.now() - t0).toFixed(2)}ms`);
|
55
|
+
|
56
|
+
if (!raw && process.argv.includes('-mem') && exports.$) {
|
57
|
+
console.log();
|
58
|
+
|
59
|
+
let lastMemory, lastPages;
|
60
|
+
const PageSize = 65536;
|
61
|
+
const memoryToString = mem => {
|
62
|
+
let out = '';
|
63
|
+
const pages = lastPages.length;
|
64
|
+
const wasmPages = mem.buffer.byteLength / PageSize;
|
65
|
+
|
66
|
+
out += `\x1B[1mallocated ${mem.buffer.byteLength / 1024}KiB\x1B[0m for ${pages} things using ${wasmPages} Wasm page${wasmPages === 1 ? '' : 's'}\n`;
|
67
|
+
|
68
|
+
const buf = new Uint8Array(mem.buffer);
|
69
|
+
|
70
|
+
for (let i = 0; i < pages; i++) {
|
71
|
+
out += `\x1B[36m${lastPages[i]}\x1B[2m | \x1B[0m`;
|
72
|
+
|
73
|
+
for (let j = 0; j < 50; j++) {
|
74
|
+
const val = buf[i * pageSize + j];
|
75
|
+
if (val === 0) out += '\x1B[2m';
|
76
|
+
out += val.toString(16).padStart(2, '0');
|
77
|
+
if (val === 0) out += '\x1B[0m';
|
78
|
+
out += ' ';
|
79
|
+
}
|
80
|
+
out += '\n';
|
81
|
+
}
|
82
|
+
|
83
|
+
return out;
|
84
|
+
};
|
85
|
+
|
86
|
+
lastPages = [...pages.keys()];
|
87
|
+
lastMemory = exports.$;
|
88
|
+
console.log(memoryToString(lastMemory));
|
89
|
+
}
|
package/runner/profile.js
CHANGED
@@ -32,8 +32,7 @@ const t1 = performance.now();
|
|
32
32
|
const { instance } = await WebAssembly.instantiate(wasm, {
|
33
33
|
'': {
|
34
34
|
p: i => print(Number(i).toString()),
|
35
|
-
c: i => print(String.fromCharCode(Number(i)))
|
36
|
-
a: c => { if (!Number(c)) throw new Error(`assert failed`); }
|
35
|
+
c: i => print(String.fromCharCode(Number(i)))
|
37
36
|
}
|
38
37
|
});
|
39
38
|
csv += `inst,${performance.now() - t1}\n`;
|
package/runner/repl.js
CHANGED
@@ -1,9 +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
|
-
const rev = fs.readFileSync('.git/refs/heads/main', 'utf8').trim();
|
7
5
|
|
8
6
|
// process.argv.push('-O0'); // disable opts
|
9
7
|
|
@@ -23,7 +21,7 @@ const memoryToString = mem => {
|
|
23
21
|
const pages = lastPages.length;
|
24
22
|
const wasmPages = mem.buffer.byteLength / PageSize;
|
25
23
|
|
26
|
-
out += `\x1B[1mallocated ${mem.buffer.byteLength / 1024}
|
24
|
+
out += `\x1B[1mallocated ${mem.buffer.byteLength / 1024}KB\x1B[0m for ${pages} thing${pages === 1 ? '' : 's'} using ${wasmPages} Wasm page${wasmPages === 1 ? '' : 's'}\n`;
|
27
25
|
|
28
26
|
const buf = new Uint8Array(mem.buffer);
|
29
27
|
|
@@ -45,13 +43,18 @@ const memoryToString = mem => {
|
|
45
43
|
|
46
44
|
let prev = '';
|
47
45
|
const run = async (source, _context, _filename, callback, run = true) => {
|
48
|
-
|
49
|
-
|
46
|
+
// hack: print "secret" before latest code ran to only enable printing for new code
|
47
|
+
|
48
|
+
let toRun = prev + `;\nprint(-0x1337);\n` + source.trim();
|
50
49
|
|
51
|
-
|
52
|
-
|
50
|
+
let shouldPrint = false;
|
51
|
+
const { exports, wasm, pages } = await compile(toRun, [], {}, str => {
|
52
|
+
if (shouldPrint) process.stdout.write(str);
|
53
|
+
if (str === '-4919') shouldPrint = true;
|
54
|
+
});
|
55
|
+
// fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
53
56
|
|
54
|
-
if (exports.$) {
|
57
|
+
if (run && exports.$) {
|
55
58
|
lastMemory = exports.$;
|
56
59
|
lastPages = [...pages.keys()];
|
57
60
|
}
|
@@ -59,8 +62,7 @@ const run = async (source, _context, _filename, callback, run = true) => {
|
|
59
62
|
const ret = run ? exports.main() : undefined;
|
60
63
|
callback(null, ret);
|
61
64
|
|
62
|
-
|
63
|
-
// prev = toRun + ';\n';
|
65
|
+
prev = prev + ';\n' + source.trim();
|
64
66
|
};
|
65
67
|
|
66
68
|
const replServer = repl.start({ prompt: '> ', eval: run });
|