porffor 0.16.0-fe07da0f4 → 0.17.0-05070e1f0

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/rhemyn/compile.js CHANGED
@@ -7,18 +7,16 @@ import { TYPES } from '../compiler/types.js';
7
7
  // local indexes
8
8
  const BasePointer = 0; // base string pointer
9
9
  const IterPointer = 1; // this iteration base pointer
10
- const EndPointer = 2; // pointer for the end
11
- const Counter = 3; // what char we are running on
12
- const Pointer = 4; // next char BYTE pointer
13
- const Length = 5;
14
- const Tmp = 6;
10
+ const Counter = 2; // what char we are running on
11
+ const Pointer = 3; // next char pointer
12
+ const Length = 4;
13
+ const Tmp = 5;
14
+ const QuantifierTmp = 6; // the temporary variable used for quanitifers
15
15
 
16
- let exprLastGet = false;
17
16
  const generate = (node, negated = false, get = true, stringSize = 2, func = 'test') => {
18
17
  let out = [];
19
18
  switch (node.type) {
20
19
  case 'Expression':
21
- exprLastGet = false;
22
20
  out = [
23
21
  // set length local
24
22
  [ Opcodes.local_get, BasePointer ],
@@ -32,49 +30,43 @@ const generate = (node, negated = false, get = true, stringSize = 2, func = 'tes
32
30
  [ Opcodes.local_set, IterPointer ],
33
31
 
34
32
  [ Opcodes.loop, Blocktype.void ],
35
-
36
- // reset pointer as iter pointer
37
- [ Opcodes.local_get, IterPointer ],
38
- [ Opcodes.local_set, Pointer ],
39
-
40
- [ Opcodes.block, Blocktype.void ],
41
-
42
- // generate checks
43
- ...node.body.flatMap((x, i) => {
44
- exprLastGet = x.type !== 'Group' && i === (node.body.length - 1);
45
- return generate(x, negated, true, stringSize, func);
46
- }),
47
-
48
- // reached end without branching out, successful match
49
- ...({
50
- test: number(1, Valtype.i32),
51
- search: [
52
- [ Opcodes.local_get, Counter ]
53
- ]
54
- })[func],
55
- [ Opcodes.return ],
56
-
57
- [ Opcodes.end ],
58
-
59
- // increment iter pointer by string size
60
- [ Opcodes.local_get, IterPointer ],
61
- ...number(stringSize, Valtype.i32),
62
- [ Opcodes.i32_add ],
63
- [ Opcodes.local_set, IterPointer ],
64
-
65
- // increment counter by 1, check if eq length, if not loop
66
- [ Opcodes.local_get, Counter ],
67
- ...number(1, Valtype.i32),
68
- [ Opcodes.i32_add ],
69
- [ Opcodes.local_tee, Counter ],
70
-
71
- [ Opcodes.local_get, Length ],
72
- [ Opcodes.i32_ne ],
73
-
74
- [ Opcodes.br_if, 0 ],
33
+ // reset pointer as iter pointer
34
+ [ Opcodes.local_get, IterPointer ],
35
+ [ Opcodes.local_set, Pointer ],
36
+
37
+ [ Opcodes.block, Blocktype.void ],
38
+ // generate checks
39
+ ...node.body.flatMap(x => generate(x, negated, true, stringSize, func)),
40
+
41
+ // reached end without branching out, successful match
42
+ ...({
43
+ test: number(1, Valtype.i32),
44
+ search: [
45
+ [ Opcodes.local_get, Counter ]
46
+ ]
47
+ })[func],
48
+ [ Opcodes.return ],
49
+ [ Opcodes.end ],
50
+
51
+ // increment iter pointer by string size
52
+ [ Opcodes.local_get, IterPointer ],
53
+ ...number(stringSize, Valtype.i32),
54
+ [ Opcodes.i32_add ],
55
+ [ Opcodes.local_set, IterPointer ],
56
+
57
+ // increment counter by 1, check if eq length, if not loop
58
+ [ Opcodes.local_get, Counter ],
59
+ ...number(1, Valtype.i32),
60
+ [ Opcodes.i32_add ],
61
+ [ Opcodes.local_tee, Counter ],
62
+
63
+ [ Opcodes.local_get, Length ],
64
+ [ Opcodes.i32_ne ],
65
+
66
+ [ Opcodes.br_if, 0 ],
75
67
  [ Opcodes.end ],
76
68
 
77
- // no match, return 0
69
+ // no match
78
70
  ...number(({
79
71
  test: 0,
80
72
  search: -1
@@ -110,12 +102,12 @@ const generate = (node, negated = false, get = true, stringSize = 2, func = 'tes
110
102
  return out;
111
103
  };
112
104
 
113
- const getNextChar = (stringSize) => [
105
+ const getNextChar = (stringSize, peek = false) => [
114
106
  // get char from pointer
115
107
  [ Opcodes.local_get, Pointer ],
116
108
  [ stringSize == 2 ? Opcodes.i32_load16_u : Opcodes.i32_load8_u, 0, 0 ],
117
109
 
118
- ...(exprLastGet ? [] : [
110
+ ...(peek ? [] : [
119
111
  // pointer += string size
120
112
  [ Opcodes.local_get, Pointer ],
121
113
  ...number(stringSize, Valtype.i32),
@@ -134,11 +126,81 @@ const checkFailure = () => [
134
126
  [ Opcodes.br_if, 0 ]
135
127
  ];
136
128
 
137
- const generateChar = (node, negated, get, stringSize) => {
129
+ const wrapQuantifier = (node, method, get, stringSize) => {
130
+ const [ min, max ] = node.quantifier;
138
131
  return [
139
- ...(get ? getNextChar(stringSize) : []),
132
+ // initalize our temp value (number of matched characters)
133
+ ...number(0, Valtype.i32),
134
+ [Opcodes.local_set, QuantifierTmp],
135
+
136
+ // start loop
137
+ [Opcodes.loop, Blocktype.void],
138
+ [ Opcodes.block, Blocktype.void ],
139
+ // if counter + tmp == length, break
140
+ [ Opcodes.local_get, Counter ],
141
+ [ Opcodes.local_get, QuantifierTmp ],
142
+ [ Opcodes.i32_add ],
143
+ [ Opcodes.local_get, Length ],
144
+ [ Opcodes.i32_eq ],
145
+ [ Opcodes.br_if, 0 ],
146
+
147
+ // if doesn't match, break
148
+ ...method,
149
+ [Opcodes.br_if, 0 ],
150
+ ...(get ? [
151
+ // pointer += stringSize
152
+ [ Opcodes.local_get, Pointer ],
153
+ ...number(stringSize, Valtype.i32),
154
+ [ Opcodes.i32_add ],
155
+ [ Opcodes.local_set, Pointer ]
156
+ ] : []),
157
+
158
+ // if maximum was reached, break
159
+ ...(max ? [
160
+ [ Opcodes.local_get, QuantifierTmp ],
161
+ ...number(max, Valtype.i32),
162
+ [ Opcodes.i32_eq ],
163
+ [ Opcodes.br_if, 0 ]
164
+ ] : []),
165
+
166
+ [ Opcodes.local_get, QuantifierTmp ],
167
+ ...number(1, Valtype.i32),
168
+ [ Opcodes.i32_add ],
169
+ [ Opcodes.local_set, QuantifierTmp ],
170
+ [ Opcodes.br, 1 ],
171
+ [ Opcodes.end ],
172
+ [ Opcodes.end ],
173
+
174
+ // if less than minimum, fail
175
+ [Opcodes.local_get, QuantifierTmp],
176
+ ...number(min, Valtype.i32),
177
+ [Opcodes.i32_lt_s],
178
+ ...(get ? checkFailure(): []),
179
+
180
+ // counter += tmp - 1
181
+ [ Opcodes.local_get, QuantifierTmp ],
182
+ ...number(1, Valtype.i32),
183
+ [ Opcodes.i32_sub ],
184
+ [ Opcodes.local_get, Counter ],
185
+ [ Opcodes.i32_add ],
186
+ [ Opcodes.local_set, Counter ]
187
+ ];
188
+ }
189
+
190
+ const generateChar = (node, negated, get, stringSize) => {
191
+ const hasQuantifier = !!node.quantifier;
192
+ const out = [
193
+ ...(get ? getNextChar(stringSize, hasQuantifier) : []),
140
194
  ...number(node.char.charCodeAt(0), Valtype.i32),
141
195
  negated ? [ Opcodes.i32_eq ] : [ Opcodes.i32_ne ],
196
+ ];
197
+
198
+ if (node.quantifier) {
199
+ return wrapQuantifier(node, out, get, stringSize);
200
+ }
201
+
202
+ return [
203
+ ...out,
142
204
  ...(get ? checkFailure(): [])
143
205
  ];
144
206
  };
@@ -146,21 +208,31 @@ const generateChar = (node, negated, get, stringSize) => {
146
208
  const generateSet = (node, negated, get, stringSize) => {
147
209
  // for a single char we do not need a tmp, it is like just
148
210
  const singleChar = node.body.length === 1 && node.body[0].type === 'Character';
211
+ if (singleChar) return generateChar(node.body[0], negated, get, stringSize)
149
212
 
150
- let out = [
151
- ...(get ? getNextChar(stringSize) : []),
152
- ...(singleChar ? [] : [ [ Opcodes.local_set, Tmp ] ]),
213
+ const hasQuantifier = !!node.quantifier;
214
+
215
+ const out = [
216
+ ...(get ? getNextChar(stringSize, hasQuantifier) : []),
217
+ [ Opcodes.local_set, Tmp ],
153
218
  ];
154
219
 
155
220
  for (const x of node.body) {
156
- out = [
157
- ...out,
158
- ...(singleChar ? [] : [ [ Opcodes.local_get, Tmp ] ]),
221
+ out.push(
222
+ [ Opcodes.local_get, Tmp ],
159
223
  ...generate(x, negated, false, stringSize)
160
- ];
224
+ );
161
225
  }
162
226
 
163
- if (node.body.length > 0) out = out.concat(new Array(node.body.length - 1).fill(negated ? [ Opcodes.i32_or ] : [ Opcodes.i32_and ]));
227
+ if (node.body.length > 0) {
228
+ for (let i = 0; i < node.body.length - 1; i++) {
229
+ out.push(negated ? [ Opcodes.i32_or ] : [ Opcodes.i32_and ])
230
+ }
231
+ };
232
+
233
+ if (hasQuantifier) {
234
+ return wrapQuantifier(node, out, get, stringSize);
235
+ }
164
236
 
165
237
  return [
166
238
  ...out,
@@ -196,7 +268,7 @@ const wrapFunc = (regex, func, name, index) => {
196
268
  const parsed = parse(regex);
197
269
 
198
270
  return outputFunc([
199
- [ Opcodes.local_get, 1 ],
271
+ [ Opcodes.local_get, IterPointer ],
200
272
  ...number(TYPES.string, Valtype.i32),
201
273
  [ Opcodes.i32_eq ],
202
274
  [ Opcodes.if, Valtype.i32 ],
@@ -224,10 +296,10 @@ const outputFunc = (wasm, name, index) => ({
224
296
  locals: {
225
297
  basePointer: { idx: 0, type: Valtype.i32 },
226
298
  iterPointer: { idx: 1, type: Valtype.i32 },
227
- endPointer: { idx: 2, type: Valtype.i32 },
228
- counter: { idx: 3, type: Valtype.i32 },
229
- pointer: { idx: 4, type: Valtype.i32 },
230
- length: { idx: 5, type: Valtype.i32 },
231
- tmp: { idx: 6, type: Valtype.i32 },
299
+ counter: { idx: 2, type: Valtype.i32 },
300
+ pointer: { idx: 3, type: Valtype.i32 },
301
+ length: { idx: 4, type: Valtype.i32 },
302
+ tmp: { idx: 5, type: Valtype.i32 },
303
+ quantifierTmp: { idx: 6, type: Valtype.i32 },
232
304
  }
233
305
  });
package/runner/debug.js CHANGED
@@ -43,7 +43,7 @@ let lastLine;
43
43
  let output = '';
44
44
 
45
45
  try {
46
- const { exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
46
+ const { exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
47
47
  y: n => {
48
48
  if (callStarts[callStarts.length - 1] === n - 1) {
49
49
  // end of call
package/runner/index.js CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env node
2
-
3
- import compile from '../compiler/wrap.js';
4
2
  import fs from 'node:fs';
5
3
 
4
+ // deno compat
5
+ if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
6
+ globalThis.process = await import('node:process');
7
+ }
8
+
6
9
  const start = performance.now();
7
10
 
8
11
  if (process.argv.includes('--compile-hints')) {
@@ -59,12 +62,22 @@ if (process.argv.includes('--help')) {
59
62
  }
60
63
 
61
64
  let file = process.argv.slice(2).find(x => x[0] !== '-');
62
- if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(file)) {
65
+ if (['precompile', 'run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(file)) {
63
66
  // remove this arg
64
67
  process.argv.splice(process.argv.indexOf(file), 1);
65
68
 
69
+ if (file === 'precompile') {
70
+ await import('../compiler/precompile.js');
71
+ await new Promise(() => {}); // do nothing for the rest of this file
72
+ }
73
+
66
74
  if (file === 'profile') {
67
- await import('./profiler.js');
75
+ await import('./profile.js');
76
+ await new Promise(() => {}); // do nothing for the rest of this file
77
+ }
78
+
79
+ if (file === 'debug') {
80
+ await import('./debug.js');
68
81
  await new Promise(() => {}); // do nothing for the rest of this file
69
82
  }
70
83
 
@@ -76,11 +89,6 @@ if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(fi
76
89
  process.argv.push('--asur', '--wasm-debug');
77
90
  }
78
91
 
79
- if (file === 'debug') {
80
- await import('./debug.js');
81
- await new Promise(() => {}); // do nothing for the rest of this file
82
- }
83
-
84
92
  file = process.argv.slice(2).find(x => x[0] !== '-');
85
93
 
86
94
  const nonOptOutFile = process.argv.slice(process.argv.indexOf(file) + 1).find(x => x[0] !== '-');
@@ -89,6 +97,8 @@ if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(fi
89
97
  }
90
98
  }
91
99
 
100
+ globalThis.file = file;
101
+
92
102
  if (!file) {
93
103
  if (process.argv.includes('-v') || process.argv.includes('--version')) {
94
104
  // just print version
@@ -103,6 +113,8 @@ if (!file) {
103
113
 
104
114
  const source = fs.readFileSync(file, 'utf8');
105
115
 
116
+ const compile = (await import('../compiler/wrap.js')).default;
117
+
106
118
  let cache = '';
107
119
  const print = str => {
108
120
  /* cache += str;
@@ -115,22 +127,27 @@ const print = str => {
115
127
  process.stdout.write(str);
116
128
  };
117
129
 
130
+ let runStart;
118
131
  try {
119
132
  if (process.argv.includes('-b')) {
120
- const { wasm, exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
133
+ const { wasm, exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
121
134
 
135
+ runStart = performance.now();
122
136
  if (!process.argv.includes('--no-run')) exports.main();
123
137
 
124
138
  console.log(`\n\nwasm size: ${wasm.byteLength} bytes`);
125
139
  } else {
126
- const { exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
140
+ const { exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
127
141
 
128
- if (!process.argv.includes('-no-run')) exports.main();
142
+ runStart = performance.now();
143
+ if (!process.argv.includes('--no-run')) exports.main();
129
144
  }
130
145
  // if (cache) process.stdout.write(cache);
131
146
  } catch (e) {
132
147
  // if (cache) process.stdout.write(cache);
133
- console.error(process.argv.includes('-i') ? e : `${e.constructor.name}: ${e.message}`);
148
+ let out = e;
149
+ if (!process.argv.includes('-i') && Object.getPrototypeOf(e).message != null) out = `${e.constructor.name}${e.message != null ? `: ${e.message}` : ''}`;
150
+ console.error(out);
134
151
  }
135
152
 
136
- if (process.argv.includes('-t')) console.log(`${process.argv.includes('-b') ? '' : '\n\n'}total time: ${(performance.now() - start).toFixed(2)}ms`);
153
+ if (process.argv.includes('-t')) console.log(`${process.argv.includes('-b') ? '' : '\n\n'}total time: ${(performance.now() - start).toFixed(2)}ms\nexecution time: ${(performance.now() - runStart).toFixed(2)}ms`);
@@ -20,7 +20,7 @@ let spin = 0;
20
20
  let last = 0;
21
21
 
22
22
  try {
23
- const { exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
23
+ const { exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
24
24
  y: n => {
25
25
  tmp[n] = performance.now();
26
26
  },
package/runner/repl.js CHANGED
@@ -40,10 +40,9 @@ let lastMemory, lastPages;
40
40
  const PageSize = 65536;
41
41
  const memoryToString = mem => {
42
42
  let out = '';
43
- const pages = lastPages.length;
44
43
  const wasmPages = mem.buffer.byteLength / PageSize;
45
44
 
46
- out += `\x1B[1mallocated ${mem.buffer.byteLength / 1024}KB\x1B[0m for ${pages} thing${pages === 1 ? '' : 's'} using ${wasmPages} Wasm page${wasmPages === 1 ? '' : 's'}\n\n`;
45
+ out += `\x1B[1mallocated ${mem.buffer.byteLength / 1024}KiB\x1B[0m (using ${wasmPages} Wasm page${wasmPages === 1 ? '' : 's'})\n\n`;
47
46
 
48
47
  const buf = new Uint8Array(mem.buffer);
49
48
 
@@ -55,10 +54,16 @@ const memoryToString = mem => {
55
54
  }
56
55
 
57
56
  out += `\x1B[0m\x1B[1m name${' '.repeat(longestName - 4)} \x1B[0m\x1B[90m│\x1B[0m\x1B[1m type${' '.repeat(longestType - 4)} \x1B[0m\x1B[90m│\x1B[0m\x1B[1m memory\x1B[0m\n`; // ─
58
- for (let i = 0; i < pages; i++) {
59
- const [ type, name ] = lastPages[i].split(': ');
60
- // out += `\x1B[36m${lastPages[i].replace(':', '\x1B[90m:\x1B[34m')}\x1B[90m${' '.repeat(longestName - lastPages[i].length)} | \x1B[0m`;
61
- out += ` \x1B[34m${name}${' '.repeat(longestName - name.length)} \x1B[90m│\x1B[0m \x1B[36m${type}${' '.repeat(longestType - type.length)} \x1B[90m│\x1B[0m `;
57
+ for (let i = 0; i < wasmPages; i++) {
58
+ if (lastPages[i]) {
59
+ const [ type, name ] = lastPages[i].split(': ');
60
+ // out += `\x1B[36m${lastPages[i].replace(':', '\x1B[90m:\x1B[34m')}\x1B[90m${' '.repeat(longestName - lastPages[i].length)} | \x1B[0m`;
61
+ out += ` \x1B[34m${name}${' '.repeat(longestName - name.length)} \x1B[90m│\x1B[0m \x1B[36m${type}${' '.repeat(longestType - type.length)} \x1B[90m│\x1B[0m `;
62
+ } else {
63
+ const type = '???';
64
+ const name = '???';
65
+ out += ` \x1B[34m${name}${' '.repeat(longestName - name.length)} \x1B[90m│\x1B[0m \x1B[36m${type}${' '.repeat(longestType - type.length)} \x1B[90m│\x1B[0m `;
66
+ }
62
67
 
63
68
  for (let j = 0; j < 40; j++) {
64
69
  const val = buf[i * pageSize + j];
@@ -75,13 +80,13 @@ const memoryToString = mem => {
75
80
  };
76
81
 
77
82
  let prev = '';
78
- const run = async (source, _context, _filename, callback, run = true) => {
83
+ const run = (source, _context, _filename, callback, run = true) => {
79
84
  // hack: print "secret" before latest code ran to only enable printing for new code
80
85
 
81
86
  let toRun = (prev ? (prev + `;\nprint(-0x1337);\n`) : '') + source.trim();
82
87
 
83
88
  let shouldPrint = !prev;
84
- const { exports, pages } = await compile(toRun, [], {}, str => {
89
+ const { exports, pages } = compile(toRun, [], {}, str => {
85
90
  if (shouldPrint) process.stdout.write(str);
86
91
  if (str === '-4919') shouldPrint = true;
87
92
  });
@@ -122,12 +127,12 @@ replServer.defineCommand('memory', {
122
127
  });
123
128
  replServer.defineCommand('asm', {
124
129
  help: 'Log Wasm decompiled bytecode',
125
- async action() {
130
+ action() {
126
131
  this.clearBufferedCommand();
127
132
 
128
133
  try {
129
134
  process.argv.push('--opt-funcs');
130
- await run('', null, null, () => {}, false);
135
+ run('', null, null, () => {}, false);
131
136
  process.argv.pop();
132
137
  } catch { }
133
138
 
@@ -136,7 +141,7 @@ replServer.defineCommand('asm', {
136
141
  });
137
142
  replServer.defineCommand('js', {
138
143
  help: 'Log JS being actually ran',
139
- async action() {
144
+ action() {
140
145
  this.clearBufferedCommand();
141
146
  console.log(prev);
142
147
  this.displayPrompt();