porffor 0.14.0-cdebd5442 โ†’ 0.14.0-d6c141d91

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/CONTRIBUTING.md CHANGED
@@ -198,11 +198,13 @@ Store the character code into the `out` pointer variable, and increment it.
198
198
 
199
199
  ## Porffor-specific TS notes
200
200
 
201
- - For declaring variables, you must use explicit type annotations currently (eg `let a: number = 1`, not `let a = 1`)
201
+ - For declaring variables, you must use explicit type annotations currently (eg `let a: number = 1`, not `let a = 1`).
202
202
  - You might spot `Porffor.fastOr`/`Porffor.fastAnd`, these are non-short circuiting versions of `||`/`&&`, taking any number of conditions as arguments. You shouldn't don't need to use or worry about these.
203
- - **There are ~no objects, you cannot use them/literals.**
203
+ - **There are ~no objects, you cannot use them.**
204
204
  - Attempt to avoid string/array-heavy code and use more variables instead if possible, easier on memory and CPU/perf.
205
205
  - Do not set a return type for prototype methods, it can cause errors/unexpected results.
206
+ - You cannot use other functions in the file not exported, or variables not inside the current function.
207
+ - `if (...)` uses a fast truthy implementation which is not spec-compliant as most conditions should be strictly checked. To use spec-compliant behavior, use `if (Boolean(...))`.
206
208
 
207
209
  <br>
208
210
 
@@ -231,7 +233,11 @@ builtins/tostring_number: impl radix
231
233
 
232
234
  Make sure you have Test262 cloned already **inside of `test262/`** (`git clone https://github.com/tc39/test262.git test262/test262`) and run `npm install` inside `test262/` too.
233
235
 
234
- Run `node test262` to run all the tests and get an output of total overall test results. The main thing you want to pay attention to is the emoji summary (lol):
236
+ Run `node test262` to run all the tests and get an output of total overall test results.
237
+
238
+ Warning: this will consume 1-6GB of memory and ~90% of all CPU cores while running (depending on thread count), it should take 15-120s depending on machine. You can specify how many threads with `--threads=N`, it will use the number of CPU threads by default.
239
+
240
+ The main thing you want to pay attention to is the emoji summary (lol):
235
241
  ```
236
242
  ๐Ÿงช 50005 | ๐Ÿค  7007 (-89) | โŒ 1914 (-32) | ๐Ÿ’€ 13904 (-61) | ๐Ÿ“ 23477 (-120) | โฐ 2 | ๐Ÿ— 2073 (+302) | ๐Ÿ’ฅ 1628
237
243
  ```
package/asur/index.js CHANGED
@@ -1155,7 +1155,7 @@ if (bc.porfFunc && paused && op) {
1155
1155
  switch (byg(
1156
1156
  paused,
1157
1157
  funcLines[currentFunc] + currentLine,
1158
- '\x1b[1masur\x1b[22m: ' + callStack.join(' -> ') + (parents.length > 1 ? \` | \${parents.slice(1).map(x => invOpcodes[x.opcode]).join(' -> ')}\` : ''),
1158
+ '\x1b[1masur debugger\x1b[22m: ' + callStack.join(' -> ') + (parents.length > 1 ? \` | \${parents.slice(1).map(x => invOpcodes[x.opcode]).join(' -> ')}\` : ''),
1159
1159
  [
1160
1160
  {
1161
1161
  x: termWidth - 1 - width - 6,
package/bf_bun ADDED
Binary file
package/bf_deno ADDED
Binary file
package/bf_porf ADDED
Binary file
package/bf_porf_fast ADDED
Binary file
package/bf_porf_lto ADDED
Binary file
package/compiler/2c.js CHANGED
@@ -119,6 +119,9 @@ const removeBrackets = str => {
119
119
  };
120
120
 
121
121
  export default ({ funcs, globals, tags, data, exceptions, pages }) => {
122
+ // fix declaring order for c
123
+ funcs.reverse();
124
+
122
125
  const invOperatorOpcode = Object.values(operatorOpcode).reduce((acc, x) => {
123
126
  for (const k in x) {
124
127
  acc[x[k]] = k;
@@ -156,6 +159,11 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
156
159
  prependMain.set('_data', data.map(x => `memcpy(_memory + ${x.offset}, (unsigned char[]){${x.bytes.join(',')}}, ${x.bytes.length});`).join('\n'));
157
160
  }
158
161
 
162
+ if (importFuncs.find(x => x.name === '__Porffor_readArgv')) {
163
+ prepend.set('argv', `int _argc; char** _argv;`);
164
+ prependMain.set('argv', `_argc = argc; _argv = argv;`);
165
+ }
166
+
159
167
  if (out) out += '\n';
160
168
 
161
169
  let depth = 1;
@@ -207,8 +215,9 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
207
215
 
208
216
  const returns = f.returns.length > 0;
209
217
 
210
- const shouldInline = f.internal;
211
- out += `${f.name === 'main' ? 'int' : (f.internal ? (returns ? CValtype.f64 : 'void') : 'struct ReturnValue')} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
218
+ const shouldInline = false; // f.internal;
219
+ if (f.name === 'main') out += `int main(${prependMain.has('argv') ? 'int argc, char* argv[]' : ''}) {\n`;
220
+ else out += `${f.internal ? (returns ? CValtype.f64 : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
212
221
 
213
222
  if (f.name === 'main') {
214
223
  out += [...prependMain.values()].join('\n');
@@ -459,6 +468,60 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
459
468
  winIncludes.set('windows.h', true);
460
469
  break;
461
470
 
471
+ case '__Porffor_readArgv':
472
+ includes.set('stdlib.h', true);
473
+
474
+ prepend.set('__Porffor_readArgv',
475
+ `void __Porffor_readArgv(u32 index, u32 outPtr) {
476
+ if (index >= _argc) {
477
+ printf("expected %d arguments\\n", index);
478
+ exit(1);
479
+ }
480
+
481
+ char* arg = _argv[index];
482
+
483
+ u32 read = 0;
484
+ char* out = _memory + outPtr + 4;
485
+ char ch;
486
+ while ((ch = *(arg++)) != 0) {
487
+ out[read++] = ch;
488
+ }
489
+
490
+ memcpy(_memory + outPtr, &read, sizeof(read));
491
+ }`);
492
+
493
+ line(`__Porffor_readArgv((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
494
+ vals.pop();
495
+ break;
496
+
497
+ case '__Porffor_readFile':
498
+ includes.set('stdio.h', true);
499
+ includes.set('stdlib.h', true);
500
+
501
+ prepend.set('__Porffor_readFile',
502
+ `void __Porffor_readFile(u32 pathPtr, u32 outPtr) {
503
+ char* path = _memory + pathPtr + 4;
504
+ FILE* fp = fopen(path, "r");
505
+ if (fp == NULL) {
506
+ printf("failed to open file: %s\\n", path);
507
+ exit(1);
508
+ }
509
+
510
+ u32 read = 0;
511
+ char* out = _memory + outPtr + 4;
512
+ char ch;
513
+ while ((ch = fgetc(fp)) != EOF) {
514
+ out[read++] = ch;
515
+ }
516
+
517
+ fclose(fp);
518
+
519
+ memcpy(_memory + outPtr, &read, sizeof(read));
520
+ }`);
521
+ line(`__Porffor_readFile((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
522
+ vals.pop();
523
+ break;
524
+
462
525
  default:
463
526
  log.warning('2c', `unimplemented import: ${importFunc.name}`);
464
527
  break;
@@ -116,6 +116,20 @@ export default (funcs, globals, tags, pages, data, flags) => {
116
116
  ] ])
117
117
  );
118
118
 
119
+ if (pages.has('func argc lut')) {
120
+ // generate func argc lut data
121
+ const bytes = [];
122
+ for (let i = 0; i < funcs.length; i++) {
123
+ const argc = Math.floor(funcs[i].params.length / 2);
124
+ bytes.push(argc % 256, (argc / 256 | 0) % 256);
125
+ }
126
+
127
+ data.push({
128
+ offset: pages.get('func argc lut').ind * pageSize,
129
+ bytes
130
+ });
131
+ }
132
+
119
133
  // const t0 = performance.now();
120
134
 
121
135
  // specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
@@ -1,4 +1,5 @@
1
1
  // @porf --valtype=i32
2
+ import type {} from './porffor.d.ts';
2
3
 
3
4
  export const __String_prototype_trimLeft = (_this: string) => {
4
5
  return __String_prototype_trimStart(_this);
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  export const __Array_isArray = (x: unknown): boolean =>
2
4
  // Porffor.wasm`local.get ${x+1}` == Porffor.TYPES.array;
3
5
  Porffor.rawType(x) == Porffor.TYPES.array;
@@ -27,14 +29,16 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
27
29
  let outPtr: i32 = Porffor.wasm`local.get ${out}`;
28
30
  let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
29
31
 
30
- const thisPtrEnd: i32 = thisPtr + end * 8;
32
+ const thisPtrEnd: i32 = thisPtr + end * 9;
31
33
 
32
- thisPtr += start * 8;
34
+ thisPtr += start * 9;
33
35
 
34
36
  while (thisPtr < thisPtrEnd) {
35
37
  Porffor.wasm.f64.store(outPtr, Porffor.wasm.f64.load(thisPtr, 0, 4), 0, 4);
36
- thisPtr += 8;
37
- outPtr += 8;
38
+ Porffor.wasm.i32.store8(outPtr + 8, Porffor.wasm.i32.load8_u(thisPtr + 8, 0, 4), 0, 4);
39
+
40
+ thisPtr += 9;
41
+ outPtr += 9;
38
42
  }
39
43
 
40
44
  out.length = end - start;
@@ -142,4 +146,80 @@ export const __Array_prototype_toReversed = (_this: any[]) => {
142
146
 
143
147
  export const __Array_prototype_valueOf = (_this: any[]) => {
144
148
  return _this;
149
+ };
150
+
151
+
152
+ export const __Array_prototype_forEach = (_this: any[], callbackFn: any) => {
153
+ const len: i32 = _this.length;
154
+ let i: i32 = 0;
155
+ while (i < len) {
156
+ callbackFn(_this[i], i++, _this);
157
+ }
158
+ };
159
+
160
+ export const __Array_prototype_filter = (_this: any[], callbackFn: any) => {
161
+ const out: any[] = [];
162
+
163
+ const len: i32 = _this.length;
164
+ let i: i32 = 0;
165
+ while (i < len) {
166
+ const el: any = _this[i];
167
+ if (Boolean(callbackFn(el, i++, _this))) out.push(el);
168
+ }
169
+
170
+ return out;
171
+ };
172
+
173
+ export const __Array_prototype_map = (_this: any[], callbackFn: any) => {
174
+ const out: any[] = [];
175
+
176
+ const len: i32 = _this.length;
177
+ let i: i32 = 0;
178
+ while (i < len) {
179
+ out.push(callbackFn(_this[i], i++, _this));
180
+ }
181
+
182
+ return out;
183
+ };
184
+
185
+ export const __Array_prototype_find = (_this: any[], callbackFn: any) => {
186
+ const len: i32 = _this.length;
187
+ let i: i32 = 0;
188
+ while (i < len) {
189
+ const el: any = _this[i];
190
+ if (Boolean(callbackFn(el, i++, _this))) return el;
191
+ }
192
+ };
193
+
194
+ export const __Array_prototype_findLast = (_this: any[], callbackFn: any) => {
195
+ let i: i32 = _this.length;
196
+ while (i > 0) {
197
+ const el: any = _this[--i];
198
+ if (Boolean(callbackFn(el, i, _this))) return el;
199
+ }
200
+ };
201
+
202
+ export const __Array_prototype_findIndex = (_this: any[], callbackFn: any) => {
203
+ const len: i32 = _this.length;
204
+ let i: i32 = 0;
205
+ while (i < len) {
206
+ if (Boolean(callbackFn(_this[i], i++, _this))) return i;
207
+ }
208
+ };
209
+
210
+ export const __Array_prototype_findLastIndex = (_this: any[], callbackFn: any) => {
211
+ let i: i32 = _this.length;
212
+ while (i > 0) {
213
+ if (Boolean(callbackFn(_this[--i], i, _this))) return i;
214
+ }
215
+ };
216
+
217
+ export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
218
+ const len: i32 = _this.length;
219
+ let i: i32 = 0;
220
+ while (i < len) {
221
+ if (!Boolean(callbackFn(_this[i], i++, _this))) return false;
222
+ }
223
+
224
+ return true;
145
225
  };
@@ -1,4 +1,5 @@
1
1
  // @porf --valtype=i32
2
+ import type {} from './porffor.d.ts';
2
3
 
3
4
  export const btoa = (input: bytestring): bytestring => {
4
5
  const keyStr: bytestring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  // 20.3.3.2 Boolean.prototype.toString ()
2
4
  // https://tc39.es/ecma262/#sec-boolean.prototype.tostring
3
5
  export const __Boolean_prototype_toString = (_this: boolean) => {
@@ -1,4 +1,5 @@
1
1
  // @porf --valtype=i32
2
+ import type {} from './porffor.d.ts';
2
3
 
3
4
  export const __crypto_randomUUID = (): bytestring => {
4
5
  let bytes: bytestring = '................';
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  // 21.4.1.3 Day (t)
2
4
  // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-day
3
5
  // 1. Return ๐”ฝ(floor(โ„(t / msPerDay))).
@@ -0,0 +1,22 @@
1
+ export default () => {
2
+ let out = '';
3
+
4
+ const error = name => out += `export const ${name} = (message: bytestring) => {
5
+ return {};
6
+ };
7
+
8
+ export const ${name}$constructor = (message: bytestring) => {
9
+ return {};
10
+ };`;
11
+
12
+ error('Error');
13
+ error('AggregateError');
14
+ error('TypeError');
15
+ error('ReferenceError');
16
+ error('SyntaxError');
17
+ error('RangeError');
18
+ error('EvalError');
19
+ error('URIError');
20
+
21
+ return out;
22
+ };
@@ -1,6 +1,5 @@
1
1
  // @porf --valtype=i32
2
-
3
- import type {} from './porffor';
2
+ import type {} from './porffor.d.ts';
4
3
 
5
4
  export const escape = (input: string|bytestring): bytestring => {
6
5
  // we have no byte array yet so use bytestring with 0x00 and 0x01 via escape characters
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  export const __Function_prototype_toString = (_this: Function) => {
2
4
  // todo: actually use source
3
5
  let out: bytestring = 'function () {}';
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  // radix: number|any for rawType check
2
4
  // export const parseInt = (input: string|bytestring, radix: number|any): f64 => {
3
5
  export const parseInt = (input: string|bytestring, radix: number): f64 => {